PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.4.0
Tutor LMS – eLearning and online course solution v1.4.0
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 / Course.php
tutor / classes Last commit date
Addons.php 6 years ago Admin.php 6 years ago Ajax.php 6 years ago Assets.php 6 years ago Course.php 6 years ago Course_Widget.php 6 years ago Dashboard.php 6 years ago Gutenberg.php 6 years ago Instructor.php 6 years ago Instructors_List.php 6 years ago Lesson.php 6 years ago Options.php 6 years ago Post_types.php 6 years ago Q_and_A.php 6 years ago Question.php 6 years ago Question_Answers_List.php 6 years ago Quiz.php 6 years ago Quiz_Attempts_List.php 6 years ago Rewrite_Rules.php 6 years ago Shortcode.php 6 years ago Student.php 6 years ago Students_List.php 6 years ago Taxonomies.php 6 years ago Template.php 6 years ago Theme_Compatibility.php 6 years ago Tools.php 6 years ago Tutor.php 6 years ago TutorEDD.php 6 years ago Tutor_Base.php 6 years ago Tutor_List_Table.php 6 years ago Upgrader.php 6 years ago User.php 6 years ago Utils.php 6 years ago Video_Stream.php 6 years ago Withdraw.php 6 years ago Withdraw_Requests_List.php 6 years ago WooCommerce.php 6 years ago
Course.php
768 lines
1 <?php
2 namespace TUTOR;
3
4 if ( ! defined( 'ABSPATH' ) )
5 exit;
6
7 class Course extends Tutor_Base {
8 public function __construct() {
9 parent::__construct();
10
11 add_action( 'add_meta_boxes', array($this, 'register_meta_box') );
12 add_action('save_post_'.$this->course_post_type, array($this, 'save_course_meta'), 10, 2);
13 add_action('wp_ajax_tutor_add_course_topic', array($this, 'tutor_add_course_topic'));
14 add_action('wp_ajax_tutor_update_topic', array($this, 'tutor_update_topic'));
15
16 //Add Column
17 add_filter( "manage_{$this->course_post_type}_posts_columns", array($this, 'add_column'), 10,1 );
18 add_action( "manage_{$this->course_post_type}_posts_custom_column" , array($this, 'custom_lesson_column'), 10, 2 );
19
20 add_action('admin_action_tutor_delete_topic', array($this, 'tutor_delete_topic'));
21 add_action('admin_action_tutor_delete_announcement', array($this, 'tutor_delete_announcement'));
22
23 //Frontend Action
24 add_action('template_redirect', array($this, 'enroll_now'));
25 add_action('template_redirect', array($this, 'mark_course_complete'));
26
27 //Modal Perform
28 add_action('wp_ajax_tutor_load_instructors_modal', array($this, 'tutor_load_instructors_modal'));
29 add_action('wp_ajax_tutor_add_instructors_to_course', array($this, 'tutor_add_instructors_to_course'));
30 add_action('wp_ajax_detach_instructor_from_course', array($this, 'detach_instructor_from_course'));
31
32 /**
33 * Frontend Dashboard
34 */
35 add_action('wp_ajax_tutor_delete_dashboard_course', array($this, 'tutor_delete_dashboard_course'));
36
37 /**
38 * Gutenberg author support
39 */
40
41 add_filter('wp_insert_post_data', array($this, 'tutor_add_gutenberg_author'), '99', 2);
42
43 /**
44 * Frontend metabox supports for course builder
45 * @since v.1.3.4
46 */
47
48 add_action('tutor/dashboard_course_builder_form_field_after', array($this, 'register_meta_box_in_frontend'));
49
50
51 /**
52 * Do Stuff for the course save from frontend
53 */
54 add_action('save_tutor_course', array($this, 'attach_product_with_course'), 10, 2);
55 }
56 /**
57 * Registering metabox
58 */
59 public function register_meta_box(){
60 $coursePostType = tutor()->course_post_type;
61 $course_marketplace = tutor_utils()->get_option('enable_course_marketplace');
62 add_meta_box( 'tutor-course-levels', __( 'Course Level', 'tutor' ), array($this, 'course_level_metabox'), $coursePostType );
63 add_meta_box( 'tutor-course-topics', __( 'Course Builder', 'tutor' ), array($this, 'course_meta_box'), $coursePostType );
64 add_meta_box( 'tutor-course-additional-data', __( 'Additional Data', 'tutor' ), array($this, 'course_additional_data_meta_box'), $coursePostType );
65 add_meta_box( 'tutor-course-videos', __( 'Video', 'tutor' ), array($this, 'video_metabox'), $coursePostType );
66 if ($course_marketplace) {
67 add_meta_box( 'tutor-instructors', __( 'Instructors', 'tutor' ), array( $this, 'instructors_metabox' ), $coursePostType );
68 }
69 add_meta_box( 'tutor-announcements', __( 'Announcements', 'tutor' ), array($this, 'announcements_metabox'), $coursePostType );
70 }
71 public function course_meta_box($echo = true){
72 ob_start();
73 include tutor()->path.'views/metabox/course-topics.php';
74 $content = ob_get_clean();
75
76 if ($echo){
77 echo $content;
78 }else{
79 return $content;
80 }
81 }
82 public function course_additional_data_meta_box($echo = true){
83
84 ob_start();
85 include tutor()->path.'views/metabox/course-additional-data.php';
86 $content = ob_get_clean();
87
88 if ($echo){
89 echo $content;
90 }else{
91 return $content;
92 }
93 }
94 public function video_metabox($echo = true){
95 ob_start();
96 include tutor()->path.'views/metabox/video-metabox.php';
97 $content = ob_get_clean();
98
99 if ($echo){
100 echo $content;
101 }else{
102 return $content;
103 }
104 }
105
106 public function course_level_metabox($echo = true){
107 ob_start();
108 include tutor()->path.'views/metabox/course-level-metabox.php';
109 $content = ob_get_clean();
110
111 if ($echo){
112 echo $content;
113 }else{
114 return $content;
115 }
116 }
117
118 public function announcements_metabox($echo = true){
119 ob_start();
120 include tutor()->path.'views/metabox/announcements-metabox.php';
121 $content = ob_get_clean();
122
123 if ($echo){
124 echo $content;
125 }else{
126 return $content;
127 }
128 }
129
130 public function instructors_metabox($echo = true){
131 ob_start();
132 include tutor()->path . 'views/metabox/instructors-metabox.php';
133 $content = ob_get_clean();
134
135 if ($echo){
136 echo $content;
137 }else{
138 return $content;
139 }
140 }
141
142 /**
143 * Register metabox in course builder tutor
144 * @since v.1.3.4
145 */
146 public function register_meta_box_in_frontend(){
147 do_action('tutor_course_builder_metabox_before', get_the_ID());
148 course_builder_section_wrap($this->video_metabox($echo = false), 'Video');
149 course_builder_section_wrap($this->course_meta_box($echo = false), 'Course Builder');
150 course_builder_section_wrap($this->instructors_metabox($echo = false), 'Instructors');
151 course_builder_section_wrap($this->course_additional_data_meta_box($echo = false), 'Additional Data');
152 course_builder_section_wrap($this->announcements_metabox($echo = false), 'Announcements');
153 do_action('tutor_course_builder_metabox_after', get_the_ID());
154 }
155
156 /**
157 * @param $post_ID
158 *
159 * Insert Topic and attached it with Course
160 */
161 public function save_course_meta($post_ID, $post){
162 global $wpdb;
163 /**
164 * Insert Topic
165 */
166 /*
167 if ( ! empty($_POST['topic_title'])) {
168 $topic_title = sanitize_text_field( $_POST['topic_title'] );
169 $topic_summery = wp_kses_post( $_POST['topic_summery'] );
170
171 $post_arr = array(
172 'post_type' => 'topics',
173 'post_title' => $topic_title,
174 'post_content' => $topic_summery,
175 'post_status' => 'publish',
176 'post_author' => get_current_user_id(),
177 'post_parent' => $post_ID,
178 );
179 wp_insert_post( $post_arr );
180 }*/
181
182 /**
183 * Save course price type
184 */
185 $price_type = tutils()->array_get('tutor_course_price_type', $_POST);
186 if ($price_type){
187 update_post_meta($post_ID, '_tutor_course_price_type', $price_type);
188 }
189
190 //Course Duration
191 if ( ! empty($_POST['course_duration'])){
192 $video = tutor_utils()->sanitize_array($_POST['course_duration']);
193 update_post_meta($post_ID, '_course_duration', $video);
194 }
195
196 if ( ! empty($_POST['course_level'])){
197 $course_level = sanitize_text_field($_POST['course_level']);
198 update_post_meta($post_ID, '_tutor_course_level', $course_level);
199 }
200
201 if ( ! empty($_POST['course_benefits'])){
202 $course_benefits = wp_kses_post($_POST['course_benefits']);
203 update_post_meta($post_ID, '_tutor_course_benefits', $course_benefits);
204 }
205
206 if ( ! empty($_POST['course_requirements'])){
207 $requirements = wp_kses_post($_POST['course_requirements']);
208 update_post_meta($post_ID, '_tutor_course_requirements', $requirements);
209 }
210
211 if ( ! empty($_POST['course_target_audience'])){
212 $target_audience = wp_kses_post($_POST['course_target_audience']);
213 update_post_meta($post_ID, '_tutor_course_target_audience', $target_audience);
214 }
215
216 if ( ! empty($_POST['course_material_includes'])){
217 $material_includes = wp_kses_post($_POST['course_material_includes']);
218 update_post_meta($post_ID, '_tutor_course_material_includes', $material_includes);
219 }
220 /**
221 * Sorting Topics and lesson
222 */
223 if ( ! empty($_POST['tutor_topics_lessons_sorting'])){
224 $new_order = sanitize_text_field(stripslashes($_POST['tutor_topics_lessons_sorting']));
225 $order = json_decode($new_order, true);
226
227 if (is_array($order) && count($order)){
228 $i = 0;
229 foreach ($order as $topic ){
230 $i++;
231 $wpdb->update(
232 $wpdb->posts,
233 array('menu_order' => $i),
234 array('ID' => $topic['topic_id'])
235 );
236
237 /**
238 * Removing All lesson with topic
239 */
240
241 $wpdb->update(
242 $wpdb->posts,
243 array('post_parent' => 0),
244 array('post_parent' => $topic['topic_id'])
245 );
246
247 /**
248 * Lesson Attaching with topic ID
249 * sorting lesson
250 */
251 if (isset($topic['lesson_ids'])){
252 $lesson_ids = $topic['lesson_ids'];
253 }else{
254 $lesson_ids = array();
255 }
256 if (count($lesson_ids)){
257 foreach ($lesson_ids as $lesson_key => $lesson_id ){
258 $wpdb->update(
259 $wpdb->posts,
260 array('post_parent' => $topic['topic_id'], 'menu_order' => $lesson_key),
261 array('ID' => $lesson_id)
262 );
263 }
264 }
265 }
266 }
267 }
268
269 //Video
270 if ( ! empty($_POST['video']['source'])){
271 //$video = tutor_utils()->sanitize_array($_POST['video']);
272 $video = tutor_utils()->array_get('video', $_POST);
273 update_post_meta($post_ID, '_video', $video);
274 }else{
275 delete_post_meta($post_ID, '_video');
276 }
277
278 /**
279 * Adding author to instructor automatically
280 */
281
282 $author_id = $post->post_author;
283 $attached = (int) $wpdb->get_var(" SELECT COUNT(umeta_id) FROM {$wpdb->usermeta} WHERE user_id = {$author_id} AND meta_key = '_tutor_instructor_course_id' AND meta_value = {$post_ID} ");
284 if ( ! $attached){
285 add_user_meta($author_id, '_tutor_instructor_course_id', $post_ID);
286 }
287
288 //Announcements
289 if ( ! wp_doing_ajax()) {
290 $announcement_title = tutor_utils()->avalue_dot( 'announcements.title', $_POST );
291 if ( ! empty( $announcement_title ) ) {
292 $title = sanitize_text_field( tutor_utils()->avalue_dot( 'announcements.title', $_POST ) );
293 $content = wp_kses_post( tutor_utils()->avalue_dot( 'announcements.content', $_POST ) );
294
295 $post_arr = array(
296 'post_type' => 'tutor_announcements',
297 'post_title' => $title,
298 'post_content' => $content,
299 'post_status' => 'publish',
300 'post_author' => get_current_user_id(),
301 'post_parent' => $post_ID,
302 );
303 wp_insert_post( $post_arr );
304 }
305 }
306 }
307
308 /**
309 * Tutor add course topic
310 */
311 public function tutor_add_course_topic(){
312 if (empty($_POST['topic_title']) ) {
313 wp_send_json_error();
314 }
315 $course_id = (int) tutor_utils()->avalue_dot('tutor_topic_course_ID', $_POST);
316 $next_topic_order_id = tutor_utils()->get_next_topic_order_id($course_id);
317
318 $topic_title = sanitize_text_field( $_POST['topic_title'] );
319 $topic_summery = wp_kses_post( $_POST['topic_summery'] );
320
321 $post_arr = array(
322 'post_type' => 'topics',
323 'post_title' => $topic_title,
324 'post_content' => $topic_summery,
325 'post_status' => 'publish',
326 'post_author' => get_current_user_id(),
327 'post_parent' => $course_id,
328 'menu_order' => $next_topic_order_id,
329 );
330 $current_topic_id = wp_insert_post( $post_arr );
331
332 ob_start();
333 include tutor()->path.'views/metabox/course-contents.php';
334 $course_contents = ob_get_clean();
335
336 wp_send_json_success(array('course_contents' => $course_contents));
337 }
338
339 /**
340 * Update the topic
341 */
342 public function tutor_update_topic(){
343 $topic_id = (int) sanitize_text_field($_POST['topic_id']);
344 $topic_title = sanitize_text_field($_POST['topic_title']);
345 $topic_summery = wp_kses_post($_POST['topic_summery']);
346
347 $topic_attr = array(
348 'ID' => $topic_id,
349 'post_title' => $topic_title,
350 'post_content' => $topic_summery,
351 );
352 wp_update_post( $topic_attr );
353
354 wp_send_json_success(array('msg' => __('Topic has been updated', 'tutor') ));
355 }
356
357
358 /**
359 * @param $columns
360 *
361 * @return mixed
362 *
363 * Add Lesson column
364 */
365
366 public function add_column($columns){
367 $date_col = $columns['date'];
368 unset($columns['date']);
369 $columns['lessons'] = __('Lessons', 'tutor');
370 $columns['students'] = __('Students', 'tutor');
371 $columns['price'] = __('Price', 'tutor');
372 $columns['date'] = $date_col;
373
374 return $columns;
375 }
376
377 /**
378 * @param $column
379 * @param $post_id
380 *
381 */
382 public function custom_lesson_column($column, $post_id ){
383 if ($column === 'lessons'){
384 echo tutor_utils()->get_lesson_count_by_course($post_id);
385 }
386
387 if ($column === 'students'){
388 echo tutor_utils()->count_enrolled_users_by_course($post_id);
389 }
390
391 if ($column === 'price'){
392 $price = tutor_utils()->get_course_price($post_id);
393 if ($price){
394 $monetize_by = tutils()->get_option('monetize_by');
395 if (function_exists('wc_price') && $monetize_by === 'wc'){
396 echo '<span class="tutor-label-success">'.wc_price($price).'</span>';
397 }else{
398 echo '<span class="tutor-label-success">'.$price.'</span>';
399 }
400 }else{
401 echo 'free';
402 }
403 }
404 }
405
406
407 public function tutor_delete_topic(){
408 if (!isset($_GET[tutor()->nonce]) || !wp_verify_nonce($_GET[tutor()->nonce], tutor()->nonce_action)) {
409 exit();
410 }
411 if ( ! isset($_GET['topic_id'])){
412 exit();
413 }
414
415 global $wpdb;
416
417 $topic_id = (int) sanitize_text_field($_GET['topic_id']);
418 $wpdb->update(
419 $wpdb->posts,
420 array('post_parent' => 0),
421 array('post_parent' => $topic_id)
422 );
423
424 $wpdb->delete(
425 $wpdb->postmeta,
426 array('post_id' => $topic_id)
427 );
428
429 wp_delete_post($topic_id);
430 wp_safe_redirect(wp_get_referer());
431 }
432
433 public function tutor_delete_announcement(){
434 tutor_utils()->checking_nonce('get');
435
436 $announcement_id = (int) sanitize_text_field($_GET['topic_id']);
437
438 wp_delete_post($announcement_id);
439 wp_safe_redirect(wp_get_referer());
440 }
441
442 public function enroll_now(){
443
444 //Checking if action comes from Enroll form
445 if (tutor_utils()->array_get('tutor_course_action', $_POST) !== '_tutor_course_enroll_now' || ! isset($_POST['tutor_course_id']) ){
446 return;
447 }
448 //Checking Nonce
449 tutor_utils()->checking_nonce();
450
451 $user_id = get_current_user_id();
452 if ( ! $user_id){
453 exit(__('Please Sign In first', 'tutor'));
454 }
455
456 $course_id = (int) sanitize_text_field($_POST['tutor_course_id']);
457 $user_id = get_current_user_id();
458
459 /**
460 * TODO: need to check purchase information
461 */
462
463 $is_purchasable = tutor_utils()->is_course_purchasable($course_id);
464
465 /**
466 * If is is not purchasable, it's free, and enroll right now
467 *
468 * if purchasable, then process purchase.
469 *
470 * @since: v.1.0.0
471 */
472 if ($is_purchasable){
473 //process purchase
474
475 }else{
476 //Free enroll
477 tutor_utils()->do_enroll($course_id);
478 }
479
480 $referer_url = wp_get_referer();
481 wp_redirect($referer_url);
482 }
483
484 /**
485 *
486 * Mark complete completed
487 *
488 * @since v.1.0.0
489 */
490 public function mark_course_complete(){
491 if ( ! isset($_POST['tutor_action']) || $_POST['tutor_action'] !== 'tutor_complete_course' ){
492 return;
493 }
494 //Checking nonce
495 tutor_utils()->checking_nonce();
496
497 $user_id = get_current_user_id();
498
499 //TODO: need to show view if not signed_in
500 if ( ! $user_id){
501 die(__('Please Sign-In', 'tutor'));
502 }
503
504 $course_id = (int) sanitize_text_field($_POST['course_id']);
505
506 do_action('tutor_course_complete_before', $course_id);
507 /**
508 * Marking course completed at Comment
509 */
510
511 global $wpdb;
512
513 $date = date("Y-m-d H:i:s");
514
515 //Making sure that, hash is unique
516 do{
517 $hash = substr(md5(wp_generate_password(32).$date.$course_id.$user_id), 0, 16);
518 $hasHash = (int) $wpdb->get_var("SELECT COUNT(comment_ID) from {$wpdb->comments} WHERE comment_agent = 'TutorLMSPlugin' AND comment_type = 'course_completed' AND comment_content = '{$hash}' ");
519 }while($hasHash > 0);
520
521 $data = array(
522 'comment_post_ID' => $course_id,
523 'comment_author' => $user_id,
524 'comment_date' => $date,
525 'comment_date_gmt' => get_gmt_from_date($date),
526 'comment_content' => $hash, //Identification Hash
527 'comment_approved' => 'approved',
528 'comment_agent' => 'TutorLMSPlugin',
529 'comment_type' => 'course_completed',
530 'user_id' => $user_id,
531 );
532
533 $wpdb->insert($wpdb->comments, $data);
534
535 do_action('tutor_course_complete_after', $course_id);
536
537 wp_redirect(get_the_permalink($course_id));
538 }
539
540
541 public function tutor_load_instructors_modal(){
542 global $wpdb;
543
544 $course_id = (int) sanitize_text_field($_POST['course_id']);
545 $search_terms = sanitize_text_field(tutor_utils()->avalue_dot('search_terms', $_POST));
546
547 $saved_instructors = tutor_utils()->get_instructors_by_course($course_id);
548
549 $instructors = array();
550
551
552 $not_in_sql = apply_filters('tutor_instructor_query_when_exists', " AND ID <1 ");
553
554 if ($saved_instructors){
555 $saved_instructors_ids = wp_list_pluck($saved_instructors, 'ID');
556 $instructor_not_in_ids = implode(',', $saved_instructors_ids);
557 $not_in_sql .= "AND ID NOT IN($instructor_not_in_ids) ";
558 }
559
560 $search_sql = '';
561 if ($search_terms){
562 $search_sql = "AND (user_login like '%{$search_terms}%' or user_nicename like '%{$search_terms}%' or display_name like '%{$search_terms}%') ";
563 }
564
565 $instructors = $wpdb->get_results("select ID, display_name from {$wpdb->users}
566 INNER JOIN {$wpdb->usermeta} ON ID = user_id AND meta_key = '_tutor_instructor_status' AND meta_value = 'approved'
567 WHERE 1=1 {$not_in_sql} {$search_sql} limit 10 ");
568
569 $output = '';
570 if (is_array($instructors) && count($instructors)){
571 $instructor_output = '';
572 foreach ($instructors as $instructor){
573 $instructor_output .= "<p><label><input type='radio' name='tutor_instructor_ids[]' value='{$instructor->ID}' > {$instructor->display_name} </label></p>";
574 }
575
576 $output .= apply_filters('tutor_course_instructors_html', $instructor_output, $instructors);
577
578 }else{
579 $output .= __('<p>No instructor available or you have already added maximum instructors</p>', 'tutor');
580 }
581
582
583 if ( ! defined('TUTOR_MT_VERSION')){
584 $output .= '<p class="tutor-notice-warning" style="margin-top: 50px; font-size: 14px;">'. sprintf( __('To add unlimited multiple instructors in your course, get %sTutor LMS Pro%s', 'tutor'), '<a href="https://www.themeum.com/product/tutor-lms" target="_blank">', "</a>" ) .'</p>';
585 }
586
587 wp_send_json_success(array('output' => $output));
588 }
589
590 public function tutor_add_instructors_to_course(){
591 $course_id = (int) sanitize_text_field($_POST['course_id']);
592 $instructor_ids = tutor_utils()->avalue_dot('tutor_instructor_ids', $_POST);
593
594 if (is_array($instructor_ids) && count($instructor_ids)){
595 foreach ($instructor_ids as $instructor_id){
596 add_user_meta($instructor_id, '_tutor_instructor_course_id', $course_id);
597 }
598 }
599
600 $saved_instructors = tutor_utils()->get_instructors_by_course($course_id);
601 $output = '';
602
603 if ($saved_instructors){
604 foreach ($saved_instructors as $t){
605
606 $output .= '<div id="added-instructor-id-'.$t->ID.'" class="added-instructor-item added-instructor-item-'.$t->ID.'" data-instructor-id="'.$t->ID.'">
607 <span class="instructor-icon">'.get_avatar($t->ID, 30).'</span>
608 <span class="instructor-name"> '.$t->display_name.' </span>
609 <span class="instructor-control">
610 <a href="javascript:;" class="tutor-instructor-delete-btn"><i class="tutor-icon-line-cross"></i></a>
611 </span>
612 </div>';
613 }
614 }
615
616 wp_send_json_success(array('output' => $output));
617 }
618
619 public function detach_instructor_from_course(){
620 global $wpdb;
621
622 $instructor_id = (int) sanitize_text_field($_POST['instructor_id']);
623 $course_id = (int) sanitize_text_field($_POST['course_id']);
624
625 $wpdb->delete($wpdb->usermeta, array('user_id' => $instructor_id, 'meta_key' => '_tutor_instructor_course_id', 'meta_value' => $course_id) );
626 wp_send_json_success();
627 }
628
629 public function tutor_delete_dashboard_course(){
630 $course_id = intval(sanitize_text_field($_POST['course_id']));
631 wp_trash_post($course_id);
632 wp_send_json_success();
633 }
634
635
636 public function tutor_add_gutenberg_author($data , $postarr){
637 global $wpdb;
638
639 $post_author = (int) tutor_utils()->avalue_dot('post_author', $data);
640
641 if ( ! $post_author){
642 $user_ID = (int) tutor_utils()->avalue_dot('user_ID', $postarr);
643 if ($user_ID){
644 $data['post_author'] = $user_ID;
645 }else{
646 global $wpdb;
647
648 $post_ID = (int) tutor_utils()->avalue_dot('ID', $postarr);
649 $post_author = (int) $wpdb->get_var("SELECT post_author FROM {$wpdb->posts} WHERE ID = {$post_ID} ");
650
651 $data['post_author'] = $post_author;
652 }
653 }
654
655 return $data;
656 }
657
658
659 /**
660 * @param $post_ID
661 * @param $postData
662 *
663 * Attach product during save course from the frontend course dashboard.
664 *
665 * @return string
666 *
667 * @since v.1.3.4
668 */
669
670 public function attach_product_with_course($post_ID, $postData){
671 $attached_product_id = tutor_utils()->get_course_product_id($post_ID);
672 $course_price = sanitize_text_field(tutor_utils()->array_get('course_price', $_POST));
673
674 if ( ! $course_price){
675 return;
676 }
677
678 $monetize_by = tutor_utils()->get_option('monetize_by');
679 $course = get_post($post_ID);
680
681 if ($monetize_by === 'wc'){
682
683 $is_update = false;
684 if ($attached_product_id){
685 $wc_product = get_post_meta($attached_product_id, '_product_version', true);
686 if ($wc_product){
687 $is_update = true;
688 }
689 }
690
691 if ($is_update){
692
693 $productObj = new \WC_Product($attached_product_id);
694 $productObj->set_price($course_price); // set product price
695 $productObj->set_regular_price($course_price); // set product regular price
696 $product_id = $productObj->save();
697
698 }else{
699
700 $productObj = new \WC_Product();
701 $productObj->set_name($course->post_title);
702 $productObj->set_status('publish');
703 $productObj->set_price($course_price); // set product price
704 $productObj->set_regular_price($course_price); // set product regular price
705
706 $product_id = $productObj->save();
707 if ($product_id) {
708 update_post_meta( $post_ID, '_tutor_course_product_id', $product_id );
709 //Mark product for woocommerce
710 update_post_meta( $product_id, '_virtual', 'yes' );
711 update_post_meta( $product_id, '_tutor_product', 'yes' );
712
713 $coursePostThumbnail = get_post_meta( $post_ID, '_thumbnail_id', true );
714 if ( $coursePostThumbnail ) {
715 set_post_thumbnail( $product_id, $coursePostThumbnail );
716 }
717 }
718 }
719
720 }elseif ($monetize_by === 'edd'){
721
722 $is_update = false;
723
724 if ($attached_product_id){
725 $edd_price = get_post_meta($attached_product_id, 'edd_price', true);
726 if ($edd_price){
727 $is_update = true;
728 }
729 }
730
731 if ($is_update){
732 //Update the product
733 update_post_meta( $attached_product_id, 'edd_price', $course_price );
734 }else{
735 //Create new product
736
737 $post_arr = array(
738 'post_type' => 'download',
739 'post_title' => $course->post_title,
740 'post_status' => 'publish',
741 'post_author' => get_current_user_id(),
742 );
743 $download_id = wp_insert_post( $post_arr );
744 if ($download_id ) {
745 //edd_price
746 update_post_meta( $download_id, 'edd_price', $course_price );
747
748 update_post_meta( $post_ID, '_tutor_course_product_id', $download_id );
749 //Mark product for EDD
750 update_post_meta( $download_id, '_tutor_product', 'yes' );
751
752 $coursePostThumbnail = get_post_meta( $post_ID, '_thumbnail_id', true );
753 if ( $coursePostThumbnail ) {
754 set_post_thumbnail( $download_id, $coursePostThumbnail );
755 }
756
757 }
758
759 }
760
761
762 }
763
764 }
765
766
767
768 }