PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.0.1
Tutor LMS – eLearning and online course solution v3.0.1
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Lesson.php
tutor / classes Last commit date
Addons.php 1 year ago Admin.php 1 year ago Ajax.php 1 year ago Announcements.php 1 year ago Assets.php 1 year ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Course.php 1 year ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 1 year ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 3 years ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 1 year ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Input.php 1 year ago Instructor.php 1 year ago Instructors_List.php 1 year ago Lesson.php 1 year ago Options_V2.php 1 year ago Permalink.php 2 years ago Post_types.php 2 years ago Private_Course_Access.php 1 year ago Q_And_A.php 1 year ago Question_Answers_List.php 3 years ago Quiz.php 1 year ago QuizBuilder.php 1 year ago Quiz_Attempts_List.php 1 year ago RestAPI.php 2 years ago Reviews.php 3 years ago Rewrite_Rules.php 2 years ago Shortcode.php 1 year ago Singleton.php 1 year ago Student.php 1 year ago Students_List.php 3 years ago Taxonomies.php 3 years ago Template.php 1 year ago Theme_Compatibility.php 3 years ago Tools.php 3 years ago Tools_V2.php 1 year ago Tutor.php 1 year ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 1 year ago Upgrader.php 1 year ago User.php 1 year ago Utils.php 1 year ago Video_Stream.php 3 years ago WhatsNew.php 2 years ago Withdraw.php 1 year ago Withdraw_Requests_List.php 3 years ago WooCommerce.php 1 year ago
Lesson.php
631 lines
1 <?php
2 /**
3 * Manage Lesson
4 *
5 * @package Tutor
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 use Tutor\Helpers\HttpHelper;
18 use Tutor\Helpers\ValidationHelper;
19 use Tutor\Models\LessonModel;
20 use Tutor\Traits\JsonResponse;
21
22 /**
23 * Lesson class
24 *
25 * @since 1.0.0
26 */
27 class Lesson extends Tutor_Base {
28 use JsonResponse;
29
30 /**
31 * Register hooks
32 *
33 * @since 1.0.0
34 *
35 * @return void
36 */
37 public function __construct() {
38 parent::__construct();
39
40 add_action( 'save_post_' . $this->lesson_post_type, array( $this, 'save_lesson_meta' ) );
41
42 add_action( 'wp_ajax_tutor_lesson_details', array( $this, 'ajax_lesson_details' ) );
43 add_action( 'wp_ajax_tutor_save_lesson', array( $this, 'ajax_save_lesson' ) );
44 add_action( 'wp_ajax_tutor_delete_lesson', array( $this, 'ajax_delete_lesson' ) );
45
46 add_filter( 'get_sample_permalink', array( $this, 'change_lesson_permalink' ), 10, 2 );
47
48 /**
49 * Frontend Action
50 */
51 add_action( 'template_redirect', array( $this, 'mark_lesson_complete' ) );
52
53 add_action( 'wp_ajax_tutor_render_lesson_content', array( $this, 'tutor_render_lesson_content' ) );
54
55 /**
56 * For public course access
57 */
58 add_action( 'wp_ajax_nopriv_tutor_render_lesson_content', array( $this, 'tutor_render_lesson_content' ) );
59
60 /**
61 * Autoplay next video
62 *
63 * @since 1.4.9
64 */
65 add_action( 'wp_ajax_autoload_next_course_content', array( $this, 'autoload_next_course_content' ) );
66
67 /**
68 * Load next course item after click complete button
69 *
70 * @since 1.5.3
71 */
72 add_action( 'tutor_lesson_completed_after', array( $this, 'tutor_lesson_completed_after' ), 999 );
73
74 /**
75 * Lesson comment & reply ajax handler
76 *
77 * @since 2.0.0
78 */
79 add_action( 'wp_ajax_tutor_single_course_lesson_load_more', array( $this, 'tutor_single_course_lesson_load_more' ) );
80 add_action( 'wp_ajax_tutor_create_lesson_comment', array( $this, 'tutor_single_course_lesson_load_more' ) );
81 add_action( 'wp_ajax_tutor_reply_lesson_comment', array( $this, 'reply_lesson_comment' ) );
82 }
83
84 /**
85 * Manage load more & comment create
86 *
87 * @since 2.0.6
88 * @return void send wp json data
89 */
90 public function tutor_single_course_lesson_load_more() {
91 tutor_utils()->checking_nonce();
92 $comment = Input::post( 'comment', '', Input::TYPE_KSES_POST );
93 if ( 'tutor_create_lesson_comment' === Input::post( 'action' ) && strlen( $comment ) > 0 ) {
94 $comment_data = array(
95 'comment_content' => $comment,
96 'comment_post_ID' => Input::post( 'comment_post_ID', 0, Input::TYPE_INT ),
97 'comment_parent' => Input::post( 'comment_parent', 0, Input::TYPE_INT ),
98 );
99 self::create_comment( $comment_data );
100 do_action( 'tutor_new_comment_added', $comment_data );
101 }
102 ob_start();
103 tutor_load_template( 'single.lesson.comment' );
104 $html = ob_get_clean();
105 wp_send_json_success( array( 'html' => $html ) );
106 }
107
108 /**
109 * Saving lesson meta and assets
110 *
111 * @since 1.0.0
112 *
113 * @param integer $post_ID post ID.
114 * @return void
115 */
116 public function save_lesson_meta( $post_ID ) {
117 $video_source = sanitize_text_field( tutor_utils()->array_get( 'video.source', $_POST ) ); //phpcs:ignore
118 if ( '-1' === $video_source ) {
119 delete_post_meta( $post_ID, '_video' );
120 } elseif ( $video_source ) {
121
122 // Sanitize data through helper method.
123 $video = Input::sanitize_array(
124 $_POST['video'] ?? array(), //phpcs:ignore
125 array(
126 'source_external_url' => 'esc_url',
127 'source_embedded' => 'wp_kses_post',
128 ),
129 true
130 );
131 update_post_meta( $post_ID, '_video', $video );
132 }
133
134 // Attachments.
135 $attachments = array();
136 // phpcs:disable WordPress.Security.NonceVerification.Missing
137 if ( ! empty( $_POST['tutor_attachments'] ) ) {
138 //phpcs:ignore -- data sanitized through helper method.
139 $attachments = tutor_utils()->sanitize_array( wp_unslash( $_POST['tutor_attachments'] ) );
140 $attachments = array_unique( $attachments );
141 }
142
143 /**
144 * If !empty attachment then update meta else
145 * delete meta key to prevent empty data in db
146 *
147 * @since 1.8.9
148 */
149 if ( ! empty( $attachments ) ) {
150 update_post_meta( $post_ID, '_tutor_attachments', $attachments );
151 } else {
152 delete_post_meta( $post_ID, '_tutor_attachments' );
153 }
154
155 }
156
157 /**
158 * Get lesson details data.
159 *
160 * @since 3.0.0
161 *
162 * @return void
163 */
164 public function ajax_lesson_details() {
165 if ( ! tutor_utils()->is_nonce_verified() ) {
166 $this->json_response( tutor_utils()->error_message( 'nonce' ), null, HttpHelper::STATUS_BAD_REQUEST );
167 }
168
169 $topic_id = Input::post( 'topic_id', 0, Input::TYPE_INT );
170 $lesson_id = Input::post( 'lesson_id', 0, Input::TYPE_INT );
171
172 if ( ! tutor_utils()->can_user_manage( 'topic', $topic_id ) ) {
173 $this->json_response(
174 tutor_utils()->error_message(),
175 null,
176 HttpHelper::STATUS_FORBIDDEN
177 );
178 }
179
180 if ( 0 !== $lesson_id ) {
181 if ( ! tutor_utils()->can_user_manage( 'lesson', $lesson_id ) ) {
182 $this->json_response(
183 tutor_utils()->error_message(),
184 null,
185 HttpHelper::STATUS_FORBIDDEN
186 );
187 }
188 }
189
190 $post = get_post( $lesson_id, ARRAY_A );
191
192 if ( $post ) {
193 $post['thumbnail_id'] = get_post_meta( $lesson_id, '_thumbnail_id', true );
194 $post['thumbnail'] = get_the_post_thumbnail_url( $lesson_id );
195 $post['attachments'] = tutor_utils()->get_attachments( $lesson_id );
196
197 $video = maybe_unserialize( get_post_meta( $lesson_id, '_video', true ) );
198 if ( $video ) {
199 $source = $video['source'] ?? '';
200 if ( 'html5' === $source ) {
201 $poster_url = wp_get_attachment_url( $video['poster'] ?? 0 );
202 $source_html5 = wp_get_attachment_url( $video['source_video_id'] ?? 0 );
203 $video['poster_url'] = $poster_url;
204 $video['source_html5'] = $source_html5;
205 }
206 }
207 $post['video'] = $video;
208 } else {
209 $post = array();
210 }
211
212 $data = apply_filters( 'tutor_lesson_details_response', $post, $lesson_id );
213
214 $this->json_response(
215 __( 'Lesson data fetched successfully', 'tutor' ),
216 $data
217 );
218 }
219
220 /**
221 * Create or update lesson.
222 *
223 * @since 1.0.0
224 * @since 1.5.1 updated
225 * @since 3.0.0 refactor and response updated.
226 *
227 * @return void
228 */
229 public function ajax_save_lesson() {
230 if ( ! tutor_utils()->is_nonce_verified() ) {
231 $this->json_response( tutor_utils()->error_message( 'nonce' ), null, HttpHelper::STATUS_BAD_REQUEST );
232 }
233
234 /**
235 * Allow iframe inside lesson content to support
236 * embed video & other stuff
237 *
238 * @since 2.1.6
239 */
240 add_filter( 'wp_kses_allowed_html', Input::class . '::allow_iframe', 10, 2 );
241
242 $is_update = false;
243
244 $lesson_id = Input::post( 'lesson_id', 0, Input::TYPE_INT );
245 $topic_id = Input::post( 'topic_id', 0, Input::TYPE_INT );
246 $course_id = tutor_utils()->get_course_id_by( 'topic', $topic_id );
247
248 if ( $lesson_id ) {
249 $is_update = true;
250 }
251
252 if ( ! tutor_utils()->can_user_manage( 'topic', $topic_id ) ) {
253 $this->json_response(
254 tutor_utils()->error_message(),
255 null,
256 HttpHelper::STATUS_FORBIDDEN
257 );
258 }
259
260 $title = Input::post( 'title' );
261 $description = Input::post( 'description', '', Input::TYPE_KSES_POST );
262 $thumbnail_id = Input::post( 'thumbnail_id', 0, Input::TYPE_INT );
263
264 $is_html_active = Input::post( 'is_html_active' ) === 'true' ? true : false;
265 $raw_html_content = Input::post( 'tutor_lesson_modal_editor', '', Input::TYPE_KSES_POST );
266 $post_content = $is_html_active ? $raw_html_content : $description;
267
268 $rules = array(
269 'topic_id' => 'required|numeric',
270 'lesson_id' => 'if_input|numeric',
271 );
272
273 //phpcs:ignore WordPress.Security.NonceVerification.Missing
274 $params = Input::sanitize_array( $_POST, array( 'description' => 'wp_kses_post' ) );
275
276 $validation = ValidationHelper::validate( $rules, $params );
277 if ( ! $validation->success ) {
278 $this->json_response(
279 __( 'Invalid inputs', 'tutor' ),
280 $validation->errors,
281 HttpHelper::STATUS_UNPROCESSABLE_ENTITY
282 );
283 }
284
285 $lesson_data = array(
286 'post_type' => $this->lesson_post_type,
287 'post_title' => $title,
288 'post_name' => sanitize_title( $title ),
289 'post_content' => $post_content,
290 'post_status' => 'publish',
291 'comment_status' => 'open',
292 'post_author' => get_current_user_id(),
293 'post_parent' => $topic_id,
294 );
295
296 if ( ! $is_update ) {
297 $lesson_data['menu_order'] = tutor_utils()->get_next_course_content_order_id( $topic_id );
298 $lesson_id = wp_insert_post( $lesson_data );
299
300 if ( $lesson_id ) {
301 do_action( 'tutor/lesson/created', $lesson_id );
302 } else {
303 $this->json_response(
304 tutor_utils()->error_message(),
305 null,
306 HttpHelper::STATUS_INTERNAL_SERVER_ERROR
307 );
308 }
309 } else {
310 $lesson_data['ID'] = $lesson_id;
311
312 if ( ! tutor_utils()->can_user_manage( 'lesson', $lesson_id ) ) {
313 $this->json_response(
314 tutor_utils()->error_message(),
315 null,
316 HttpHelper::STATUS_FORBIDDEN
317 );
318 }
319
320 do_action( 'tutor/lesson_update/before', $lesson_id );
321 wp_update_post( $lesson_data );
322 do_action( 'tutor/lesson_update/after', $lesson_id );
323 }
324
325 if ( $thumbnail_id ) {
326 update_post_meta( $lesson_id, '_thumbnail_id', $thumbnail_id );
327 } else {
328 delete_post_meta( $lesson_id, '_thumbnail_id' );
329 }
330
331 if ( $is_update ) {
332 $this->json_response(
333 __( 'Lesson updated successfully', 'tutor' ),
334 $lesson_id
335 );
336 } else {
337 $this->json_response(
338 __( 'Lesson created successfully', 'tutor' ),
339 $lesson_id,
340 HttpHelper::STATUS_CREATED
341 );
342 }
343 }
344
345 /**
346 * Delete Lesson from course builder by ID
347 *
348 * @since 1.0.0
349 * @since 3.0.0 refactor and update response.
350 *
351 * @return void
352 */
353 public function ajax_delete_lesson() {
354 tutor_utils()->check_nonce();
355
356 $lesson_id = Input::post( 'lesson_id', 0, Input::TYPE_INT );
357
358 if ( ! tutor_utils()->can_user_manage( 'lesson', $lesson_id ) ) {
359 $this->json_response(
360 tutor_utils()->error_message(),
361 null,
362 HttpHelper::STATUS_FORBIDDEN
363 );
364 }
365
366 $content = __( 'Lesson', 'tutor' );
367 $post_type = get_post_type( $lesson_id );
368 if ( tutor()->assignment_post_type === $post_type ) {
369 $content = __( 'Assignment', 'tutor' );
370 }
371
372 if ( tutor()->has_pro && \TutorPro\H5P\H5P::is_enabled() ) {
373 \TutorPro\H5P\Lesson::delete_h5p_lesson_statements_by_id( 0, $lesson_id );
374 }
375
376 wp_delete_post( $lesson_id, true );
377 /* translators: %s refers to the name of the content being deleted */
378 $this->json_response( sprintf( __( '%s deleted successfully', 'tutor' ), $content ) );
379 }
380
381
382 /**
383 * Changed the URI based
384 *
385 * @since 1.0.0
386 *
387 * @param string $uri URI.
388 * @param integer $lesson_id lesson ID.
389 *
390 * @return string
391 */
392 public function change_lesson_permalink( $uri, $lesson_id ) {
393 $post = get_post( $lesson_id );
394
395 if ( $post && $post->post_type === $this->lesson_post_type ) {
396 $uri_base = trailingslashit( site_url() );
397
398 $sample_course = 'sample-course';
399 $is_course = tutor_utils()->get_course_id_by( 'lesson', get_the_ID() );
400 if ( $is_course ) {
401 $course = get_post( $is_course );
402 if ( $course ) {
403 $sample_course = $course->post_name;
404 }
405 }
406
407 $new_course_base = $uri_base . "course/{$sample_course}/lesson/%pagename%/";
408 $uri[0] = $new_course_base;
409 }
410
411 return $uri;
412 }
413
414 /**
415 * Mark lesson completed
416 *
417 * @since 1.0.0
418 *
419 * @return void
420 */
421 public function mark_lesson_complete() {
422 if ( 'tutor_complete_lesson' !== Input::post( 'tutor_action' ) ) {
423 return;
424 }
425 // Checking nonce.
426 tutor_utils()->checking_nonce();
427
428 $user_id = get_current_user_id();
429
430 // TODO: need to show view if not signed_in.
431 if ( ! $user_id ) {
432 die( esc_html__( 'Please Sign-In', 'tutor' ) );
433 }
434
435 $lesson_id = Input::post( 'lesson_id', 0, Input::TYPE_INT );
436
437 if ( ! $lesson_id ) {
438 return;
439 }
440
441 $validated = apply_filters( 'tutor_validate_lesson_complete', true, $user_id, $lesson_id );
442 if ( ! $validated ) {
443 return;
444 }
445
446 do_action( 'tutor_lesson_completed_before', $lesson_id );
447 /**
448 * Marking lesson at user meta, meta format, _tutor_completed_lesson_id_{id} and value = tutor_time();
449 */
450 LessonModel::mark_lesson_complete( $lesson_id );
451
452 do_action( 'tutor_lesson_completed_email_after', $lesson_id, $user_id );
453 do_action( 'tutor_lesson_completed_after', $lesson_id, $user_id );
454 }
455
456 /**
457 * Render the lesson content
458 *
459 * @since 1.0.0
460 *
461 * @return void
462 */
463 public function tutor_render_lesson_content() {
464 tutor_utils()->checking_nonce();
465
466 $lesson_id = Input::post( 'lesson_id', 0, Input::TYPE_INT );
467
468 $ancestors = get_post_ancestors( $lesson_id );
469 $course_id = ! empty( $ancestors ) ? array_pop( $ancestors ) : $lesson_id;
470
471 // Course must be public or current user must be enrolled to access this lesson.
472 if ( get_post_meta( $course_id, '_tutor_is_public_course', true ) !== 'yes' && ! tutor_utils()->is_enrolled( $course_id ) ) {
473
474 $is_admin = tutor_utils()->has_user_role( 'administrator' );
475 $allowed = $is_admin ? true : tutor_utils()->is_instructor_of_this_course( get_current_user_id(), $course_id );
476
477 if ( ! $allowed ) {
478 http_response_code( 400 );
479 exit;
480 }
481 }
482
483 ob_start();
484 global $post;
485
486 $post = get_post( $lesson_id ); //phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
487 setup_postdata( $post );
488 tutor_lesson_content();
489 wp_reset_postdata();
490
491 $html = ob_get_clean();
492
493 wp_send_json_success( array( 'html' => $html ) );
494 }
495
496 /**
497 * Load next course item automatically
498 *
499 * @since 1.4.9
500 *
501 * @return void
502 */
503 public function autoload_next_course_content() {
504 tutor_utils()->checking_nonce();
505
506 $post_id = Input::post( 'post_id', 0, Input::TYPE_INT );
507 $content_id = tutor_utils()->get_post_id( $post_id );
508 $contents = tutor_utils()->get_course_prev_next_contents_by_id( $content_id );
509
510 $autoload_course_content = (bool) get_tutor_option( 'autoload_next_course_content' );
511 $next_url = false;
512 if ( $autoload_course_content ) {
513 $next_url = get_the_permalink( $contents->next_id );
514 }
515 wp_send_json_success( array( 'next_url' => $next_url ) );
516 }
517
518 /**
519 * Load next course item after click complete button
520 *
521 * @since 1.5.3
522 *
523 * @param integer $content_id content ID.
524 * @return void
525 */
526 public function tutor_lesson_completed_after( $content_id ) {
527 $contents = tutor_utils()->get_course_prev_next_contents_by_id( $content_id );
528 $autoload_course_content = (bool) get_tutor_option( 'autoload_next_course_content' );
529 if ( $autoload_course_content ) {
530 wp_safe_redirect( get_the_permalink( $contents->next_id ) );
531 } else {
532 wp_safe_redirect( get_the_permalink( $content_id ) );
533 }
534 die();
535 }
536
537 /**
538 * Replay lesson comment
539 *
540 * @since 1.0.0
541 *
542 * @return void|null
543 */
544 public function reply_lesson_comment() {
545 tutor_utils()->checking_nonce();
546 $comment = Input::post( 'comment', '', Input::TYPE_KSES_POST );
547 if ( 0 === strlen( $comment ) ) {
548 wp_send_json_error();
549 return;
550 }
551
552 $comment_data = array(
553 'comment_content' => $comment,
554 'comment_post_ID' => Input::post( 'comment_post_ID', 0, Input::TYPE_INT ),
555 'comment_parent' => Input::post( 'comment_parent', 0, Input::TYPE_INT ),
556 );
557 $comment_id = self::create_comment( $comment_data );
558 if ( false === $comment_id ) {
559 wp_send_json_error();
560 return;
561 }
562 $reply = get_comment( $comment_id );
563 do_action( 'tutor_reply_lesson_comment_thread', $comment_id, $comment_data );
564
565 ob_start();
566 ?>
567 <div class="tutor-comments-list tutor-child-comment tutor-mt-32" id="lesson-comment-<?php echo esc_attr( $reply->comment_ID ); ?>">
568 <div class="comment-avatar">
569 <img src="<?php echo esc_url( get_avatar_url( $reply->user_id ) ); ?>" alt="">
570 </div>
571 <div class="tutor-single-comment">
572 <div class="tutor-actual-comment tutor-mb-12">
573 <div class="tutor-comment-author">
574 <span class="tutor-fs-6 tutor-fw-bold">
575 <?php echo esc_html( $reply->comment_author ); ?>
576 </span>
577 <span class="tutor-fs-7 tutor-ml-0 tutor-ml-sm-10">
578 <?php echo esc_html( human_time_diff( strtotime( $reply->comment_date ), tutor_time() ) . __( ' ago', 'tutor' ) ); ?>
579 </span>
580 </div>
581 <div class="tutor-comment-text tutor-fs-6 tutor-mt-4">
582 <?php echo esc_html( $reply->comment_content ); ?>
583 </div>
584 </div>
585 </div>
586 </div>
587 <?php
588 $html = ob_get_clean();
589 wp_send_json_success( array( 'html' => $html ) );
590 }
591
592 /**
593 * Get comments
594 *
595 * @since 2.0.6
596 * @see Checkout arguments details: https://developer.wordpress.org/reference/classes/wp_comment_query/__construct/
597 *
598 * @param array $args arguments.
599 * @return mixed based on arguments
600 */
601 public static function get_comments( array $args ) {
602 $comments = get_comments( $args );
603 return $comments;
604 }
605
606 /**
607 * Create comment
608 *
609 * @since 1.0.0
610 *
611 * @param array $request request.
612 * @return mixed comment id on success, false on failure
613 */
614 public static function create_comment( array $request ) {
615 $current_user = wp_get_current_user();
616 $default_data = array(
617 'comment_content' => '',
618 'comment_post_ID' => '',
619 'comment_parent' => '',
620 'user_id' => $current_user->ID,
621 'comment_author' => $current_user->user_login,
622 'comment_author_email' => $current_user->user_email,
623 'comment_author_url' => $current_user->user_url,
624 'comment_agent' => 'Tutor',
625 );
626 $comment_data = wp_parse_args( $request, $default_data );
627 return wp_insert_comment( $comment_data );
628 }
629
630 }
631