PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.8.3
Tutor LMS – eLearning and online course solution v3.8.3
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 / Ajax.php
tutor / classes Last commit date
Addons.php 11 months ago Admin.php 9 months ago Ajax.php 9 months ago Announcements.php 1 year ago Assets.php 10 months ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 11 months ago Container.php 11 months ago Course.php 9 months ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 10 months ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 1 year ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 9 months ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Icon.php 9 months ago Input.php 1 year ago Instructor.php 1 year ago Instructors_List.php 11 months ago Lesson.php 10 months ago Options_V2.php 9 months ago Permalink.php 2 years ago Post_types.php 1 year ago Private_Course_Access.php 1 year ago Q_And_A.php 10 months ago Question_Answers_List.php 11 months ago Quiz.php 9 months ago QuizBuilder.php 11 months ago Quiz_Attempts_List.php 9 months ago RestAPI.php 2 years ago Reviews.php 9 months ago Rewrite_Rules.php 2 years ago Shortcode.php 9 months ago Singleton.php 1 year ago Student.php 1 year ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 9 months ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 1 year ago Tutor.php 9 months ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 1 year ago Upgrader.php 9 months ago User.php 1 year ago Utils.php 9 months ago Video_Stream.php 3 years ago WhatsNew.php 9 months ago Withdraw.php 1 year ago Withdraw_Requests_List.php 11 months ago WooCommerce.php 9 months ago
Ajax.php
639 lines
1 <?php
2 /**
3 * Handle Ajax Request
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\Models\LessonModel;
19 use Tutor\Traits\JsonResponse;
20
21 /**
22 * Ajax Class
23 *
24 * @since 1.0.0
25 */
26 class Ajax {
27 use JsonResponse;
28
29 const LOGIN_ERRORS_TRANSIENT_KEY = 'tutor_login_errors';
30 /**
31 * Constructor
32 *
33 * @since 1.0.0
34 * @since 2.6.2 added allow_hooks param.
35 *
36 * @param bool $allow_hooks default value true.
37 *
38 * @return void
39 */
40 public function __construct( $allow_hooks = true ) {
41 if ( $allow_hooks ) {
42 add_action( 'wp_ajax_sync_video_playback', array( $this, 'sync_video_playback' ) );
43 add_action( 'wp_ajax_nopriv_sync_video_playback', array( $this, 'sync_video_playback_noprev' ) );
44 add_action( 'wp_ajax_tutor_place_rating', array( $this, 'tutor_place_rating' ) );
45 add_action( 'wp_ajax_delete_tutor_review', array( $this, 'delete_tutor_review' ) );
46
47 add_action( 'wp_ajax_tutor_course_add_to_wishlist', array( $this, 'tutor_course_add_to_wishlist' ) );
48 add_action( 'wp_ajax_nopriv_tutor_course_add_to_wishlist', array( $this, 'tutor_course_add_to_wishlist' ) );
49
50 /**
51 * Ajax login
52 *
53 * @since v.1.6.3
54 */
55 add_action( 'tutor_action_tutor_user_login', array( $this, 'process_tutor_login' ) );
56
57 /**
58 * Announcement
59 *
60 * @since v.1.7.9
61 */
62 add_action( 'wp_ajax_tutor_announcement_create', array( $this, 'create_or_update_annoucement' ) );
63 add_action( 'wp_ajax_tutor_announcement_delete', array( $this, 'delete_annoucement' ) );
64
65 add_action( 'wp_ajax_tutor_youtube_video_duration', array( $this, 'ajax_youtube_video_duration' ) );
66 }
67 }
68
69
70
71 /**
72 * Update video information and data when necessary
73 *
74 * @since 1.0.0
75 * @return void
76 */
77 public function sync_video_playback() {
78 tutor_utils()->checking_nonce();
79
80 $user_id = get_current_user_id();
81 $post_id = Input::post( 'post_id', 0, Input::TYPE_INT );
82 $duration = Input::post( 'duration' );
83 $current_time = Input::post( 'currentTime' );
84
85 if ( ! tutor_utils()->has_enrolled_content_access( 'lesson', $post_id ) ) {
86 wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
87 exit;
88 }
89
90 /**
91 * Update posts attached video
92 */
93 $video = tutor_utils()->get_video( $post_id );
94
95 if ( $duration ) {
96 $video['duration_sec'] = $duration; // Duration in sec.
97 $video['playtime'] = tutor_utils()->playtime_string( $duration );
98 $video['runtime'] = tutor_utils()->playtime_array( $duration );
99 }
100 tutor_utils()->update_video( $post_id, $video );
101
102 /**
103 * Sync Lesson Reading Info by Users
104 */
105
106 $best_watch_time = tutor_utils()->get_lesson_reading_info( $post_id, $user_id, 'video_best_watched_time' );
107 if ( $best_watch_time < $current_time ) {
108 LessonModel::update_lesson_reading_info( $post_id, $user_id, 'video_best_watched_time', $current_time );
109 }
110
111 if ( Input::post( 'is_ended', false, Input::TYPE_BOOL ) ) {
112 LessonModel::mark_lesson_complete( $post_id );
113 LessonModel::update_lesson_reading_info( $post_id, $user_id, 'video_best_watched_time', 0 );
114 }
115 exit();
116 }
117
118 /**
119 * Video playback callback for noprev
120 *
121 * @since 1.0.0
122 * @return void
123 */
124 public function sync_video_playback_noprev() {
125 }
126
127 /**
128 * Place rating
129 *
130 * @since 1.0.0
131 * @return void
132 */
133 public function tutor_place_rating() {
134 tutor_utils()->checking_nonce();
135
136 $user_id = get_current_user_id();
137 $course_id = Input::post( 'course_id' );
138 $rating = Input::post( 'tutor_rating_gen_input', 0, Input::TYPE_INT );
139 $review = Input::post( 'review', '', Input::TYPE_TEXTAREA );
140
141 $rating <= 0 ? $rating = 1 : 0;
142 $rating > 5 ? $rating = 5 : 0;
143
144 $this->add_or_update_review( $user_id, $course_id, $rating, $review );
145 }
146
147 /**
148 * Add/Update rating
149 *
150 * @param int $user_id the user id.
151 * @param int $course_id the course id.
152 * @param int $rating rating star number.
153 * @param string $review review description.
154 * @param int $review_id review id needed for api update.
155 *
156 * @return void|string
157 */
158 public function add_or_update_review( $user_id, $course_id, $rating, $review, $review_id = 0 ) {
159 global $wpdb;
160
161 $moderation = tutor_utils()->get_option( 'enable_course_review_moderation', false, true, true );
162 $user = get_userdata( $user_id );
163 $date = date( 'Y-m-d H:i:s', tutor_time() ); //phpcs:ignore
164
165 if ( ! tutor_is_rest() && ! tutor_utils()->has_enrolled_content_access( 'course', $course_id ) ) {
166 wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
167 exit;
168 }
169
170 do_action( 'tutor_before_rating_placed' );
171
172 $is_edit = 0 === $review_id ? false : true;
173
174 if ( ! tutor_is_rest() ) {
175 $previous_rating_id = $wpdb->get_var(
176 $wpdb->prepare(
177 "SELECT comment_ID
178 from {$wpdb->comments}
179 WHERE comment_post_ID = %d AND
180 user_id = %d AND
181 comment_type = 'tutor_course_rating'
182 LIMIT 1;",
183 $course_id,
184 $user_id
185 )
186 );
187
188 if ( ! empty( $previous_rating_id ) ) {
189 $review_id = $previous_rating_id;
190 $is_edit = true;
191 }
192 }
193
194 if ( $is_edit ) {
195 $wpdb->update(
196 $wpdb->comments,
197 array(
198 'comment_content' => $review,
199 'comment_approved' => $moderation ? 'hold' : 'approved',
200 'comment_date' => $date,
201 'comment_date_gmt' => get_gmt_from_date( $date ),
202 ),
203 array( 'comment_ID' => $review_id )
204 );
205
206 $rating_info = $wpdb->get_row(
207 $wpdb->prepare(
208 "SELECT * FROM {$wpdb->commentmeta}
209 WHERE comment_id = %d
210 AND meta_key = 'tutor_rating'; ",
211 $review_id
212 )
213 );
214
215 if ( $rating_info ) {
216 $wpdb->update(
217 $wpdb->commentmeta,
218 array( 'meta_value' => $rating ),
219 array(
220 'comment_id' => $review_id,
221 'meta_key' => 'tutor_rating',
222 )
223 );
224 } else {
225 $wpdb->insert(
226 $wpdb->commentmeta,
227 array(
228 'comment_id' => $review_id,
229 'meta_key' => 'tutor_rating',
230 'meta_value' => $rating,
231 )
232 );
233 }
234 } else {
235 $data = array(
236 'comment_post_ID' => esc_sql( $course_id ),
237 'comment_approved' => $moderation ? 'hold' : 'approved',
238 'comment_type' => 'tutor_course_rating',
239 'comment_date' => $date,
240 'comment_date_gmt' => get_gmt_from_date( $date ),
241 'user_id' => $user_id,
242 'comment_author' => $user->user_login,
243 'comment_agent' => 'TutorLMSPlugin',
244 );
245 if ( $review ) {
246 $data['comment_content'] = $review;
247 }
248
249 $wpdb->insert( $wpdb->comments, $data );
250 $comment_id = (int) $wpdb->insert_id;
251 $review_id = $comment_id;
252
253 if ( $comment_id ) {
254 $wpdb->insert(
255 $wpdb->commentmeta,
256 array(
257 'comment_id' => $comment_id,
258 'meta_key' => 'tutor_rating',
259 'meta_value' => $rating,
260 )
261 );
262
263 do_action( 'tutor_after_rating_placed', $comment_id );
264 }
265 }
266
267 if ( ! tutor_is_rest() ) {
268 wp_send_json_success(
269 array(
270 'message' => __( 'Rating placed successfully!', 'tutor' ),
271 'review_id' => $review_id,
272 )
273 );
274 } else {
275 return $is_edit ? 'updated' : 'created';
276 }
277 }
278
279 /**
280 * Delete a review
281 *
282 * @since 1.0.0
283 * @since 2.6.2 added params user_id.
284 * @param int $user_id the user id.
285 * @return void|bool
286 */
287 public function delete_tutor_review( $user_id = 0 ) {
288 if ( ! tutor_is_rest() ) {
289 tutor_utils()->checking_nonce();
290 }
291
292 $review_id = Input::post( 'review_id' );
293
294 if ( ! tutor_utils()->can_user_manage( 'review', $review_id, tutils()->get_user_id( $user_id ) ) ) {
295 wp_send_json_error( array( 'message' => __( 'Permissioned Denied!', 'tutor' ) ) );
296 exit;
297 }
298
299 global $wpdb;
300 $wpdb->delete( $wpdb->commentmeta, array( 'comment_id' => $review_id ) );
301 $wpdb->delete( $wpdb->comments, array( 'comment_ID' => $review_id ) );
302
303 if ( tutor_is_rest() ) {
304 return true;
305 }
306
307 wp_send_json_success();
308 }
309
310 /**
311 * Add course in wishlist
312 *
313 * @since 1.0.0
314 * @return void|string
315 */
316 public function tutor_course_add_to_wishlist() {
317 tutor_utils()->checking_nonce();
318
319 $is_enabled_wishlist = tutor_utils()->get_option( 'enable_wishlist', true );
320 if ( ! $is_enabled_wishlist ) {
321 wp_send_json_error( array( 'message' => __( 'Wishlist option is disabled', 'tutor' ) ) );
322 }
323
324 // Redirect login since only logged in user can add courses to wishlist.
325 if ( ! is_user_logged_in() ) {
326 wp_send_json_error(
327 array(
328 'redirect_to' => wp_login_url( wp_get_referer() ),
329 )
330 );
331 }
332
333 $user_id = get_current_user_id();
334 $course_id = Input::post( 'course_id', 0, Input::TYPE_INT );
335
336 $result = $this->add_or_delete_wishlist( $user_id, $course_id );
337
338 if ( tutor_is_rest() ) {
339 return $result;
340 } elseif ( 'added' === $result ) {
341 wp_send_json_success(
342 array(
343 'status' => 'added',
344 'message' => __( 'Course added to wish list', 'tutor' ),
345 )
346 );
347 } else {
348 wp_send_json_success(
349 array(
350 'status' => 'removed',
351 'message' => __( 'Course removed from wish list', 'tutor' ),
352 )
353 );
354 }
355 }
356
357 /**
358 * Add or Delete wishlist by user_id and course_id
359 *
360 * @since 2.6.2
361 *
362 * @param int $user_id the user id.
363 * @param int $course_id the course_id to add to the wishlist.
364 *
365 * @return string
366 */
367 public function add_or_delete_wishlist( $user_id, $course_id ) {
368 global $wpdb;
369
370 $if_added_to_list = tutor_utils()->is_wishlisted( $course_id, $user_id );
371
372 $result = '';
373
374 if ( $if_added_to_list ) {
375 $wpdb->delete(
376 $wpdb->usermeta,
377 array(
378 'user_id' => $user_id,
379 'meta_key' => '_tutor_course_wishlist',
380 'meta_value' => $course_id,
381 )
382 );
383
384 $result = 'removed';
385 } else {
386 add_user_meta( $user_id, '_tutor_course_wishlist', $course_id );
387
388 $result = 'added';
389 }
390
391 return $result;
392 }
393
394 /**
395 * Process tutor login
396 *
397 * @since 1.6.3
398 *
399 * @since 2.1.3 Ajax removed, validation errors
400 * stores in session.
401 *
402 * @return void
403 */
404 public function process_tutor_login() {
405 $validation_error = new \WP_Error();
406
407 /**
408 * Separate nonce verification added to show nonce verification
409 * failed message in a proper way.
410 *
411 * @since 2.1.4
412 */
413 if ( ! wp_verify_nonce( $_POST[ tutor()->nonce ], tutor()->nonce_action ) ) { //phpcs:ignore
414 $validation_error->add( 401, __( 'Nonce verification failed', 'tutor' ) );
415 \set_transient( self::LOGIN_ERRORS_TRANSIENT_KEY, $validation_error->get_error_messages() );
416 return;
417 }
418 //phpcs:disable WordPress.Security.NonceVerification.Missing
419
420 /**
421 * No sanitization/wp_unslash needed for log & pwd since WordPress
422 * does itself
423 *
424 * @since 2.1.3
425 *
426 * @see https://developer.wordpress.org/reference/functions/wp_signon/
427 */
428 $username = tutor_utils()->array_get( 'log', $_POST ); //phpcs:ignore
429 $password = tutor_utils()->array_get( 'pwd', $_POST ); //phpcs:ignore
430 $redirect_to = isset( $_POST['redirect_to'] ) ? esc_url_raw( wp_unslash( $_POST['redirect_to'] ) ) : '';
431 $remember = isset( $_POST['rememberme'] );
432
433 try {
434 $creds = array(
435 'user_login' => trim( $username ),
436 'user_password' => $password,
437 'remember' => $remember,
438 );
439
440 $validation_error = apply_filters( 'tutor_process_login_errors', $validation_error, $creds['user_login'], $creds['user_password'] );
441
442 if ( $validation_error->get_error_code() ) {
443 $validation_error->add(
444 $validation_error->get_error_code(),
445 $validation_error->get_error_message()
446 );
447 }
448
449 if ( empty( $creds['user_login'] ) ) {
450 $validation_error->add(
451 400,
452 __( 'Username is required.', 'tutor' )
453 );
454 }
455
456 // On multi-site, ensure user exists on current site, if not add them before allowing login.
457 if ( is_multisite() ) {
458 $user_data = get_user_by( is_email( $creds['user_login'] ) ? 'email' : 'login', $creds['user_login'] );
459
460 if ( $user_data && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) {
461 add_user_to_blog( get_current_blog_id(), $user_data->ID, 'customer' );
462 }
463 }
464
465 // Perform the login.
466 $user = wp_signon( apply_filters( 'tutor_login_credentials', $creds ), is_ssl() );
467
468 if ( is_wp_error( $user ) ) {
469 // If no error exist then add WP login error, to prevent error duplication.
470 if ( ! $validation_error->has_errors() ) {
471 $validation_error->add( 400, $user->get_error_message() );
472 }
473 } else {
474 do_action( 'tutor_after_login_success', $user->ID );
475 // Since 1.9.8 do enroll if guest attempt to enroll.
476 $course_enroll_attempt = Input::post( 'tutor_course_enroll_attempt' );
477 if ( ! empty( $course_enroll_attempt ) && is_a( $user, 'WP_User' ) ) {
478 do_action( 'tutor_do_enroll_after_login_if_attempt', $course_enroll_attempt, $user->ID );
479 }
480 wp_safe_redirect( $redirect_to );
481 exit();
482 }
483 } catch ( \Exception $e ) {
484 do_action( 'tutor_login_failed' );
485 $validation_error->add( 400, $e->getMessage() );
486 } finally {
487 // Store errors in transient data.
488 \set_transient( self::LOGIN_ERRORS_TRANSIENT_KEY, $validation_error->get_error_messages() );
489 }
490 }
491
492 /**
493 * Create/Update announcement
494 *
495 * @since 1.7.9
496 * @return void
497 */
498 public function create_or_update_annoucement() {
499 tutor_utils()->checking_nonce();
500
501 $error = array();
502 $course_id = Input::post( 'tutor_announcement_course' );
503 $announcement_title = Input::post( 'tutor_announcement_title' );
504 $announcement_summary = Input::post( 'tutor_announcement_summary', '', Input::TYPE_TEXTAREA );
505
506 // Check if user can manage this announcment.
507 if ( ! tutor_utils()->can_user_manage( 'course', $course_id ) ) {
508 wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
509 }
510
511 // Set data and sanitize it.
512 $form_data = array(
513 'post_type' => 'tutor_announcements',
514 'post_title' => $announcement_title,
515 'post_content' => $announcement_summary,
516 'post_parent' => $course_id,
517 'post_status' => 'publish',
518 );
519
520 if ( Input::has( 'announcement_id' ) ) {
521 $form_data['ID'] = Input::post( 'announcement_id' );
522 }
523
524 if ( ! empty( $form_data['ID'] ) ) {
525 if ( ! tutor_utils()->can_user_manage( 'announcement', $form_data['ID'] ) ) {
526 wp_send_json_error( array( 'message' => tutor_utils()->error_message() ) );
527 }
528 }
529
530 // Validation message set.
531 if ( empty( $form_data['post_parent'] ) ) {
532 $error['post_parent'] = __( 'Course name required', 'tutor' );
533
534 }
535
536 if ( empty( $form_data['post_title'] ) ) {
537 $error['post_title'] = __( 'Announcement title required', 'tutor' );
538 }
539
540 if ( empty( $form_data['post_content'] ) ) {
541 $error['post_content'] = __( 'Announcement summary required', 'tutor' );
542
543 }
544
545 if ( empty( $form_data['post_content'] ) ) {
546 $error['post_content'] = __( 'Announcement summary required', 'tutor' );
547
548 }
549
550 // If validation fails.
551 if ( count( $error ) > 0 ) {
552 wp_send_json_error(
553 array(
554 'message' => __( 'All fields required!', 'tutor' ),
555 'fields' => $error,
556 )
557 );
558 }
559
560 // Insert or update post.
561 $post_id = wp_insert_post( $form_data );
562 if ( $post_id > 0 ) {
563 $announcement = get_post( $post_id );
564 $action_type = Input::post( 'action_type' );
565
566 do_action( 'tutor_announcements/after/save', $post_id, $announcement, $action_type );
567
568 $resp_message = 'create' === $action_type ? __( 'Announcement created successfully', 'tutor' ) : __( 'Announcement updated successfully', 'tutor' );
569 wp_send_json_success( array( 'message' => $resp_message ) );
570 }
571
572 wp_send_json_error( array( 'message' => __( 'Something Went Wrong!', 'tutor' ) ) );
573 }
574
575 /**
576 * Delete announcement
577 *
578 * @since 1.7.9
579 * @return void
580 */
581 public function delete_annoucement() {
582 tutor_utils()->checking_nonce();
583
584 $announcement_id = Input::post( 'announcement_id' );
585
586 if ( ! tutor_utils()->can_user_manage( 'announcement', $announcement_id ) ) {
587 wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
588 }
589
590 $delete = wp_delete_post( $announcement_id );
591 if ( $delete ) {
592 wp_send_json_success( array( 'message' => __( 'Announcement deleted successfully', 'tutor' ) ) );
593 }
594
595 wp_send_json_error( array( 'message' => __( 'Announcement delete failed', 'tutor' ) ) );
596 }
597
598 /**
599 * Get youtube video duration.
600 *
601 * @since 3.0.0
602 *
603 * @return void
604 */
605 public function ajax_youtube_video_duration() {
606 tutor_utils()->check_nonce();
607
608 $video_id = Input::post( 'video_id' );
609 if ( empty( $video_id ) ) {
610 $this->json_response( __( 'Video ID is required', 'tutor' ), null, HttpHelper::STATUS_BAD_REQUEST );
611 }
612
613 tutor_utils()->check_current_user_capability( 'edit_tutor_course' );
614
615 $api_key = tutor_utils()->get_option( 'lesson_video_duration_youtube_api_key', '' );
616 $url = "https://www.googleapis.com/youtube/v3/videos?id=$video_id&part=contentDetails&key=$api_key";
617
618 $request = HttpHelper::get( $url );
619 if ( HttpHelper::STATUS_OK === $request->get_status_code() ) {
620 $response = $request->get_json();
621 if ( isset( $response->items[0]->contentDetails->duration ) ) {
622 $duration = $response->items[0]->contentDetails->duration;
623 $this->json_response(
624 __( 'Fetched duration successfully', 'tutor' ),
625 array(
626 'duration' => $duration,
627 )
628 );
629 }
630 }
631
632 $this->json_response(
633 __( 'Failed to fetch duration', 'tutor' ),
634 null,
635 HttpHelper::STATUS_BAD_REQUEST
636 );
637 }
638 }
639