PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.7.7
Tutor LMS – eLearning and online course solution v1.7.7
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 5 years ago Admin.php 5 years ago Ajax.php 5 years ago Assets.php 5 years ago Course.php 5 years ago Course_Filter.php 5 years ago Course_Settings_Tabs.php 5 years ago Course_Widget.php 5 years ago Custom_Validation.php 5 years ago Dashboard.php 5 years ago Delete_Enrollment_With_Order.php 5 years ago Email.php 5 years ago FormHandler.php 5 years ago Frontend.php 5 years ago Gutenberg.php 5 years ago Instructor.php 5 years ago Instructors_List.php 5 years ago Lesson.php 5 years ago Options.php 5 years ago Post_types.php 5 years ago Private_Course_Access.php 5 years ago Q_and_A.php 5 years ago Question_Answers_List.php 5 years ago Quiz.php 5 years ago Quiz_Attempts_List.php 5 years ago RestAPI.php 5 years ago Rewrite_Rules.php 5 years ago Shortcode.php 5 years ago Student.php 5 years ago Students_List.php 5 years ago Taxonomies.php 5 years ago Template.php 5 years ago Theme_Compatibility.php 5 years ago Tools.php 5 years ago Tutor.php 5 years ago TutorEDD.php 5 years ago Tutor_Base.php 5 years ago Tutor_List_Table.php 5 years ago Tutor_Setup.php 5 years ago Upgrader.php 5 years ago User.php 5 years ago Utils.php 5 years ago Video_Stream.php 5 years ago Withdraw.php 5 years ago Withdraw_Requests_List.php 5 years ago WooCommerce.php 5 years ago
Course.php
1307 lines
1 <?php
2 namespace TUTOR;
3
4 if ( ! defined( 'ABSPATH' ) )
5 exit;
6
7 class Course extends Tutor_Base {
8
9 private $additional_meta=array(
10 '_tutor_disable_qa',
11 '_tutor_is_public_course'
12 );
13
14 public function __construct() {
15 parent::__construct();
16
17 add_action( 'add_meta_boxes', array($this, 'register_meta_box') );
18 add_action('save_post_'.$this->course_post_type, array($this, 'save_course_meta'), 10, 2);
19 add_action('wp_ajax_tutor_add_course_topic', array($this, 'tutor_add_course_topic'));
20 add_action('wp_ajax_tutor_update_topic', array($this, 'tutor_update_topic'));
21
22 //Add Column
23 add_filter( "manage_{$this->course_post_type}_posts_columns", array($this, 'add_column'), 10,1 );
24 add_action( "manage_{$this->course_post_type}_posts_custom_column" , array($this, 'custom_lesson_column'), 10, 2 );
25
26 add_action('admin_action_tutor_delete_topic', array($this, 'tutor_delete_topic'));
27 add_action('admin_action_tutor_delete_announcement', array($this, 'tutor_delete_announcement'));
28
29 //Frontend Action
30 add_action('template_redirect', array($this, 'enroll_now'));
31 add_action('template_redirect', array($this, 'mark_course_complete'));
32
33 //Modal Perform
34 add_action('wp_ajax_tutor_load_instructors_modal', array($this, 'tutor_load_instructors_modal'));
35 add_action('wp_ajax_tutor_add_instructors_to_course', array($this, 'tutor_add_instructors_to_course'));
36 add_action('wp_ajax_detach_instructor_from_course', array($this, 'detach_instructor_from_course'));
37
38 /**
39 * Frontend Dashboard
40 */
41 add_action('wp_ajax_tutor_delete_dashboard_course', array($this, 'tutor_delete_dashboard_course'));
42
43 /**
44 * Gutenberg author support
45 */
46 add_filter('wp_insert_post_data', array($this, 'tutor_add_gutenberg_author'), '99', 2);
47
48 /**
49 * Frontend metabox supports for course builder
50 * @since v.1.3.4
51 */
52 add_action('tutor/dashboard_course_builder_form_field_after', array($this, 'register_meta_box_in_frontend'));
53
54
55 /**
56 * Do Stuff for the course save from frontend
57 */
58 add_action('save_tutor_course', array($this, 'attach_product_with_course'), 10, 2);
59
60 /**
61 * Add course level to course settings
62 * @since v.1.4.1
63 */
64 add_action('tutor_course/settings_tab_content/after/general', array($this, 'add_course_level_to_settings'));
65
66 /**
67 * Enable Disable Course Details Page Feature
68 * @since v.1.4.8
69 */
70 $this->course_elements_enable_disable();
71
72 /**
73 * @since v.1.4.8
74 * Check if course starting, set meta if starting
75 */
76 add_action('tutor_lesson_load_before', array($this, 'tutor_lesson_load_before'));
77
78 /**
79 * @since v.1.4.9
80 * Filter product in shop page
81 */
82 $this->filter_product_in_shop_page();
83
84 /**
85 * Remove the course price if enrolled
86 * @since 1.5.8
87 */
88 add_filter('tutor_course_price', array($this, 'remove_price_if_enrolled'));
89
90
91 /**
92 * Remove course complete button if course completion is strict mode
93 * @since v.1.6.1
94 */
95 add_filter('tutor_course/single/complete_form', array($this, 'tutor_lms_hide_course_complete_btn'));
96 add_filter('get_gradebook_generate_form_html', array($this, 'get_generate_greadbook'));
97
98 /**
99 * Add social share content in header
100 * @since v.1.6.3
101 */
102 add_action('wp_head', array($this, 'social_share_content'));
103
104 /**
105 * Delete course data after deleted course
106 * @since v.1.6.6
107 */
108 add_action('deleted_post', array($this, 'delete_tutor_course_data'));
109
110
111 add_action('tutor/dashboard_course_builder_form_field_after', array($this, 'tutor_course_setting_metabox_frontend'));
112 }
113
114 /**
115 * Registering metabox
116 */
117 public function register_meta_box(){
118 $coursePostType = tutor()->course_post_type;
119 $course_marketplace = tutor_utils()->get_option('enable_course_marketplace');
120 //add_meta_box( 'tutor-course-levels', __( 'Course Level', 'tutor' ), array($this, 'course_level_metabox'), $coursePostType );
121 add_meta_box( 'tutor-course-topics', __( 'Course Builder', 'tutor' ), array($this, 'course_meta_box'), $coursePostType );
122 add_meta_box( 'tutor-course-additional-data', __( 'Additional Data', 'tutor' ), array($this, 'course_additional_data_meta_box'), $coursePostType );
123 add_meta_box( 'tutor-course-videos', __( 'Video', 'tutor' ), array($this, 'video_metabox'), $coursePostType );
124 if ($course_marketplace) {
125 add_meta_box( 'tutor-instructors', __( 'Instructors', 'tutor' ), array( $this, 'instructors_metabox' ), $coursePostType );
126 }
127 add_meta_box( 'tutor-announcements', __( 'Announcements', 'tutor' ), array($this, 'announcements_metabox'), $coursePostType );
128
129 /**
130 * Tutor course sidebar settings metabox
131 * @since v.1.7.0
132 */
133 add_meta_box( 'tutor-course-sidebar-settings', __( 'Tutor Settings', 'tutor' ), array($this, 'tutor_course_setting_metabox'), $coursePostType, 'side' );
134 }
135
136 public function course_meta_box($echo = true){
137 ob_start();
138 include tutor()->path.'views/metabox/course-topics.php';
139 $content = ob_get_clean();
140
141 if ($echo){
142 echo $content;
143 }else{
144 return $content;
145 }
146 }
147
148 public function course_additional_data_meta_box($echo = true){
149
150 ob_start();
151 include tutor()->path.'views/metabox/course-additional-data.php';
152 $content = ob_get_clean();
153
154 if ($echo){
155 echo $content;
156 }else{
157 return $content;
158 }
159 }
160
161 public function video_metabox($echo = true){
162 ob_start();
163 include tutor()->path.'views/metabox/video-metabox.php';
164 $content = ob_get_clean();
165
166 if ($echo){
167 echo $content;
168 }else{
169 return $content;
170 }
171 }
172
173 public function course_level_metabox($echo = true){
174 ob_start();
175 include tutor()->path.'views/metabox/course-level-metabox.php';
176 $content = ob_get_clean();
177
178 if ($echo){
179 echo $content;
180 }else{
181 return $content;
182 }
183 }
184
185 public function announcements_metabox($echo = true){
186 ob_start();
187 include tutor()->path.'views/metabox/announcements-metabox.php';
188 $content = ob_get_clean();
189
190 if ($echo){
191 echo $content;
192 }else{
193 return $content;
194 }
195 }
196
197 public function instructors_metabox($echo = true){
198 ob_start();
199 include tutor()->path . 'views/metabox/instructors-metabox.php';
200 $content = ob_get_clean();
201
202 if ($echo){
203 echo $content;
204 }else{
205 return $content;
206 }
207 }
208
209 /**
210 * Register metabox in course builder tutor
211 * @since v.1.3.4
212 */
213 public function register_meta_box_in_frontend(){
214 do_action('tutor_course_builder_metabox_before', get_the_ID());
215 course_builder_section_wrap($this->video_metabox($echo = false), __( 'Video', 'tutor' ) );
216 course_builder_section_wrap($this->course_meta_box($echo = false), __( 'Course Builder', 'tutor' ) );
217 course_builder_section_wrap($this->instructors_metabox($echo = false), __( 'Instructors', 'tutor' ) );
218 course_builder_section_wrap($this->course_additional_data_meta_box($echo = false), __( 'Additional Data', 'tutor' ) );
219 course_builder_section_wrap($this->announcements_metabox($echo = false), __( 'Announcements', 'tutor' ) );
220 do_action('tutor_course_builder_metabox_after', get_the_ID());
221 }
222
223 /**
224 * @param $post_ID
225 *
226 * Insert Topic and attached it with Course
227 */
228 public function save_course_meta($post_ID, $post){
229 global $wpdb;
230
231 do_action( "tutor_save_course", $post_ID, $post);
232
233 /**
234 * Insert Topic
235 */
236 /*
237 if ( ! empty($_POST['topic_title'])) {
238 $topic_title = sanitize_text_field( $_POST['topic_title'] );
239 $topic_summery = wp_kses_post( $_POST['topic_summery'] );
240
241 $post_arr = array(
242 'post_type' => 'topics',
243 'post_title' => $topic_title,
244 'post_content' => $topic_summery,
245 'post_status' => 'publish',
246 'post_author' => get_current_user_id(),
247 'post_parent' => $post_ID,
248 );
249 wp_insert_post( $post_arr );
250 }*/
251
252 /**
253 * Save course price type
254 */
255 $price_type = tutils()->array_get('tutor_course_price_type', $_POST);
256 if ($price_type){
257 update_post_meta($post_ID, '_tutor_course_price_type', $price_type);
258 }
259
260 //Course Duration
261 if ( ! empty($_POST['course_duration'])){
262 $video = tutils()->sanitize_array($_POST['course_duration']);
263 update_post_meta($post_ID, '_course_duration', $video);
264 }
265
266 if ( ! empty($_POST['course_level'])){
267 $course_level = sanitize_text_field($_POST['course_level']);
268 update_post_meta($post_ID, '_tutor_course_level', $course_level);
269 }
270
271 $additional_data_edit = tutils()->avalue_dot('_tutor_course_additional_data_edit', $_POST);
272 if ($additional_data_edit) {
273 if (!empty($_POST['course_benefits'])) {
274 $course_benefits = wp_kses_post($_POST['course_benefits']);
275 update_post_meta($post_ID, '_tutor_course_benefits', $course_benefits);
276 } else {
277 delete_post_meta($post_ID, '_tutor_course_benefits');
278 }
279
280 if (!empty($_POST['course_requirements'])) {
281 $requirements = wp_kses_post($_POST['course_requirements']);
282 update_post_meta($post_ID, '_tutor_course_requirements', $requirements);
283 } else {
284 delete_post_meta($post_ID, '_tutor_course_requirements');
285 }
286
287 if (!empty($_POST['course_target_audience'])) {
288 $target_audience = wp_kses_post($_POST['course_target_audience']);
289 update_post_meta($post_ID, '_tutor_course_target_audience', $target_audience);
290 } else {
291 delete_post_meta($post_ID, '_tutor_course_target_audience');
292 }
293
294 if (!empty($_POST['course_material_includes'])) {
295 $material_includes = wp_kses_post($_POST['course_material_includes']);
296 update_post_meta($post_ID, '_tutor_course_material_includes', $material_includes);
297 } else {
298 delete_post_meta($post_ID, '_tutor_course_material_includes');
299 }
300 }
301
302
303 /**
304 * Sorting Topics and lesson
305 */
306 if ( ! empty($_POST['tutor_topics_lessons_sorting'])){
307 $new_order = sanitize_text_field(stripslashes($_POST['tutor_topics_lessons_sorting']));
308 $order = json_decode($new_order, true);
309
310 if (is_array($order) && count($order)){
311 $i = 0;
312 foreach ($order as $topic ){
313 $i++;
314 $wpdb->update(
315 $wpdb->posts,
316 array('menu_order' => $i),
317 array('ID' => $topic['topic_id'])
318 );
319
320 /**
321 * Removing All lesson with topic
322 */
323
324 $wpdb->update(
325 $wpdb->posts,
326 array('post_parent' => 0),
327 array('post_parent' => $topic['topic_id'])
328 );
329
330 /**
331 * Lesson Attaching with topic ID
332 * sorting lesson
333 */
334 if (isset($topic['lesson_ids'])){
335 $lesson_ids = $topic['lesson_ids'];
336 }else{
337 $lesson_ids = array();
338 }
339 if (count($lesson_ids)){
340 foreach ($lesson_ids as $lesson_key => $lesson_id ){
341 $wpdb->update(
342 $wpdb->posts,
343 array('post_parent' => $topic['topic_id'], 'menu_order' => $lesson_key),
344 array('ID' => $lesson_id)
345 );
346 }
347 }
348 }
349 }
350 }
351
352 if ($additional_data_edit) {
353 if ( ! empty($_POST['video']['source'])) { //Video
354 $video = tutor_utils()->array_get('video', $_POST);
355 update_post_meta($post_ID, '_video', $video);
356 }else{
357 delete_post_meta($post_ID, '_video');
358 }
359 }
360
361 /**
362 * Adding author to instructor automatically
363 */
364
365 $author_id = $post->post_author;
366 $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} ");
367 if ( ! $attached){
368 add_user_meta($author_id, '_tutor_instructor_course_id', $post_ID);
369 }
370
371 //Announcements
372 if ( ! wp_doing_ajax()) {
373 $announcement_title = tutor_utils()->avalue_dot( 'announcements.title', $_POST );
374 if ( ! empty( $announcement_title ) ) {
375 $title = sanitize_text_field( tutor_utils()->avalue_dot( 'announcements.title', $_POST ) );
376 $content = wp_kses_post( tutor_utils()->avalue_dot( 'announcements.content', $_POST ) );
377
378 $post_arr = array(
379 'post_type' => 'tutor_announcements',
380 'post_title' => $title,
381 'post_content' => $content,
382 'post_status' => 'publish',
383 'post_author' => get_current_user_id(),
384 'post_parent' => $post_ID,
385 );
386 $announcement_id = wp_insert_post( $post_arr );
387
388 if ($announcement_id) {
389 $announcement = (object) $post_arr;
390 do_action('tutor_announcements/after/save', $announcement_id, $announcement);
391 }
392 }
393 }
394
395 /**
396 * Disable question and answer for this course
397 * @since 1.7.0
398 */
399 if ($additional_data_edit) {
400
401 foreach($this->additional_meta as $key){
402 update_post_meta($post_ID, $key, (isset($_POST[$key]) ? 'yes' : 'no'));
403 }
404 }
405
406 do_action( "tutor_save_course_after", $post_ID, $post);
407 }
408
409 /**
410 * Tutor add course topic
411 */
412 public function tutor_add_course_topic(){
413 if (empty($_POST['topic_title']) ) {
414 wp_send_json_error();
415 }
416 $course_id = (int) tutor_utils()->avalue_dot('tutor_topic_course_ID', $_POST);
417 $next_topic_order_id = tutor_utils()->get_next_topic_order_id($course_id);
418
419 if(!tutils()->can_user_manage('course', $course_id)) {
420 wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
421 }
422
423 $topic_title = sanitize_text_field( $_POST['topic_title'] );
424 $topic_summery = wp_kses_post( $_POST['topic_summery'] );
425
426 $post_arr = array(
427 'post_type' => 'topics',
428 'post_title' => $topic_title,
429 'post_content' => $topic_summery,
430 'post_status' => 'publish',
431 'post_author' => get_current_user_id(),
432 'post_parent' => $course_id,
433 'menu_order' => $next_topic_order_id,
434 );
435 $current_topic_id = wp_insert_post( $post_arr );
436
437 ob_start();
438 include tutor()->path.'views/metabox/course-contents.php';
439 $course_contents = ob_get_clean();
440
441 wp_send_json_success(array('course_contents' => $course_contents));
442 }
443
444 /**
445 * Update the topic
446 */
447 public function tutor_update_topic(){
448 $topic_id = (int) sanitize_text_field($_POST['topic_id']);
449 $topic_title = sanitize_text_field($_POST['topic_title']);
450 $topic_summery = wp_kses_post($_POST['topic_summery']);
451
452 if(!tutils()->can_user_manage('topic', $topic_id)) {
453 wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
454 }
455
456 $topic_attr = array(
457 'ID' => $topic_id,
458 'post_title' => $topic_title,
459 'post_content' => $topic_summery,
460 );
461 wp_update_post( $topic_attr );
462
463 wp_send_json_success(array('msg' => __('Topic has been updated', 'tutor') ));
464 }
465
466
467 /**
468 * @param $columns
469 *
470 * @return mixed
471 *
472 * Add Lesson column
473 */
474 public function add_column($columns){
475 $date_col = $columns['date'];
476 unset($columns['date']);
477 $columns['lessons'] = __('Lessons', 'tutor');
478 $columns['students'] = __('Students', 'tutor');
479 $columns['price'] = __('Price', 'tutor');
480 $columns['date'] = $date_col;
481
482 return $columns;
483 }
484
485 /**
486 * @param $column
487 * @param $post_id
488 *
489 */
490 public function custom_lesson_column($column, $post_id ){
491 if ($column === 'lessons'){
492 echo tutor_utils()->get_lesson_count_by_course($post_id);
493 }
494
495 if ($column === 'students'){
496 echo tutor_utils()->count_enrolled_users_by_course($post_id);
497 }
498
499 if ($column === 'price'){
500 $price = tutor_utils()->get_course_price($post_id);
501 if ($price){
502 $monetize_by = tutils()->get_option('monetize_by');
503 if (function_exists('wc_price') && $monetize_by === 'wc'){
504 echo '<span class="tutor-label-success">'.wc_price($price).'</span>';
505 }else{
506 echo '<span class="tutor-label-success">'.$price.'</span>';
507 }
508 }else{
509 echo apply_filters('tutor-loop-default-price', 'free');
510 }
511 }
512 }
513
514
515 public function tutor_delete_topic(){
516 if (!isset($_GET[tutor()->nonce]) || !wp_verify_nonce($_GET[tutor()->nonce], tutor()->nonce_action)) {
517 exit();
518 }
519 if ( ! isset($_GET['topic_id'])){
520 exit();
521 }
522
523 global $wpdb;
524
525 $topic_id = (int) sanitize_text_field($_GET['topic_id']);
526 $wpdb->update(
527 $wpdb->posts,
528 array('post_parent' => 0),
529 array('post_parent' => $topic_id)
530 );
531
532 $wpdb->delete(
533 $wpdb->postmeta,
534 array('post_id' => $topic_id)
535 );
536
537 wp_delete_post($topic_id);
538 wp_safe_redirect(wp_get_referer());
539 }
540
541 public function tutor_delete_announcement(){
542 tutor_utils()->checking_nonce('get');
543
544 $announcement_id = (int) sanitize_text_field($_GET['topic_id']);
545
546 wp_delete_post($announcement_id);
547 wp_safe_redirect(wp_get_referer());
548 }
549
550 public function enroll_now(){
551
552 //Checking if action comes from Enroll form
553 if (tutor_utils()->array_get('tutor_course_action', $_POST) !== '_tutor_course_enroll_now' || ! isset($_POST['tutor_course_id']) ){
554 return;
555 }
556 //Checking Nonce
557 tutor_utils()->checking_nonce();
558
559 $user_id = get_current_user_id();
560 if ( ! $user_id){
561 exit(__('Please Sign In first', 'tutor'));
562 }
563
564 $course_id = (int) sanitize_text_field($_POST['tutor_course_id']);
565 $user_id = get_current_user_id();
566
567 /**
568 * TODO: need to check purchase information
569 */
570
571 $is_purchasable = tutor_utils()->is_course_purchasable($course_id);
572
573 /**
574 * If is is not purchasable, it's free, and enroll right now
575 *
576 * if purchasable, then process purchase.
577 *
578 * @since: v.1.0.0
579 */
580 if ($is_purchasable){
581 //process purchase
582
583 }else{
584 //Free enroll
585 tutor_utils()->do_enroll($course_id);
586 }
587
588 $referer_url = wp_get_referer();
589 wp_redirect($referer_url);
590 }
591
592 /**
593 *
594 * Mark complete completed
595 *
596 * @since v.1.0.0
597 */
598 public function mark_course_complete(){
599 if ( ! isset($_POST['tutor_action']) || $_POST['tutor_action'] !== 'tutor_complete_course' ){
600 return;
601 }
602 //Checking nonce
603 tutor_utils()->checking_nonce();
604
605 $user_id = get_current_user_id();
606
607 //TODO: need to show view if not signed_in
608 if ( ! $user_id){
609 die(__('Please Sign-In', 'tutor'));
610 }
611
612 $course_id = (int) sanitize_text_field($_POST['course_id']);
613
614 do_action('tutor_course_complete_before', $course_id);
615 /**
616 * Marking course completed at Comment
617 */
618
619 global $wpdb;
620
621 $date = date("Y-m-d H:i:s", tutor_time());
622
623 //Making sure that, hash is unique
624 do{
625 $hash = substr(md5(wp_generate_password(32).$date.$course_id.$user_id), 0, 16);
626 $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}' ");
627 }while($hasHash > 0);
628
629 $data = array(
630 'comment_post_ID' => $course_id,
631 'comment_author' => $user_id,
632 'comment_date' => $date,
633 'comment_date_gmt' => get_gmt_from_date($date),
634 'comment_content' => $hash, //Identification Hash
635 'comment_approved' => 'approved',
636 'comment_agent' => 'TutorLMSPlugin',
637 'comment_type' => 'course_completed',
638 'user_id' => $user_id,
639 );
640
641 $wpdb->insert($wpdb->comments, $data);
642
643 do_action('tutor_course_complete_after', $course_id, $user_id);
644
645 wp_redirect(get_the_permalink($course_id));
646 }
647
648
649 public function tutor_load_instructors_modal(){
650 global $wpdb;
651
652 $course_id = (int) sanitize_text_field($_POST['course_id']);
653 $search_terms = sanitize_text_field(tutor_utils()->avalue_dot('search_terms', $_POST));
654
655 if(!tutils()->can_user_manage('course', $course_id)) {
656 wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
657 }
658
659 $saved_instructors = tutor_utils()->get_instructors_by_course($course_id);
660 $instructors = array();
661
662 $not_in_sql = apply_filters('tutor_instructor_query_when_exists', " AND ID <1 ");
663
664 if ($saved_instructors){
665 $saved_instructors_ids = wp_list_pluck($saved_instructors, 'ID');
666 $instructor_not_in_ids = implode(',', $saved_instructors_ids);
667 $not_in_sql .= "AND ID NOT IN($instructor_not_in_ids) ";
668 }
669
670 $search_sql = '';
671 if ($search_terms){
672 $search_sql = "AND (user_login like '%{$search_terms}%' or user_nicename like '%{$search_terms}%' or display_name like '%{$search_terms}%') ";
673 }
674
675 $instructors = $wpdb->get_results("select ID, display_name from {$wpdb->users}
676 INNER JOIN {$wpdb->usermeta} ON ID = user_id AND meta_key = '_tutor_instructor_status' AND meta_value = 'approved'
677 WHERE 1=1 {$not_in_sql} {$search_sql} limit 10 ");
678
679 $output = '';
680 if (is_array($instructors) && count($instructors)){
681 $instructor_output = '';
682 foreach ($instructors as $instructor){
683 $instructor_output .= "<p><label><input type='radio' name='tutor_instructor_ids[]' value='{$instructor->ID}' > {$instructor->display_name} </label></p>";
684 }
685
686 $output .= apply_filters('tutor_course_instructors_html', $instructor_output, $instructors);
687
688 }else{
689 $output .= __('<p>No instructor available or you have already added maximum instructors</p>', 'tutor');
690 }
691
692
693 if ( ! defined('TUTOR_MT_VERSION')){
694 $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>';
695 }
696
697 wp_send_json_success(array('output' => $output));
698 }
699
700 public function tutor_add_instructors_to_course(){
701 $course_id = (int) sanitize_text_field($_POST['course_id']);
702 $instructor_ids = tutor_utils()->avalue_dot('tutor_instructor_ids', $_POST);
703
704 if(!tutils()->can_user_manage('course', $course_id)) {
705 wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
706 }
707
708 if (is_array($instructor_ids) && count($instructor_ids)){
709 foreach ($instructor_ids as $instructor_id){
710 add_user_meta($instructor_id, '_tutor_instructor_course_id', $course_id);
711 }
712 }
713
714 $saved_instructors = tutor_utils()->get_instructors_by_course($course_id);
715 $output = '';
716
717 if ($saved_instructors){
718 foreach ($saved_instructors as $t){
719
720 $output .= '<div id="added-instructor-id-'.$t->ID.'" class="added-instructor-item added-instructor-item-'.$t->ID.'" data-instructor-id="'.$t->ID.'">
721 <span class="instructor-icon">'.get_avatar($t->ID, 30).'</span>
722 <span class="instructor-name"> '.$t->display_name.' </span>
723 <span class="instructor-control">
724 <a href="javascript:;" class="tutor-instructor-delete-btn"><i class="tutor-icon-line-cross"></i></a>
725 </span>
726 </div>';
727 }
728 }
729
730 wp_send_json_success(array('output' => $output));
731 }
732
733 public function detach_instructor_from_course(){
734 global $wpdb;
735
736 $instructor_id = (int) sanitize_text_field($_POST['instructor_id']);
737 $course_id = (int) sanitize_text_field($_POST['course_id']);
738
739 if(!tutils()->can_user_manage('course', $course_id)) {
740 wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
741 }
742
743 $wpdb->delete($wpdb->usermeta, array('user_id' => $instructor_id, 'meta_key' => '_tutor_instructor_course_id', 'meta_value' => $course_id) );
744 wp_send_json_success();
745 }
746
747 public function tutor_delete_dashboard_course(){
748 $course_id = intval(sanitize_text_field($_POST['course_id']));
749
750 if(!tutils()->can_user_manage('course', $course_id)) {
751 wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
752 }
753
754 wp_trash_post($course_id);
755 wp_send_json_success(['element'=>'course']);
756 }
757
758
759 public function tutor_add_gutenberg_author($data , $postarr){
760 global $wpdb;
761
762 $courses_post_type = tutor()->course_post_type;
763 $post_type = tutils()->array_get('post_type', $postarr);
764
765 /*
766 $post_author = (int) tutor_utils()->avalue_dot('post_author', $data);
767
768 if ( ! $post_author){
769 $user_ID = (int) tutor_utils()->avalue_dot('user_ID', $postarr);
770 if ($user_ID){
771 $data['post_author'] = $user_ID;
772 }else{
773 $post_ID = (int) tutor_utils()->avalue_dot('ID', $postarr);
774 $post_author = (int) $wpdb->get_var("SELECT post_author FROM {$wpdb->posts} WHERE ID = {$post_ID} ");
775
776 $data['post_author'] = $post_author;
777 }
778 }*/
779
780 if ($courses_post_type === $post_type){
781 $post_ID = (int) tutor_utils()->avalue_dot('ID', $postarr);
782 $post_author = (int) $wpdb->get_var("SELECT post_author FROM {$wpdb->posts} WHERE ID = {$post_ID} ");
783
784 if ($post_author > 0){
785 $data['post_author'] = $post_author;
786 }else{
787 $data['post_author'] = get_current_user_id();
788 }
789 }
790
791 return $data;
792 }
793
794
795 /**
796 * @param $post_ID
797 * @param $postData
798 *
799 * Attach product during save course from the frontend course dashboard.
800 *
801 * @return string
802 *
803 * @since v.1.3.4
804 */
805 public function attach_product_with_course($post_ID, $postData){
806 $attached_product_id = tutor_utils()->get_course_product_id($post_ID);
807 $course_price = sanitize_text_field(tutor_utils()->array_get('course_price', $_POST));
808
809 if ( ! $course_price){
810 return;
811 }
812
813 $monetize_by = tutor_utils()->get_option('monetize_by');
814 $course = get_post($post_ID);
815
816 if ($monetize_by === 'wc'){
817
818 $is_update = false;
819 if ($attached_product_id){
820 $wc_product = get_post_meta($attached_product_id, '_product_version', true);
821 if ($wc_product){
822 $is_update = true;
823 }
824 }
825
826 if ($is_update){
827
828 $productObj = new \WC_Product($attached_product_id);
829 $productObj->set_price($course_price); // set product price
830 $productObj->set_regular_price($course_price); // set product regular price
831 $product_id = $productObj->save();
832
833 }else{
834
835 $productObj = new \WC_Product();
836 $productObj->set_name($course->post_title);
837 $productObj->set_status('publish');
838 $productObj->set_price($course_price); // set product price
839 $productObj->set_regular_price($course_price); // set product regular price
840
841 $product_id = $productObj->save();
842 if ($product_id) {
843 update_post_meta( $post_ID, '_tutor_course_product_id', $product_id );
844 //Mark product for woocommerce
845 update_post_meta( $product_id, '_virtual', 'yes' );
846 update_post_meta( $product_id, '_tutor_product', 'yes' );
847
848 $coursePostThumbnail = get_post_meta( $post_ID, '_thumbnail_id', true );
849 if ( $coursePostThumbnail ) {
850 set_post_thumbnail( $product_id, $coursePostThumbnail );
851 }
852 }
853 }
854
855 }elseif ($monetize_by === 'edd'){
856
857 $is_update = false;
858
859 if ($attached_product_id){
860 $edd_price = get_post_meta($attached_product_id, 'edd_price', true);
861 if ($edd_price){
862 $is_update = true;
863 }
864 }
865
866 if ($is_update){
867 //Update the product
868 update_post_meta( $attached_product_id, 'edd_price', $course_price );
869 }else{
870 //Create new product
871
872 $post_arr = array(
873 'post_type' => 'download',
874 'post_title' => $course->post_title,
875 'post_status' => 'publish',
876 'post_author' => get_current_user_id(),
877 );
878 $download_id = wp_insert_post( $post_arr );
879 if ($download_id ) {
880 //edd_price
881 update_post_meta( $download_id, 'edd_price', $course_price );
882
883 update_post_meta( $post_ID, '_tutor_course_product_id', $download_id );
884 //Mark product for EDD
885 update_post_meta( $download_id, '_tutor_product', 'yes' );
886
887 $coursePostThumbnail = get_post_meta( $post_ID, '_thumbnail_id', true );
888 if ( $coursePostThumbnail ) {
889 set_post_thumbnail( $download_id, $coursePostThumbnail );
890 }
891
892 }
893
894 }
895
896
897 }
898
899 }
900
901
902 /**
903 * Add Course level to course settings
904 * @since v.1.4.1
905 */
906 public function add_course_level_to_settings(){
907 include tutor()->path.'views/metabox/course-level-metabox.php';
908 }
909
910 /**
911 * Check if course starting
912 *
913 * @since v.1.4.8
914 */
915 public function tutor_lesson_load_before(){
916 $course_id = tutils()->get_course_id_by_content(get_the_ID());
917 $completed_lessons = tutor_utils()->get_completed_lesson_count_by_course($course_id);
918 if (is_user_logged_in()){
919 $is_course_started = get_post_meta($course_id, '_tutor_course_started', true);
920 if ( ! $completed_lessons && ! $is_course_started){
921 update_post_meta($course_id, '_tutor_course_started', tutor_time());
922 do_action('tutor/course/started', $course_id);
923 }
924 }
925 }
926
927 /**
928 * Add Course level to course settings
929 * @since v.1.4.8
930 */
931 public function course_elements_enable_disable(){
932 add_filter('tutor_course/single/completing-progress-bar', array($this, 'enable_disable_course_progress_bar') );
933 add_filter('tutor_course/single/material_includes', array($this, 'enable_disable_material_includes') );
934 add_filter('tutor_course/single/content', array($this, 'enable_disable_course_content') );
935 add_filter('tutor_course/single/benefits_html', array($this, 'enable_disable_course_benefits') );
936 add_filter('tutor_course/single/requirements_html', array($this, 'enable_disable_course_requirements') );
937 add_filter('tutor_course/single/audience_html', array($this, 'enable_disable_course_target_audience') );
938 add_filter('tutor_course/single/enrolled/nav_items', array($this, 'enable_disable_course_nav_items') );
939 }
940
941 /**
942 * Enable disable course progress bar
943 * @since v.1.4.8
944 */
945 public function enable_disable_course_progress_bar($html){
946 $disable_option = (bool) get_tutor_option('disable_course_progress_bar');
947 if($disable_option){
948 return '';
949 }
950 return $html;
951 }
952
953 /**
954 * Enable disable material includes
955 * @since v.1.4.8
956 */
957 public function enable_disable_material_includes($html){
958 $disable_option = (bool) get_tutor_option('disable_course_material');
959 if($disable_option){
960 return '';
961 }
962 return $html;
963 }
964
965 /**
966 * Enable disable course content
967 * @since v.1.4.8
968 */
969 public function enable_disable_course_content($html){
970 $disable_option = (bool) get_tutor_option('disable_course_description');
971 if($disable_option){
972 return '';
973 }
974 return $html;
975 }
976
977 /**
978 * Enable disable course benefits
979 * @since v.1.4.8
980 */
981 public function enable_disable_course_benefits($html){
982 $disable_option = (bool) get_tutor_option('disable_course_benefits');
983 if($disable_option){
984 return '';
985 }
986 return $html;
987 }
988
989 /**
990 * Enable disable course requirements
991 * @since v.1.4.8
992 */
993 public function enable_disable_course_requirements($html){
994 $disable_option = (bool) get_tutor_option('disable_course_requirements');
995 if($disable_option){
996 return '';
997 }
998 return $html;
999 }
1000
1001 /**
1002 * Enable disable course target audience
1003 * @since v.1.4.8
1004 */
1005 public function enable_disable_course_target_audience($html){
1006 $disable_option = (bool) get_tutor_option('disable_course_target_audience');
1007 if($disable_option){
1008 return '';
1009 }
1010 return $html;
1011 }
1012
1013 /**
1014 * Enable disable course nav items
1015 * @since v.1.4.8
1016 */
1017 public function enable_disable_course_nav_items($items){
1018 global $wp_query, $post;
1019 $enable_q_and_a_on_course = (bool) get_tutor_option('enable_q_and_a_on_course');
1020 $disable_course_announcements = (bool) get_tutor_option('disable_course_announcements');
1021
1022 $disable_qa_for_this_course = ($wp_query->is_single && !empty($post)) ? get_post_meta($post->ID, '_tutor_disable_qa', true) : '';
1023
1024 if(!$enable_q_and_a_on_course || $disable_qa_for_this_course == 'yes') {
1025 if(tutils()->array_get('questions', $items)) {
1026 unset($items['questions']);
1027 }
1028 }
1029 if($disable_course_announcements){
1030 if(tutils()->array_get('announcements', $items)) {
1031 unset($items['announcements']);
1032 }
1033 }
1034 return $items;
1035 }
1036
1037 /**
1038 * Filter product in shop page
1039 * @since v.1.4.9
1040 */
1041 public function filter_product_in_shop_page(){
1042 $hide_course_from_shop_page = (bool) get_tutor_option('hide_course_from_shop_page');
1043 if(!$hide_course_from_shop_page){
1044 return;
1045 }
1046 add_action('woocommerce_product_query', array($this, 'filter_woocommerce_product_query'));
1047 add_filter('edd_downloads_query', array($this, 'filter_edd_downloads_query'), 10, 2);
1048 add_action('pre_get_posts', array($this, 'filter_archive_meta_query'), 1);
1049 }
1050
1051 /**
1052 * Tutor product meta query
1053 * @since v.1.4.9
1054 */
1055 public function tutor_product_meta_query(){
1056 $meta_query = array(
1057 'key' => '_tutor_product',
1058 'compare' => 'NOT EXISTS'
1059 );
1060 return $meta_query;
1061 }
1062
1063 /**
1064 * Filter product in woocommerce shop page
1065 * @since v.1.4.9
1066 */
1067 public function filter_woocommerce_product_query($wp_query){
1068 $wp_query->set('meta_query', array($this->tutor_product_meta_query()));
1069 return $wp_query;
1070 }
1071
1072 /**
1073 * Filter product in edd downloads shortcode page
1074 * @since v.1.4.9
1075 */
1076 public function filter_edd_downloads_query($query){
1077 $query['meta_query'][] = $this->tutor_product_meta_query();
1078 return $query;
1079 }
1080
1081 /**
1082 * Filter product in edd downloads archive page
1083 * @since v.1.4.9
1084 */
1085 public function filter_archive_meta_query($wp_query){
1086 if(!is_admin() && $wp_query->is_archive && $wp_query->get('post_type') === 'download'){
1087 $wp_query->set('meta_query', array($this->tutor_product_meta_query()));
1088 }
1089 return $wp_query;
1090 }
1091
1092 /**
1093 * @param $html
1094 * @return string
1095 *
1096 * Removed course price if already enrolled at single course
1097 *
1098 * @since v.1.5.8
1099 */
1100 public function remove_price_if_enrolled($html){
1101 $should_removed = apply_filters('should_remove_price_if_enrolled', true);
1102
1103 if ($should_removed){
1104 $course_id = get_the_ID();
1105 $enrolled = tutils()->is_enrolled($course_id);
1106 if ($enrolled){
1107 $html = '';
1108 }
1109 }
1110 return $html;
1111 }
1112
1113 /**
1114 * @param $html
1115 * @return string
1116 *
1117 * Check if all lessons and quizzes done before mark course complete.
1118 */
1119 function tutor_lms_hide_course_complete_btn($html){
1120
1121 $completion_mode = tutils()->get_option('course_completion_process');
1122 if ($completion_mode !== 'strict'){
1123 return $html;
1124 }
1125
1126 $completed_lesson = tutils()->get_completed_lesson_count_by_course();
1127 $lesson_count = tutils()->get_lesson_count_by_course();
1128
1129 if ($completed_lesson < $lesson_count){
1130 return '<p class="suggestion-before-course-complete">'.__('complete all lessons to mark this course as complete', 'tutor').'</p>';
1131 }
1132
1133 $quizzes = array();
1134
1135 $course_contents = tutils()->get_course_contents_by_id();
1136 if (tutils()->count($course_contents)){
1137 foreach ($course_contents as $content){
1138 if ($content->post_type === 'tutor_quiz'){
1139 $quizzes[] = $content;
1140 }
1141 }
1142 }
1143
1144 $is_pass = true;
1145 $required_quiz_pass = 0;
1146
1147 if (tutils()->count($quizzes)){
1148 foreach ($quizzes as $quiz){
1149
1150 $attempt = tutils()->get_quiz_attempt($quiz->ID);
1151 if ($attempt) {
1152 $passing_grade = tutor_utils()->get_quiz_option($quiz->ID, 'passing_grade', 0);
1153 $earned_percentage = $attempt->earned_marks > 0 ? (number_format(($attempt->earned_marks * 100) / $attempt->total_marks)) : 0;
1154
1155 if ($earned_percentage < $passing_grade) {
1156 $required_quiz_pass++;
1157 $is_pass = false;
1158 }
1159 }else{
1160 $required_quiz_pass++;
1161 $is_pass = false;
1162 }
1163 }
1164 }
1165
1166 if ( ! $is_pass){
1167 return '<p class="suggestion-before-course-complete">'.sprintf(__('You have to pass %s quizzes to complete this course.', 'tutor'), $required_quiz_pass).'</p>';
1168 }
1169
1170 return $html;
1171 }
1172
1173 public function get_generate_greadbook($html){
1174 if ( ! tutils()->is_completed_course()){
1175 return '';
1176 }
1177 return $html;
1178 }
1179
1180 /**
1181 * Add social share content in header
1182 * @since v.1.6.3
1183 */
1184 public function social_share_content(){
1185 global $wp_query, $post;
1186 if ($wp_query->is_single && ! empty($wp_query->query_vars['post_type']) && $wp_query->query_vars['post_type'] === $this->course_post_type) { ?>
1187 <!--Facebook-->
1188 <meta property="og:type" content="website"/>
1189 <meta property="og:image" content="<?php echo get_tutor_course_thumbnail_src(); ?>" />
1190 <meta property="og:description" content="<?php echo esc_html($post->post_content); ?>" />
1191 <!--Twitter-->
1192 <meta name="twitter:image" content="<?php echo get_tutor_course_thumbnail_src(); ?>">
1193 <meta name="twitter:description" content="<?php echo esc_html($post->post_content); ?>">
1194 <!--Google+-->
1195 <meta itemprop="image" content="<?php echo get_tutor_course_thumbnail_src(); ?>">
1196 <meta itemprop="description" content="<?php echo esc_html($post->post_content); ?>"> <?php
1197 }
1198 }
1199
1200 /**
1201 * Get posts by type and parent
1202 * @since v.1.6.6
1203 */
1204 public function tutor_get_post_ids($post_type, $post_parent) {
1205 $args = array(
1206 'fields' => 'ids',
1207 'post_type' => $post_type,
1208 'post_parent' => $post_parent,
1209 'post_status' => 'any',
1210 'posts_per_page' => -1,
1211 );
1212 return get_posts($args);
1213 }
1214
1215 /**
1216 * Delete course data when permanently deleting a course.
1217 * @since v.1.6.6
1218 */
1219 function delete_tutor_course_data( $post_id ) {
1220 $course_post_type = tutor()->course_post_type;
1221 $lesson_post_type = tutor()->lesson_post_type;
1222
1223 if (get_post_type($post_id) == $course_post_type) {
1224 global $wpdb;
1225 $topic_ids = $this->tutor_get_post_ids('topics', $post_id);
1226 if ( !empty($topic_ids) ) {
1227 foreach ($topic_ids as $topic_id) {
1228 $content_post_type = apply_filters('tutor_course_contents_post_types', array($lesson_post_type, 'tutor_quiz'));
1229 $topic_content_ids = $this->tutor_get_post_ids($content_post_type, $topic_id);
1230
1231 foreach ($topic_content_ids as $content_id) {
1232 if( get_post_type($content_id) == 'tutor_quiz') {
1233 $wpdb->delete($wpdb->prefix.'tutor_quiz_attempts', array('quiz_id' => $content_id));
1234 $wpdb->delete($wpdb->prefix.'tutor_quiz_attempt_answers', array('quiz_id' => $content_id));
1235
1236 $questions_ids = $wpdb->get_col("SELECT question_id FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$content_id} ");
1237 if (is_array($questions_ids) && count($questions_ids)){
1238 $in_question_ids = "'".implode("','", $questions_ids)."'";
1239 $wpdb->query("DELETE FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id IN({$in_question_ids}) ");
1240 }
1241 $wpdb->delete($wpdb->prefix.'tutor_quiz_questions', array('quiz_id' => $content_id));
1242 }
1243 wp_delete_post($content_id, true);
1244 }
1245 wp_delete_post($topic_id, true);
1246 }
1247 }
1248 $child_post_ids = $this->tutor_get_post_ids(array('tutor_announcements', 'tutor_enrolled'), $post_id);
1249 if ( !empty($child_post_ids) ) {
1250 foreach ($child_post_ids as $child_post_id) {
1251 wp_delete_post($child_post_id, true);
1252 }
1253 }
1254 }
1255 }
1256
1257 /**
1258 * tutor course setting metabox
1259 * @since v.1.7.0
1260 */
1261 function tutor_course_setting_metabox( $post ) {
1262
1263 $disable_qa = $this->additional_meta[0];
1264 $is_public = $this->additional_meta[1];
1265
1266 $disable_qa_checked = get_post_meta($post->ID, $disable_qa, true)=='yes' ? 'checked="checked"' : '';
1267 $is_public_checked = get_post_meta($post->ID, $is_public, true)=='yes' ? 'checked="checked"' : '';
1268
1269 do_action('tutor_before_course_sidebar_settings_metabox', $post);
1270 ?>
1271 <div class="tutor-course-sidebar-settings-item" id="_tutor_is_course_public_meta_checkbox" style="display:none">
1272 <label for="<?php echo $is_public; ?>">
1273 <input id="<?php echo $is_public; ?>" type="checkbox" name="<?php echo $is_public; ?>" value="yes" <?php echo $is_public_checked; ?> />
1274 <?php _e('Make This Course Public', 'tutor'); ?>
1275 <small style="display:block;padding-left:24px">
1276 <?php _e('No enrollment required.', 'tutor'); ?>
1277 </small>
1278 </label>
1279 </div>
1280 <div class="tutor-course-sidebar-settings-item">
1281 <label for="<?php echo $disable_qa; ?>">
1282 <input type="hidden" name="_tutor_course_additional_data_edit" value="true" />
1283 <input id="<?php echo $disable_qa; ?>" type="checkbox" name="<?php echo $disable_qa; ?>" value="yes" <?php echo $disable_qa_checked; ?> />
1284 <?php _e('Disable Q&A', 'tutor'); ?>
1285 </label>
1286 </div>
1287 <?php
1288 do_action('tutor_after_course_sidebar_settings_metabox', $post);
1289 }
1290
1291 function tutor_course_setting_metabox_frontend( $post ){
1292 ?>
1293 <div class="tutor-course-builder-section tutor-course-builder-info">
1294 <div class="tutor-course-builder-section-title">
1295 <h3><i class="tutor-icon-down"></i><span><?php esc_html_e('Tutor Settings', 'tutor'); ?></span></h3>
1296 </div>
1297 <div class="tutor-course-builder-section-content">
1298 <div class="tutor-frontend-builder-item-scope">
1299 <div class="tutor-form-group">
1300 <?php $this->tutor_course_setting_metabox($post); ?>
1301 </div>
1302 </div>
1303 </div>
1304 </div>
1305 <?php
1306 }
1307 }