1: <?php
2: if ( ! defined( 'ABSPATH' ) ) exit;
3:
4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Sensei_Utils {
15: 16: 17: 18: 19: 20:
21: public static function get_placeholder_image () {
22:
23: return esc_url( apply_filters( 'sensei_placeholder_thumbnail', Sensei()->plugin_url . 'assets/images/placeholder.png' ) );
24: }
25:
26: 27: 28: 29: 30: 31: 32: 33: 34:
35: public static function sensei_is_woocommerce_present () {
36:
37: return Sensei_WC::is_woocommerce_present();
38:
39: }
40:
41: 42: 43: 44: 45: 46: 47: 48: 49:
50: public static function sensei_is_woocommerce_activated () {
51:
52: return Sensei_WC::is_woocommerce_active();
53:
54: }
55:
56: 57: 58: 59: 60: 61: 62:
63: public static function sensei_log_activity ( $args = array() ) {
64: global $wpdb;
65:
66:
67: $data = array(
68: 'comment_post_ID' => intval( $args['post_id'] ),
69: 'comment_author' => '',
70: 'comment_author_email' => '',
71: 'comment_author_url' => '',
72: 'comment_content' => !empty($args['data']) ? esc_html( $args['data'] ) : '',
73: 'comment_type' => esc_attr( $args['type'] ),
74: 'user_id' => intval( $args['user_id'] ),
75: 'comment_approved' => !empty($args['status']) ? esc_html( $args['status'] ) : 'log',
76: );
77:
78: if ( !empty($args['username']) ) {
79: $data['comment_author'] = sanitize_user( $args['username'] );
80: }
81: if ( !empty($args['user_email']) ) {
82: $data['comment_author_email'] = sanitize_email( $args['user_email'] );
83: }
84: if ( !empty($args['user_url']) ) {
85: $data['comment_author_url'] = esc_url( $args['user_url'] );
86: }
87: if ( !empty($args['parent']) ) {
88: $data['comment_parent'] = $args['parent'];
89: }
90:
91: if ( empty($args['user_id']) ) {
92: _deprecated_argument( __FUNCTION__, '1.0', __('At no point should user_id be equal to 0.', 'woothemes-sensei') );
93: return false;
94: }
95:
96: do_action( 'sensei_log_activity_before', $args, $data );
97:
98: $flush_cache = false;
99:
100:
101:
102: $comment_id = $wpdb->get_var( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND user_id = %d AND comment_type = %s ", $args['post_id'], $args['user_id'], $args['type'] ) );
103: if ( ! $comment_id ) {
104:
105: $comment_id = wp_insert_comment( $data );
106:
107: $flush_cache = true;
108: } elseif ( isset( $args['action'] ) && 'update' == $args['action'] ) {
109:
110: $data['comment_ID'] = $comment_id;
111:
112: if ( empty($args['keep_time']) ) {
113: $data['comment_date'] = current_time('mysql');
114: }
115: wp_update_comment( $data );
116: $flush_cache = true;
117: }
118:
119:
120: if ( $flush_cache ) {
121: wp_cache_flush();
122: }
123:
124: do_action( 'sensei_log_activity_after', $args, $data, $comment_id );
125:
126: if ( 0 < $comment_id ) {
127:
128: return $comment_id;
129: } else {
130: return false;
131: }
132: }
133:
134:
135: 136: 137: 138: 139: 140: 141: 142:
143: public static function sensei_check_for_activity ( $args = array(), $return_comments = false ) {
144:
145: global $wp_version;
146: if ( !$return_comments ) {
147: $args['count'] = true;
148: }
149:
150:
151: if ( isset( $args['count'] ) || isset( $args['post_id'] ) ){
152:
153:
154: if ( version_compare( $wp_version, '4.1', '>=' ) ) {
155: $args['order'] = false;
156: $args['orderby'] = false;
157: }
158: }
159:
160:
161: if ( isset( $args['user_id'] ) && 0 == intval ( $args['user_id'] ) ) {
162: _deprecated_argument( __FUNCTION__, '1.0', __('At no point should user_id be equal to 0.', 'woothemes-sensei') );
163: return false;
164: }
165:
166: if ( isset($args['type']) && in_array($args['type'], array('sensei_course_start', 'sensei_course_end', 'sensei_lesson_start', 'sensei_lesson_end', 'sensei_quiz_asked', 'sensei_user_grade', 'sensei_quiz_grade', 'sense_answer_notes') ) ) {
167: _deprecated_argument( __FUNCTION__, '1.7', sprintf( __('Sensei activity type %s is no longer used.', 'woothemes-sensei'), $args['type'] ) );
168: return false;
169: }
170:
171: if ( isset($args['status']) ) {
172:
173: if ( is_array( $args['status'] ) && version_compare($wp_version, '4.1', '<') ) {
174:
175: $args['status'] = implode( ",", $args['status'] );
176:
177: add_filter( 'comments_clauses', array( __CLASS__, 'comment_multiple_status_filter' ) );
178: }
179: }
180: else {
181: $args['status'] = 'any';
182: }
183:
184:
185: if ( ( is_array( $args['status'] ) || 'any' == $args['status'] ) && version_compare($wp_version, '4.1', '<') ) {
186: add_filter( 'comments_clauses', array( __CLASS__, 'comment_any_status_filter' ) );
187: }
188:
189:
190: 191: 192: 193: 194: 195: 196:
197: $comments = apply_filters('sensei_check_for_activity', get_comments( $args ) );
198:
199: remove_filter( 'comments_clauses', array( __CLASS__, 'comment_multiple_status_filter' ) );
200: remove_filter( 'comments_clauses', array( __CLASS__, 'comment_any_status_filter' ) );
201:
202: if ( $return_comments ) {
203:
204: if ( is_array($comments) && 1 == count($comments) ) {
205: $comments = array_shift($comments);
206: }
207:
208: return $comments;
209: }
210:
211: return intval($comments);
212: }
213:
214:
215: 216: 217: 218: 219: 220: 221:
222: public static function sensei_activity_ids ( $args = array() ) {
223:
224:
225: $comments = Sensei_Utils::sensei_check_for_activity( $args, true );
226:
227: if ( !is_array($comments) ) {
228: $comments = array( $comments );
229: }
230:
231: $post_ids = array();
232:
233: if ( is_array( $comments ) && ( 0 < intval( count( $comments ) ) ) ) {
234: foreach ( $comments as $key => $value ) {
235:
236: if ( isset( $args['field'] ) && 'comment' == $args['field'] ) {
237: array_push( $post_ids, $value->comment_ID );
238: } elseif( isset( $args['field'] ) && 'user_id' == $args['field'] ) {
239: array_push( $post_ids, $value->user_id );
240: } else {
241: array_push( $post_ids, $value->comment_post_ID );
242: }
243: }
244:
245: $post_ids = array_unique( $post_ids );
246: $post_ids = array_values( $post_ids );
247: }
248:
249: return $post_ids;
250: }
251:
252:
253: 254: 255: 256: 257: 258: 259:
260: public static function sensei_delete_activities ( $args = array() ) {
261:
262: $dataset_changes = false;
263:
264:
265: $comments = Sensei_Utils::sensei_check_for_activity( array( 'post_id' => intval( $args['post_id'] ), 'user_id' => intval( $args['user_id'] ), 'type' => esc_attr( $args['type'] ) ), true );
266: if( $comments ) {
267:
268: if ( !is_array( $comments ) ) {
269: $comments = array( $comments );
270: }
271: foreach ( $comments as $key => $value ) {
272: if ( isset( $value->comment_ID ) && 0 < $value->comment_ID ) {
273: $dataset_changes = wp_delete_comment( intval( $value->comment_ID ), true );
274: }
275: }
276:
277: wp_cache_flush();
278: }
279: return $dataset_changes;
280: }
281:
282: 283: 284: 285: 286: 287: 288:
289: public static function delete_all_user_activity( $user_id = 0 ) {
290:
291: $dataset_changes = false;
292:
293: if( $user_id ) {
294:
295: $activities = Sensei_Utils::sensei_check_for_activity( array( 'user_id' => $user_id ), true );
296:
297: if( $activities ) {
298:
299:
300: if ( ! is_array( $activities ) ) {
301: $activities = array( $activities );
302: }
303:
304: foreach( $activities as $activity ) {
305: if( '' == $activity->comment_type ) continue;
306: if( strpos( 'sensei_', $activity->comment_type ) != 0 ) continue;
307: $dataset_changes = wp_delete_comment( intval( $activity->comment_ID ), true );
308: wp_cache_flush();
309: }
310: }
311: }
312:
313: return $dataset_changes;
314: }
315:
316:
317: 318: 319: 320: 321: 322: 323:
324: public static function sensei_get_activity_value ( $args = array() ) {
325:
326: $activity_value = false;
327: if ( !empty($args['field']) ) {
328: $comment = Sensei_Utils::sensei_check_for_activity( $args, true );
329:
330: if ( isset( $comment->{$args['field']} ) && '' != $comment->{$args['field']} ) {
331: $activity_value = $comment->{$args['field']};
332: }
333: }
334: return $activity_value;
335: }
336:
337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347:
348: public static function sensei_customer_bought_product ( $customer_email, $user_id, $product_id ) {
349:
350: $emails = array();
351:
352: if ( $user_id ) {
353: $user = get_user_by( 'id', intval( $user_id ) );
354: $emails[] = $user->user_email;
355: }
356:
357: if ( is_email( $customer_email ) )
358: $emails[] = $customer_email;
359:
360: if ( sizeof( $emails ) == 0 )
361: return false;
362:
363: return Sensei_WC::has_customer_bought_product( $user_id, $product_id );
364:
365: }
366:
367: 368: 369: 370: 371: 372: 373:
374: public static function sensei_text_editor( $content = '', $editor_id = 'senseitexteditor', $input_name = '' ) {
375:
376: if( ! $input_name ) $input_name = $editor_id;
377:
378: $buttons = 'bold,italic,underline,strikethrough,blockquote,bullist,numlist,justifyleft,justifycenter,justifyright,undo,redo,pastetext';
379:
380: $settings = array(
381: 'media_buttons' => false,
382: 'wpautop' => true,
383: 'textarea_name' => $input_name,
384: 'editor_class' => 'sensei_text_editor',
385: 'teeny' => false,
386: 'dfw' => false,
387: 'tinymce' => array(
388: 'theme_advanced_buttons1' => $buttons,
389: 'theme_advanced_buttons2' => ''
390: ),
391: 'quicktags' => false
392: );
393:
394: wp_editor( $content, $editor_id, $settings );
395:
396: }
397:
398: 399: 400: 401: 402: 403: 404: 405:
406: public static function sensei_save_quiz_answers( $submitted = array(), $user_id = 0 ) {
407:
408: if( intval( $user_id ) == 0 ) {
409: $user_id = get_current_user_id();
410: }
411:
412: $answers_saved = false;
413:
414: if( $submitted && intval( $user_id ) > 0 ) {
415:
416: foreach( $submitted as $question_id => $answer ) {
417:
418:
419: $question_type = Sensei()->question->get_question_type( $question_id );
420:
421:
422: if( 0 == get_magic_quotes_gpc() ) {
423: $answer = wp_unslash( $answer );
424: }
425: switch( $question_type ) {
426: case 'multi-line': $answer = nl2br( $answer ); break;
427: case 'single-line': break;
428: case 'gap-fill': break;
429: default: $answer = maybe_serialize( $answer ); break;
430: }
431: $args = array(
432: 'post_id' => $question_id,
433: 'data' => base64_encode( $answer ),
434: 'type' => 'sensei_user_answer',
435: 'user_id' => $user_id,
436: 'action' => 'update'
437: );
438: $answers_saved = Sensei_Utils::sensei_log_activity( $args );
439: }
440:
441:
442: if( isset( $_FILES ) ) {
443: foreach( $_FILES as $field => $file ) {
444: if( strpos( $field, 'file_upload_' ) !== false ) {
445: $question_id = str_replace( 'file_upload_', '', $field );
446: if( $file && $question_id ) {
447: $attachment_id = self::upload_file( $file );
448: if( $attachment_id ) {
449: $args = array(
450: 'post_id' => $question_id,
451: 'data' => base64_encode( $attachment_id ),
452: 'type' => 'sensei_user_answer',
453: 'user_id' => $user_id,
454: 'action' => 'update'
455: );
456: $answers_saved = Sensei_Utils::sensei_log_activity( $args );
457: }
458: }
459: }
460: }
461: }
462: }
463:
464: return $answers_saved;
465:
466: }
467:
468: public static function upload_file( $file = array() ) {
469:
470: require_once( ABSPATH . 'wp-admin/includes/admin.php' );
471:
472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484:
485: $file_upload_args = apply_filters( 'sensei_file_upload_args', array('test_form' => false ) );
486:
487: $file_return = wp_handle_upload( $file, $file_upload_args );
488:
489: if( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) {
490: return false;
491: } else {
492:
493: $filename = $file_return['file'];
494:
495: $attachment = array(
496: 'post_mime_type' => $file_return['type'],
497: 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
498: 'post_content' => '',
499: 'post_status' => 'inherit',
500: 'guid' => $file_return['url']
501: );
502:
503: $attachment_id = wp_insert_attachment( $attachment, $filename );
504:
505: require_once(ABSPATH . 'wp-admin/includes/image.php');
506: $attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
507: wp_update_attachment_metadata( $attachment_id, $attachment_data );
508:
509: if( 0 < intval( $attachment_id ) ) {
510: return $attachment_id;
511: }
512: }
513:
514: return false;
515: }
516:
517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534:
535: public static function sensei_grade_quiz_auto( $quiz_id = 0, $submitted = array(), $total_questions = 0, $quiz_grade_type = 'auto' ) {
536:
537: return Sensei_Grading::grade_quiz_auto( $quiz_id, $submitted, $total_questions, $quiz_grade_type );
538:
539: }
540:
541: 542: 543: 544: 545: 546: 547: 548:
549: public static function sensei_grade_quiz( $quiz_id = 0, $grade = 0, $user_id = 0, $quiz_grade_type = 'auto' ) {
550: if( intval( $user_id ) == 0 ) {
551: $user_id = get_current_user_id();
552: }
553:
554: $activity_logged = false;
555: if( intval( $quiz_id ) > 0 && intval( $user_id ) > 0 ) {
556: $lesson_id = get_post_meta( $quiz_id, '_quiz_lesson', true );
557: $user_lesson_status = Sensei_Utils::user_lesson_status( $lesson_id, $user_id );
558: $activity_logged = update_comment_meta( $user_lesson_status->comment_ID, 'grade', $grade );
559:
560: $quiz_passmark = absint( get_post_meta( $quiz_id, '_quiz_passmark', true ) );
561:
562: do_action( 'sensei_user_quiz_grade', $user_id, $quiz_id, $grade, $quiz_passmark, $quiz_grade_type );
563: }
564:
565: return $activity_logged;
566: }
567:
568: 569: 570: 571: 572: 573: 574: 575: 576: 577: 578: 579: 580: 581:
582: public static function sensei_grade_question_auto( $question_id = 0, $question_type = '', $answer = '', $user_id = 0 ) {
583:
584: return WooThemes_Sensei_Grading::grade_question_auto( $question_id, $question_type, $answer, $user_id );
585:
586: }
587:
588: 589: 590: 591: 592: 593: 594:
595: public static function sensei_grade_question( $question_id = 0, $grade = 0, $user_id = 0 ) {
596: if( intval( $user_id ) == 0 ) {
597: $user_id = get_current_user_id();
598: }
599:
600: $activity_logged = false;
601: if( intval( $question_id ) > 0 && intval( $user_id ) > 0 ) {
602:
603: $user_answer_id = Sensei_Utils::sensei_get_activity_value( array( 'post_id' => $question_id, 'user_id' => $user_id, 'type' => 'sensei_user_answer', 'field' => 'comment_ID' ) );
604: $activity_logged = update_comment_meta( $user_answer_id, 'user_grade', $grade );
605:
606: $answer_notes = get_post_meta( $question_id, '_answer_feedback', true );
607: if ( !empty($answer_notes) ) {
608: update_comment_meta( $user_answer_id, 'answer_note', base64_encode( $answer_notes ) );
609: }
610:
611: }
612:
613: return $activity_logged;
614: }
615:
616: public static function sensei_delete_question_grade( $question_id = 0, $user_id = 0 ) {
617: if( intval( $user_id ) == 0 ) {
618: $user_id = get_current_user_id();
619: }
620:
621: $activity_logged = false;
622: if( intval( $question_id ) > 0 ) {
623: $user_answer_id = Sensei_Utils::sensei_get_activity_value( array( 'post_id' => $question_id, 'user_id' => $user_id, 'type' => 'sensei_user_answer', 'field' => 'comment_ID' ) );
624: $activity_logged = delete_comment_meta( $user_answer_id, 'user_grade' );
625: }
626:
627: return $activity_logged;
628: }
629:
630:
631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641:
642: public static function user_start_lesson( $user_id = 0, $lesson_id = 0, $complete = false ) {
643:
644: return self::sensei_start_lesson( $lesson_id, $user_id, $complete );
645:
646: }
647:
648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659: 660:
661: public static function sensei_start_lesson( $lesson_id = 0, $user_id = 0, $complete = false ) {
662:
663:
664: if( intval( $user_id ) == 0 ) {
665: $user_id = get_current_user_id();
666: }
667:
668: $activity_logged = false;
669:
670: if( intval( $lesson_id ) > 0 ) {
671:
672: $course_id = get_post_meta( $lesson_id, '_lesson_course', true );
673: if( $course_id ) {
674: $is_user_taking_course = Sensei_Utils::user_started_course( $course_id, $user_id );
675: if( ! $is_user_taking_course ) {
676: Sensei_Utils::user_start_course( $user_id, $course_id );
677: }
678: }
679:
680: $metadata = array();
681: $status = 'in-progress';
682:
683:
684: do_action( 'sensei_user_lesson_start', $user_id, $lesson_id );
685:
686: if( $complete ) {
687:
688: $has_questions = get_post_meta( $lesson_id, '_quiz_has_questions', true );
689: if ( $has_questions ) {
690: $status = 'passed';
691: $metadata['grade'] = 0;
692: }
693: else {
694: $status = 'complete';
695: }
696: }
697:
698:
699: $activity_logged = Sensei_Utils::user_started_lesson( $lesson_id, $user_id );
700: if( ! $activity_logged ) {
701:
702: $metadata['start'] = current_time('mysql');
703: $activity_logged = Sensei_Utils::update_lesson_status( $user_id, $lesson_id, $status, $metadata );
704:
705: } else {
706:
707:
708: $current_user_activity = get_comment($activity_logged);
709: if( $status=='complete' &&
710: $status != $current_user_activity->comment_approved ){
711:
712: $comment = array();
713: $comment['comment_ID'] = $activity_logged;
714: $comment['comment_approved'] = $status;
715: wp_update_comment( $comment );
716:
717: }
718:
719: }
720:
721: if ( $complete ) {
722:
723: do_action( 'sensei_user_lesson_end', $user_id, $lesson_id );
724: }
725:
726: }
727:
728: return $activity_logged;
729: }
730:
731: 732: 733: 734: 735: 736: 737:
738: public static function sensei_remove_user_from_lesson( $lesson_id = 0, $user_id = 0, $from_course = false ) {
739:
740: if( ! $lesson_id ) return false;
741:
742: if( intval( $user_id ) == 0 ) {
743: $user_id = get_current_user_id();
744: }
745:
746:
747: $lesson_quiz_id = Sensei()->lesson->lesson_quizzes( $lesson_id );
748:
749:
750: Sensei_Utils::sensei_delete_quiz_answers( $lesson_quiz_id, $user_id );
751:
752:
753:
754: Sensei()->quiz->reset_user_lesson_data( $lesson_id, $user_id );
755:
756:
757: $args = array(
758: 'post_id' => $lesson_id,
759: 'type' => 'sensei_lesson_status',
760: 'user_id' => $user_id,
761: );
762:
763: Sensei_Utils::sensei_delete_activities( $args );
764:
765: if( ! $from_course ) {
766: do_action( 'sensei_user_lesson_reset', $user_id, $lesson_id );
767: }
768:
769: return true;
770: }
771:
772: 773: 774: 775: 776: 777: 778:
779: public static function sensei_remove_user_from_course( $course_id = 0, $user_id = 0 ) {
780:
781:
782: if( ! $course_id ) return false;
783:
784: if( intval( $user_id ) == 0 ) {
785: $user_id = get_current_user_id();
786: }
787:
788: $lesson_ids = Sensei()->course->course_lessons( $course_id, 'any', 'ids' );
789:
790: foreach( $lesson_ids as $lesson_id ) {
791: Sensei_Utils::sensei_remove_user_from_lesson( $lesson_id, $user_id, true );
792: }
793:
794:
795: $args = array(
796: 'post_id' => $course_id,
797: 'type' => 'sensei_course_status',
798: 'user_id' => $user_id,
799: );
800:
801: Sensei_Utils::sensei_delete_activities( $args );
802:
803: do_action( 'sensei_user_course_reset', $user_id, $course_id );
804:
805: return true;
806: }
807:
808: public static function sensei_get_quiz_questions( $quiz_id = 0 ) {
809:
810:
811: $questions = array();
812:
813: if( intval( $quiz_id ) > 0 ) {
814: $questions = Sensei()->lesson->lesson_quiz_questions( $quiz_id );
815: $questions = Sensei_Utils::array_sort_reorder( $questions );
816: }
817:
818: return $questions;
819: }
820:
821: public static function sensei_get_quiz_total( $quiz_id = 0 ) {
822:
823:
824: $quiz_total = 0;
825:
826: if( $quiz_id > 0 ) {
827: $questions = Sensei_Utils::sensei_get_quiz_questions( $quiz_id );
828: $question_grade = 0;
829: foreach( $questions as $question ) {
830: $question_grade = Sensei()->question->get_question_grade( $question->ID );
831: $quiz_total += $question_grade;
832: }
833: }
834:
835: return $quiz_total;
836: }
837:
838: 839: 840: 841: 842: 843: 844:
845: public static function sensei_get_user_question_grade( $question = 0, $user_id = 0 ) {
846: $question_grade = false;
847: if( $question ) {
848: if ( is_object( $question ) ) {
849: $user_answer_id = $question->comment_ID;
850: }
851: else {
852: if( intval( $user_id ) == 0 ) {
853: $user_id = get_current_user_id();
854: }
855: $user_answer_id = Sensei_Utils::sensei_get_activity_value( array( 'post_id' => intval($question), 'user_id' => $user_id, 'type' => 'sensei_user_answer', 'field' => 'comment_ID' ) );
856: }
857: if ( $user_answer_id ) {
858: $question_grade = get_comment_meta( $user_answer_id, 'user_grade', true );
859: }
860: }
861:
862: return $question_grade;
863: }
864:
865: 866: 867: 868: 869: 870: 871: 872:
873: public static function sensei_get_user_question_answer_notes( $question = 0, $user_id = 0 ) {
874: $answer_notes = false;
875: if( $question ) {
876: if ( is_object( $question ) ) {
877: $user_answer_id = $question->comment_ID;
878: }
879: else {
880: if( intval( $user_id ) == 0 ) {
881: $user_id = get_current_user_id();
882: }
883: $user_answer_id = Sensei_Utils::sensei_get_activity_value( array( 'post_id' => intval($question), 'user_id' => $user_id, 'type' => 'sensei_user_answer', 'field' => 'comment_ID' ) );
884: }
885: if ( $user_answer_id ) {
886: $answer_notes = base64_decode( get_comment_meta( $user_answer_id, 'answer_note', true ) );
887: }
888: }
889:
890: return $answer_notes;
891: }
892:
893: public static function sensei_delete_quiz_answers( $quiz_id = 0, $user_id = 0 ) {
894: if( intval( $user_id ) == 0 ) {
895: $user_id = get_current_user_id();
896: }
897:
898: $delete_answers = false;
899: if( intval( $quiz_id ) > 0 ) {
900: $questions = Sensei_Utils::sensei_get_quiz_questions( $quiz_id );
901: foreach( $questions as $question ) {
902: $delete_answers = Sensei_Utils::sensei_delete_activities( array( 'post_id' => $question->ID, 'user_id' => $user_id, 'type' => 'sensei_user_answer' ) );
903: }
904: }
905:
906: return $delete_answers;
907: }
908:
909: public static function sensei_delete_quiz_grade( $quiz_id = 0, $user_id = 0 ) {
910: if( intval( $user_id ) == 0 ) {
911: $user_id = get_current_user_id();
912: }
913:
914: $delete_grade = false;
915: if( intval( $quiz_id ) > 0 ) {
916: $lesson_id = get_post_meta( $quiz_id, '_quiz_lesson', true );
917: $user_lesson_status = Sensei_Utils::user_lesson_status( $lesson_id, $user_id );
918: $delete_grade = delete_comment_meta( $user_lesson_status->comment_ID, 'grade' );
919: }
920:
921: return $delete_grade;
922: }
923:
924: 925: 926: 927: 928: 929: 930:
931: public static function sensei_add_answer_notes( $question_id = 0, $user_id = 0, $notes = '' ) {
932: if( intval( $user_id ) == 0 ) {
933: $user_id = get_current_user_id();
934: }
935:
936: $activity_logged = false;
937:
938: if( intval( $question_id ) > 0 ) {
939: $notes = base64_encode( $notes );
940:
941:
942: if ( !empty($notes) ) {
943: $user_lesson_id = Sensei_Utils::sensei_get_activity_value( array( 'post_id' => $question_id, 'user_id' => $user_id, 'type' => 'sensei_user_answer', 'field' => 'comment_ID' ) );
944: $activity_logged = update_comment_meta( $user_lesson_id, 'answer_note', $notes );
945: }
946: else {
947: $activity_logged = true;
948: }
949: }
950:
951: return $activity_logged;
952: }
953:
954: 955: 956: 957: 958: 959:
960: public static function array_sort_reorder( $return_array ) {
961: if ( isset( $_GET['orderby'] ) && '' != esc_html( $_GET['orderby'] ) ) {
962: $sort_key = '';
963:
964:
965:
966: if ( '' != $sort_key ) {
967: Sensei_Utils::sort_array_by_key($return_array,$sort_key);
968: if ( isset( $_GET['order'] ) && 'desc' == esc_html( $_GET['order'] ) ) {
969: $return_array = array_reverse( $return_array, true );
970: }
971: }
972: return $return_array;
973: } else {
974: return $return_array;
975: }
976: }
977:
978: 979: 980: 981: 982: 983: 984:
985: public static function sort_array_by_key( $array, $key ) {
986: $sorter = array();
987: $ret = array();
988: reset( $array );
989: foreach ( $array as $ii => $va ) {
990: $sorter[$ii] = $va[$key];
991: }
992: asort( $sorter );
993: foreach ( $sorter as $ii => $va ) {
994: $ret[$ii] = $array[$ii];
995: }
996: $array = $ret;
997: }
998:
999: 1000: 1001: 1002: 1003: 1004:
1005: public static function lesson_quiz_questions( $quiz_id = 0 ) {
1006: $questions_array = array();
1007: if ( 0 < $quiz_id ) {
1008: $question_args = array( 'post_type' => 'question',
1009: 'posts_per_page' => -1,
1010: 'orderby' => 'ID',
1011: 'order' => 'ASC',
1012: 'meta_query' => array(
1013: array(
1014: 'key' => '_quiz_id',
1015: 'value' => $quiz_id,
1016: )
1017: ),
1018: 'post_status' => 'any',
1019: 'suppress_filters' => 0
1020: );
1021: $questions_array = get_posts( $question_args );
1022: }
1023: return $questions_array;
1024: }
1025:
1026: 1027: 1028: 1029: 1030:
1031: public static function sensei_course_pass_grade( $course_id = 0 ) {
1032:
1033:
1034: $course_passmark = 0;
1035:
1036: if( $course_id > 0 ) {
1037: $lessons = Sensei()->course->course_lessons( $course_id );
1038: $lesson_count = 0;
1039: $total_passmark = 0;
1040: foreach( $lessons as $lesson ) {
1041:
1042:
1043: $quiz_id = Sensei()->lesson->lesson_quizzes( $lesson->ID );
1044:
1045:
1046: $pass_required = get_post_meta( $quiz_id, '_pass_required', true );
1047: if ( $pass_required ) {
1048:
1049: $quiz_passmark = absint( get_post_meta( $quiz_id, '_quiz_passmark', true ) );
1050:
1051:
1052: $total_passmark += $quiz_passmark;
1053:
1054: ++$lesson_count;
1055: }
1056: }
1057:
1058: if ( $lesson_count ) {
1059: $course_passmark = ( $total_passmark / $lesson_count );
1060: }
1061: }
1062:
1063: return Sensei_Utils::round( $course_passmark );
1064: }
1065:
1066: 1067: 1068: 1069: 1070: 1071:
1072: public static function sensei_course_user_grade( $course_id = 0, $user_id = 0 ) {
1073:
1074:
1075: if( intval( $user_id ) == 0 ) {
1076: $user_id = get_current_user_id();
1077: }
1078:
1079: $total_grade = 0;
1080:
1081: if( $course_id > 0 && $user_id > 0 ) {
1082: $lessons = Sensei()->course->course_lessons( $course_id );
1083: $lesson_count = 0;
1084: $total_grade = 0;
1085: foreach( $lessons as $lesson ) {
1086:
1087:
1088: $has_questions = get_post_meta( $lesson->ID, '_quiz_has_questions', true );
1089: if ( $has_questions ) {
1090: $user_lesson_status = Sensei_Utils::user_lesson_status( $lesson->ID, $user_id );
1091:
1092: if( empty( $user_lesson_status ) ){
1093: continue;
1094: }
1095:
1096: $quiz_grade = get_comment_meta( $user_lesson_status->comment_ID, 'grade', true );
1097:
1098:
1099: $total_grade += $quiz_grade;
1100:
1101: ++$lesson_count;
1102: }
1103: }
1104:
1105:
1106: if ( $lesson_count ) {
1107: $total_grade = ( $total_grade / $lesson_count );
1108: }
1109:
1110: }
1111:
1112: return Sensei_Utils::round( $total_grade );
1113: }
1114:
1115: 1116: 1117: 1118: 1119: 1120:
1121: public static function sensei_user_passed_course( $course_id = 0, $user_id = 0 ) {
1122: if( intval( $user_id ) == 0 ) {
1123: $user_id = get_current_user_id();
1124: }
1125:
1126: $pass = false;
1127:
1128: if( $course_id > 0 && $user_id > 0 ) {
1129: $passmark = Sensei_Utils::sensei_course_pass_grade( $course_id );
1130: $user_grade = Sensei_Utils::sensei_course_user_grade( $course_id, $user_id );
1131:
1132: if( $user_grade >= $passmark ) {
1133: $pass = true;
1134: }
1135: }
1136:
1137: return $pass;
1138:
1139: }
1140:
1141: 1142: 1143: 1144: 1145:
1146: public static function sensei_user_course_status_message( $course_id = 0, $user_id = 0 ) {
1147: if( intval( $user_id ) == 0 ) {
1148: $user_id = get_current_user_id();
1149: }
1150:
1151: $status = 'not_started';
1152: $box_class = 'info';
1153: $message = __( 'You have not started this course yet.', 'woothemes-sensei' );
1154:
1155: if( $course_id > 0 && $user_id > 0 ) {
1156:
1157: $started_course = Sensei_Utils::user_started_course( $course_id, $user_id );
1158:
1159: if( $started_course ) {
1160: $passmark = Sensei_Utils::sensei_course_pass_grade( $course_id );
1161: $user_grade = Sensei_Utils::sensei_course_user_grade( $course_id, $user_id );
1162: if( $user_grade >= $passmark ) {
1163: $status = 'passed';
1164: $box_class = 'tick';
1165: $message = sprintf( __( 'You have passed this course with a grade of %1$d%%.', 'woothemes-sensei' ), $user_grade );
1166: } else {
1167: $status = 'failed';
1168: $box_class = 'alert';
1169: $message = sprintf( __( 'You require %1$d%% to pass this course. Your grade is %2$s%%.', 'woothemes-sensei' ), $passmark, $user_grade );
1170: }
1171: }
1172:
1173: }
1174:
1175: $message = apply_filters( 'sensei_user_course_status_' . $status, $message );
1176: Sensei()->notices->add_notice( $message, $box_class );
1177: }
1178:
1179: 1180: 1181: 1182: 1183: 1184: 1185:
1186: public static function sensei_user_quiz_status_message( $lesson_id = 0, $user_id = 0, $is_lesson = false ) {
1187: global $current_user;
1188: if( intval( $user_id ) == 0 ) {
1189: $user_id = $current_user->ID;
1190: }
1191:
1192: $status = 'not_started';
1193: $box_class = 'info';
1194: $message = __( "You have not taken this lesson's quiz yet", 'woothemes-sensei' );
1195: $extra = '';
1196:
1197: if( $lesson_id > 0 && $user_id > 0 ) {
1198:
1199:
1200: $prerequisite = get_post_meta( $lesson_id, '_lesson_prerequisite', true );
1201:
1202:
1203: $course_id = absint( get_post_meta( $lesson_id, '_lesson_course', true ) );
1204:
1205:
1206: $started_course = Sensei_Utils::user_started_course( $course_id, $user_id );
1207:
1208:
1209: $user_lesson_status = Sensei_Utils::user_lesson_status( $lesson_id, $user_id );
1210: $lesson_complete = Sensei_Utils::user_completed_lesson( $user_lesson_status );
1211:
1212:
1213: $quiz_id = Sensei()->lesson->lesson_quizzes( $lesson_id );
1214:
1215:
1216: $quiz_grade = 0;
1217: if ( $user_lesson_status ) {
1218: $quiz_grade = get_comment_meta( $user_lesson_status->comment_ID, 'grade', true );
1219: }
1220:
1221:
1222: $quiz_passmark = absint( get_post_meta( $quiz_id, '_quiz_passmark', true ) );
1223: $quiz_passmark_float = (float) $quiz_passmark;
1224:
1225:
1226: $pass_required = get_post_meta( $quiz_id, '_pass_required', true );
1227:
1228:
1229: $has_quiz_questions = get_post_meta( $lesson_id, '_quiz_has_questions', true );
1230:
1231: if ( ! $started_course ) {
1232:
1233: $status = 'not_started_course';
1234: $box_class = 'info';
1235: $message = sprintf( __( 'Please sign up for %1$sthe course%2$s before taking this quiz', 'woothemes-sensei' ), '<a href="' . esc_url( get_permalink( $course_id ) ) . '" title="' . esc_attr( __( 'Sign Up', 'woothemes-sensei' ) ) . '">', '</a>' );
1236:
1237: } elseif ( ! is_user_logged_in() ) {
1238:
1239: $status = 'login_required';
1240: $box_class = 'info';
1241: $message = __( 'You must be logged in to take this quiz', 'woothemes-sensei' );
1242:
1243: }
1244:
1245: elseif ( $lesson_complete ) {
1246:
1247: $status = 'passed';
1248: $box_class = 'tick';
1249:
1250: if ( ! $has_quiz_questions ) {
1251: $message = sprintf( __( 'Congratulations! You have passed this lesson.', 'woothemes-sensei' ) );
1252: }
1253:
1254: elseif ( empty( $quiz_grade ) ) {
1255: $message = sprintf( __( 'Congratulations! You have completed this lesson.', 'woothemes-sensei' ) );
1256: }
1257:
1258: elseif ( ! empty( $quiz_grade ) && abs( $quiz_grade ) >= 0 ) {
1259: if( $is_lesson ) {
1260: $message = sprintf( __( 'Congratulations! You have passed this lesson\'s quiz achieving %s%%', 'woothemes-sensei' ), Sensei_Utils::round( $quiz_grade ) );
1261: } else {
1262: $message = sprintf( __( 'Congratulations! You have passed this quiz achieving %s%%', 'woothemes-sensei' ), Sensei_Utils::round( $quiz_grade ) );
1263: }
1264: }
1265:
1266:
1267: $nav_id_array = sensei_get_prev_next_lessons( $lesson_id );
1268: $next_lesson_id = absint( $nav_id_array['next_lesson'] );
1269:
1270:
1271: if ( ( 0 < $next_lesson_id ) ) {
1272: $message .= ' ' . '<a class="next-lesson" href="' . esc_url( get_permalink( $next_lesson_id ) )
1273: . '" rel="next"><span class="meta-nav"></span>'. __( 'Next Lesson' ,'woothemes-sensei')
1274: .'</a>';
1275:
1276: }
1277:
1278: } else {
1279:
1280:
1281: if ( isset( $user_lesson_status->comment_approved ) && 'ungraded' == $user_lesson_status->comment_approved ) {
1282: $status = 'complete';
1283: $box_class = 'info';
1284: if( $is_lesson ) {
1285: $message = sprintf( __( 'You have completed this lesson\'s quiz and it will be graded soon. %1$sView the lesson quiz%2$s', 'woothemes-sensei' ), '<a href="' . esc_url( get_permalink( $quiz_id ) ) . '" title="' . esc_attr( get_the_title( $quiz_id ) ) . '">', '</a>' );
1286: } else {
1287: $message = sprintf( __( 'You have completed this quiz and it will be graded soon. You require %1$s%% to pass.', 'woothemes-sensei' ), Sensei_Utils::round( $quiz_passmark ) );
1288: }
1289: }
1290:
1291: elseif ( isset( $user_lesson_status->comment_approved ) && 'failed' == $user_lesson_status->comment_approved ) {
1292: $status = 'failed';
1293: $box_class = 'alert';
1294: if( $is_lesson ) {
1295: $message = sprintf( __( 'You require %1$d%% to pass this lesson\'s quiz. Your grade is %2$s%%', 'woothemes-sensei' ), Sensei_Utils::round( $quiz_passmark ), Sensei_Utils::round( $quiz_grade ) );
1296: } else {
1297: $message = sprintf( __( 'You require %1$d%% to pass this quiz. Your grade is %2$s%%', 'woothemes-sensei' ), Sensei_Utils::round( $quiz_passmark ), Sensei_Utils::round( $quiz_grade ) );
1298: }
1299: }
1300:
1301: elseif ( $pass_required ) {
1302: $status = 'not_started';
1303: $box_class = 'info';
1304:
1305: if( ! Sensei_Lesson::is_prerequisite_complete( $lesson_id, get_current_user_id() ) ) {
1306: $message = '';
1307: } else if( $is_lesson ) {
1308: $message = sprintf( __( 'You require %1$d%% to pass this lesson\'s quiz.', 'woothemes-sensei' ), Sensei_Utils::round( $quiz_passmark ) );
1309: } else {
1310: $message = sprintf( __( 'You require %1$d%% to pass this quiz.', 'woothemes-sensei' ), Sensei_Utils::round( $quiz_passmark ) );
1311: }
1312: }
1313: }
1314:
1315: }else{
1316:
1317: $course_id = Sensei()->lesson->get_course_id( $lesson_id );
1318: $a_element = '<a href="' . esc_url( get_permalink( $course_id ) ) . '" title="' . __( 'Sign Up', 'woothemes-sensei' ) . '">';
1319: $a_element .= __( 'course', 'woothemes-sensei' );
1320: $a_element .= '</a>';
1321:
1322: if ( Sensei_WC::is_course_purchasable( $course_id ) ){
1323:
1324: $message = sprintf( __( 'Please purchase the %1$s before taking this quiz.', 'woothemes-sensei' ), $a_element );
1325:
1326: } else {
1327:
1328: $message = sprintf( __( 'Please sign up for the %1$s before taking this quiz.', 'woothemes-sensei' ), $a_element );
1329:
1330: }
1331:
1332:
1333: }
1334:
1335:
1336: $message = apply_filters( 'sensei_user_quiz_status_' . $status, $message );
1337:
1338: if( $is_lesson && ! in_array( $status, array( 'login_required', 'not_started_course' ) ) ) {
1339: $quiz_id = Sensei()->lesson->lesson_quizzes( $lesson_id );
1340: $extra = '<p><a class="button" href="' . esc_url( get_permalink( $quiz_id ) ) . '" title="' . __( 'View the lesson quiz', 'woothemes-sensei' ) . '">' . __( 'View the lesson quiz', 'woothemes-sensei' ) . '</a></p>';
1341: }
1342:
1343:
1344: return apply_filters( 'sensei_user_quiz_status', array( 'status' => $status, 'box_class' => $box_class, 'message' => $message, 'extra' => $extra ), $lesson_id, $user_id, $is_lesson );
1345: }
1346:
1347: 1348: 1349: 1350: 1351: 1352: 1353:
1354: public static function user_start_course( $user_id = 0, $course_id = 0 ) {
1355:
1356: $activity_logged = false;
1357:
1358: if( $user_id && $course_id ) {
1359:
1360: $activity_logged = Sensei_Utils::user_started_course( $course_id, $user_id );
1361: if ( ! $activity_logged ) {
1362:
1363:
1364: $course_metadata = array(
1365: 'start' => current_time('mysql'),
1366: 'percent' => 0,
1367: 'complete' => 0,
1368: );
1369:
1370: $activity_logged = Sensei_Utils::update_course_status( $user_id, $course_id, $course_status = 'in-progress', $course_metadata );
1371:
1372:
1373: if ( $activity_logged ) {
1374: do_action( 'sensei_user_course_start', $user_id, $course_id );
1375: }
1376: }
1377: }
1378:
1379: return $activity_logged;
1380: }
1381:
1382: 1383: 1384: 1385: 1386: 1387: 1388: 1389:
1390: public static function user_started_course( $course_id = 0, $user_id = 0 ) {
1391:
1392: $user_started_course = false;
1393:
1394: if( $course_id ) {
1395:
1396: if( ! $user_id ) {
1397: $user_id = get_current_user_id();
1398: }
1399:
1400: if ( ! $user_id > 0 ) {
1401:
1402: $user_started_course = false;
1403:
1404: } else {
1405:
1406: $activity_args = array(
1407: 'post_id' => $course_id,
1408: 'user_id' => $user_id,
1409: 'type' => 'sensei_course_status',
1410: 'field' => 'comment_ID'
1411: );
1412:
1413: $user_course_status_id = Sensei_Utils::sensei_get_activity_value( $activity_args );
1414:
1415: if ( $user_course_status_id ) {
1416:
1417: $user_started_course = $user_course_status_id;
1418:
1419: }
1420: }
1421: }
1422:
1423: 1424: 1425: 1426: 1427: 1428: 1429: 1430: 1431: 1432:
1433: return apply_filters( 'sensei_user_started_course', $user_started_course, $course_id, $user_id );
1434:
1435: }
1436:
1437: 1438: 1439: 1440: 1441: 1442: 1443: 1444:
1445: public static function user_complete_course( $course_id = 0, $user_id = 0 ) {
1446: global $wp_version;
1447:
1448: if( $course_id ) {
1449: if( ! $user_id ) {
1450: $user_id = get_current_user_id();
1451: }
1452:
1453: $course_status = 'in-progress';
1454: $course_metadata = array();
1455: $course_completion = Sensei()->settings->settings[ 'course_completion' ];
1456: $lessons_completed = $total_lessons = 0;
1457: $lesson_status_args = array(
1458: 'user_id' => $user_id,
1459: 'status' => 'any',
1460: 'type' => 'sensei_lesson_status',
1461: );
1462:
1463:
1464: $lesson_ids = Sensei()->course->course_lessons( $course_id, 'any', 'ids' );
1465: $total_lessons = count( $lesson_ids );
1466:
1467:
1468:
1469:
1470:
1471:
1472:
1473:
1474:
1475:
1476: $all_lesson_statuses = array();
1477:
1478: if ( version_compare($wp_version, '4.1', '>=') ) {
1479: $lesson_status_args['post__in'] = $lesson_ids;
1480: $all_lesson_statuses = Sensei_Utils::sensei_check_for_activity( $lesson_status_args, true );
1481:
1482: if ( !is_array($all_lesson_statuses) ) {
1483: $all_lesson_statuses = array( $all_lesson_statuses );
1484: }
1485: }
1486:
1487: else {
1488: foreach( $lesson_ids as $lesson_id ) {
1489: $lesson_status_args['post_id'] = $lesson_id;
1490: $each_lesson_status = Sensei_Utils::sensei_check_for_activity( $lesson_status_args, true );
1491:
1492: if ( !empty($each_lesson_status->comment_approved) ) {
1493: $all_lesson_statuses[] = $each_lesson_status;
1494: }
1495: }
1496: }
1497: foreach( $all_lesson_statuses as $lesson_status ) {
1498:
1499: if ( 'passed' != $course_completion ) {
1500: switch ( $lesson_status->comment_approved ) {
1501:
1502: case 'in-progress':
1503: case 'ungraded':
1504: break;
1505:
1506: default:
1507: $lessons_completed++;
1508: break;
1509: }
1510: }
1511: else {
1512: switch ( $lesson_status->comment_approved ) {
1513: case 'complete':
1514: case 'graded':
1515: case 'passed':
1516: $lessons_completed++;
1517: break;
1518:
1519:
1520: case 'failed':
1521: default:
1522: break;
1523: }
1524: }
1525: }
1526: if ( $lessons_completed == $total_lessons ) {
1527: $course_status = 'complete';
1528: }
1529:
1530:
1531: $course_metadata['complete'] = $lessons_completed;
1532:
1533: $course_metadata['percent'] = abs( round( ( doubleval( $lessons_completed ) * 100 ) / ( $total_lessons ), 0 ) );
1534:
1535: $activity_logged = Sensei_Utils::update_course_status( $user_id, $course_id, $course_status, $course_metadata );
1536:
1537:
1538: if ( 'complete' == $course_status ) {
1539: do_action( 'sensei_user_course_end', $user_id, $course_id );
1540: }
1541: return $activity_logged;
1542: }
1543:
1544: return false;
1545: }
1546:
1547: 1548: 1549: 1550: 1551: 1552: 1553: 1554:
1555: public static function user_completed_course( $course , $user_id = 0 ) {
1556:
1557: if( $course ) {
1558: if ( is_object( $course ) && is_a( $course,'WP_Comment') ) {
1559: $user_course_status = $course->comment_approved;
1560: }
1561: elseif ( !is_numeric( $course ) && ! is_a( $course,'WP_Post') ) {
1562: $user_course_status = $course;
1563: }
1564: else {
1565:
1566:
1567: if( ! $user_id ) {
1568:
1569: $user_id = get_current_user_id();
1570:
1571: if( empty( $user_id ) ){
1572:
1573: return false;
1574:
1575: }
1576: }
1577:
1578: if( is_a( $course, 'WP_Post' ) ){
1579: $course = $course->ID;
1580: }
1581:
1582: $user_course_status = Sensei_Utils::user_course_status( $course , $user_id );
1583: if( isset( $user_course_status->comment_approved ) ){
1584: $user_course_status = $user_course_status->comment_approved;
1585: }
1586:
1587: }
1588: if( $user_course_status && 'complete' == $user_course_status ) {
1589: return true;
1590: }
1591: }
1592: return false;
1593: }
1594:
1595: 1596: 1597: 1598: 1599: 1600: 1601: 1602:
1603: public static function user_started_lesson( $lesson_id = 0, $user_id = 0 ) {
1604:
1605: if( $lesson_id ) {
1606: if( ! $user_id ) {
1607: $user_id = get_current_user_id();
1608: }
1609:
1610: $activity_args = array(
1611: 'post_id' => $lesson_id,
1612: 'user_id' => $user_id,
1613: 'type' => 'sensei_lesson_status',
1614: 'field' => 'comment_ID' );
1615:
1616: $user_lesson_status_id = Sensei_Utils::sensei_get_activity_value( $activity_args );
1617: if( $user_lesson_status_id ) {
1618: return $user_lesson_status_id;
1619: }
1620: }
1621: return false;
1622: }
1623:
1624: 1625: 1626: 1627: 1628: 1629: 1630: 1631:
1632: public static function user_completed_lesson( $lesson = 0, $user_id = 0 ) {
1633:
1634: if( $lesson ) {
1635: $lesson_id = 0;
1636: if ( is_object( $lesson ) ) {
1637: $user_lesson_status = $lesson->comment_approved;
1638: $lesson_id = $lesson->comment_post_ID;
1639: }
1640: elseif ( ! is_numeric( $lesson ) ) {
1641: $user_lesson_status = $lesson;
1642: }
1643: else {
1644: if( ! $user_id ) {
1645: $user_id = get_current_user_id();
1646: }
1647:
1648:
1649: if( ! $user_id > 0 ){
1650: return false;
1651: }
1652: $_user_lesson_status = Sensei_Utils::user_lesson_status( $lesson, $user_id );
1653:
1654: if ( isset( $_user_lesson_status->comment_approved ) ) {
1655:
1656: $user_lesson_status = $_user_lesson_status->comment_approved;
1657:
1658: } else {
1659:
1660: return false;
1661:
1662: }
1663:
1664: $lesson_id = $lesson;
1665: }
1666: if ( 'in-progress' != $user_lesson_status ) {
1667:
1668:
1669:
1670:
1671: switch( $user_lesson_status ) {
1672: case 'complete':
1673: case 'graded':
1674: case 'passed':
1675: return true;
1676: break;
1677:
1678: case 'failed':
1679:
1680: if ( $lesson_id ) {
1681:
1682: $lesson_quiz_id = Sensei()->lesson->lesson_quizzes( $lesson_id );
1683: if ( $lesson_quiz_id ) {
1684:
1685: $pass_required = get_post_meta( $lesson_quiz_id, '_pass_required', true );
1686: if ( empty($pass_required) ) {
1687:
1688: return true;
1689: }
1690: }
1691: }
1692: return false;
1693: break;
1694: }
1695: }
1696: }
1697:
1698: return false;
1699: }
1700:
1701: 1702: 1703: 1704: 1705: 1706: 1707: 1708:
1709: public static function user_course_status( $course_id = 0, $user_id = 0 ) {
1710:
1711:
1712: if( $course_id ) {
1713: if( ! $user_id ) {
1714: $user_id = get_current_user_id();
1715: }
1716:
1717: $user_course_status = Sensei_Utils::sensei_check_for_activity( array( 'post_id' => $course_id, 'user_id' => $user_id, 'type' => 'sensei_course_status' ), true );
1718: return $user_course_status;
1719: }
1720:
1721: return false;
1722: }
1723:
1724: 1725: 1726: 1727: 1728: 1729: 1730: 1731:
1732: public static function user_lesson_status( $lesson_id = 0, $user_id = 0 ) {
1733:
1734: if( ! $user_id ) {
1735: $user_id = get_current_user_id();
1736: }
1737:
1738: if( $lesson_id > 0 && $user_id > 0 ) {
1739:
1740: $user_lesson_status = Sensei_Utils::sensei_check_for_activity( array( 'post_id' => $lesson_id, 'user_id' => $user_id, 'type' => 'sensei_lesson_status' ), true );
1741: return $user_lesson_status;
1742: }
1743:
1744: return false;
1745: }
1746:
1747: public static function is_preview_lesson( $lesson_id ) {
1748: $is_preview = false;
1749:
1750: if( 'lesson' == get_post_type( $lesson_id ) ) {
1751: $lesson_preview = get_post_meta( $lesson_id, '_lesson_preview', true );
1752: if ( isset( $lesson_preview ) && '' != $lesson_preview ) {
1753: $is_preview = true;
1754: }
1755: }
1756:
1757: return $is_preview;
1758: }
1759:
1760: public static function user_passed_quiz( $quiz_id = 0, $user_id = 0 ) {
1761:
1762: if( ! $quiz_id ) return false;
1763:
1764: if( ! $user_id ) {
1765: $user_id = get_current_user_id();
1766: }
1767: $lesson_id = get_post_meta( $quiz_id, '_quiz_lesson', true );
1768:
1769:
1770: $lesson_status = Sensei_Utils::user_lesson_status( $lesson_id, $user_id );
1771: $quiz_grade = get_comment_meta( $lesson_status->comment_ID, 'grade', true );
1772:
1773:
1774: $quiz_passmark = abs( round( doubleval( get_post_meta( $quiz_id, '_quiz_passmark', true ) ), 2 ) );
1775: if ( $quiz_passmark <= intval( $quiz_grade ) ) {
1776: return true;
1777: }
1778:
1779: return false;
1780:
1781: }
1782:
1783: 1784: 1785: 1786: 1787: 1788: 1789: 1790: 1791: 1792: 1793: 1794:
1795: public static function update_lesson_status( $user_id, $lesson_id, $status = 'in-progress', $metadata = array() ) {
1796: $comment_id = false;
1797: if ( !empty($status) ) {
1798: $args = array(
1799: 'user_id' => $user_id,
1800: 'post_id' => $lesson_id,
1801: 'status' => $status,
1802: 'type' => 'sensei_lesson_status',
1803: 'action' => 'update',
1804: 'keep_time' => true,
1805: );
1806: if( 'in-progress' == $status ) {
1807: unset( $args['keep_time'] );
1808: }
1809:
1810: $comment_id = Sensei_Utils::sensei_log_activity( $args );
1811: if ( $comment_id && !empty($metadata) ) {
1812: foreach( $metadata as $key => $value ) {
1813: update_comment_meta( $comment_id, $key, $value );
1814: }
1815: }
1816:
1817: do_action( 'sensei_lesson_status_updated', $status, $user_id, $lesson_id, $comment_id );
1818: }
1819: return $comment_id;
1820: }
1821:
1822: 1823: 1824: 1825: 1826: 1827: 1828: 1829: 1830: 1831: 1832:
1833: public static function update_course_status( $user_id, $course_id, $status = 'in-progress', $metadata = array() ) {
1834: $comment_id = false;
1835: if ( !empty($status) ) {
1836: $args = array(
1837: 'user_id' => $user_id,
1838: 'post_id' => $course_id,
1839: 'status' => $status,
1840: 'type' => 'sensei_course_status',
1841: 'action' => 'update',
1842: 'keep_time' => true,
1843: );
1844: if( 'in-progress' == $status ) {
1845: unset( $args['keep_time'] );
1846: }
1847:
1848: $comment_id = Sensei_Utils::sensei_log_activity( $args );
1849: if ( $comment_id && !empty($metadata) ) {
1850: foreach( $metadata as $key => $value ) {
1851: update_comment_meta( $comment_id, $key, $value );
1852: }
1853: }
1854: do_action( 'sensei_course_status_updated', $status, $user_id, $course_id, $comment_id );
1855: }
1856: return $comment_id;
1857: }
1858:
1859: 1860: 1861: 1862: 1863: 1864: 1865:
1866: public static function single_comment_filter( $pieces ) {
1867: unset( $pieces['orderby'] );
1868: unset( $pieces['order'] );
1869:
1870: return $pieces;
1871: }
1872:
1873: 1874: 1875: 1876: 1877: 1878: 1879:
1880: public static function comment_any_status_filter( $pieces ) {
1881:
1882: $pieces['where'] = str_replace( array( "( comment_approved = '0' OR comment_approved = '1' ) AND", "comment_approved = 'any' AND" ), '', $pieces['where'] );
1883:
1884: return $pieces;
1885: }
1886:
1887: 1888: 1889: 1890: 1891: 1892: 1893:
1894: public static function comment_multiple_status_filter( $pieces ) {
1895:
1896: preg_match( "/^comment_approved = '([a-z\-\,]+)'/", $pieces['where'], $placeholder );
1897: if ( !empty($placeholder[1]) ) {
1898: $statuses = explode( ',', $placeholder[1] );
1899: $pieces['where'] = str_replace( "comment_approved = '" . $placeholder[1] . "'", "comment_approved IN ('". implode( "', '", $statuses ) . "')", $pieces['where'] );
1900: }
1901:
1902: return $pieces;
1903: }
1904:
1905: 1906: 1907: 1908: 1909: 1910:
1911: public static function comment_total_sum_meta_value_filter( $pieces ) {
1912: global $wpdb, $wp_version;
1913:
1914: $pieces['fields'] = " COUNT(*) AS total, SUM($wpdb->commentmeta.meta_value) AS meta_sum ";
1915: unset( $pieces['groupby'] );
1916: if ( version_compare($wp_version, '4.1', '>=') ) {
1917: $args['order'] = false;
1918: $args['orderby'] = false;
1919: }
1920:
1921: return $pieces;
1922: }
1923:
1924: 1925: 1926: 1927: 1928: 1929: 1930:
1931: public static function get_posts_count_only_filter( $pieces ) {
1932: global $wp_version;
1933:
1934: $pieces['fields'] = " COUNT(*) AS total ";
1935: unset( $pieces['groupby'] );
1936: if ( version_compare($wp_version, '4.1', '>=') ) {
1937: $args['order'] = false;
1938: $args['orderby'] = false;
1939: }
1940: return $pieces;
1941: }
1942:
1943: 1944: 1945: 1946: 1947: 1948: 1949: 1950: 1951: 1952: 1953: 1954:
1955: public static function add_user_data( $data_key, $post_id , $value = '' , $user_id = 0 ){
1956:
1957: return self::update_user_data( $data_key, $post_id, $value , $user_id );
1958:
1959: }
1960:
1961: 1962: 1963: 1964: 1965: 1966: 1967: 1968: 1969: 1970: 1971: 1972: 1973: 1974: 1975:
1976: public static function update_user_data( $data_key, $post_id, $value = '' , $user_id = 0 ){
1977:
1978: if( ! ( $user_id > 0 ) ){
1979: $user_id = get_current_user_id();
1980: }
1981:
1982: $supported_post_types = array( 'course', 'lesson' );
1983: $post_type = get_post_type( $post_id );
1984: if( empty( $post_id ) || empty( $data_key )
1985: || ! is_int( $post_id ) || ! ( intval( $post_id ) > 0 ) || ! ( intval( $user_id ) > 0 )
1986: || !get_userdata( $user_id )
1987: || ! in_array( $post_type, $supported_post_types ) ){
1988:
1989: return false;
1990: }
1991:
1992:
1993:
1994: $status_function = 'user_'.$post_type.'_status';
1995: $sensei_user_status = self::$status_function( $post_id ,$user_id );
1996: if( ! isset( $sensei_user_status->comment_ID ) ){
1997:
1998: $start_function = 'user_start_'.$post_type;
1999: $sensei_user_activity_id = self::$start_function( $user_id, $post_id );
2000:
2001: }else{
2002:
2003: $sensei_user_activity_id = $sensei_user_status->comment_ID;
2004:
2005: }
2006:
2007:
2008: $success = update_comment_meta( $sensei_user_activity_id, $data_key, $value );
2009:
2010: return $success;
2011:
2012: }
2013:
2014: 2015: 2016: 2017: 2018: 2019: 2020: 2021: 2022: 2023: 2024: 2025: 2026:
2027: public static function get_user_data( $data_key, $post_id, $user_id = 0 ){
2028:
2029: $user_data_value = true;
2030:
2031: if( ! ( $user_id > 0 ) ){
2032: $user_id = get_current_user_id();
2033: }
2034:
2035: $supported_post_types = array( 'course', 'lesson' );
2036: $post_type = get_post_type( $post_id );
2037: if( empty( $post_id ) || empty( $data_key )
2038: || ! ( intval( $post_id ) > 0 ) || ! ( intval( $user_id ) > 0 )
2039: || ! get_userdata( $user_id )
2040: || !in_array( $post_type, $supported_post_types ) ){
2041:
2042: return false;
2043: }
2044:
2045:
2046:
2047: $status_function = 'user_'.$post_type.'_status';
2048: $sensei_user_status = self::$status_function( $post_id ,$user_id );
2049: if( ! isset( $sensei_user_status->comment_ID ) ){
2050: return false;
2051: }
2052:
2053: $sensei_user_activity_id = $sensei_user_status->comment_ID;
2054: $user_data_value = get_comment_meta( $sensei_user_activity_id , $data_key, true );
2055:
2056: return $user_data_value;
2057:
2058: }
2059:
2060: 2061: 2062: 2063: 2064: 2065: 2066: 2067: 2068:
2069: public static function delete_user_data( $data_key, $post_id , $user_id ){
2070: $deleted = true;
2071:
2072: if( ! ( $user_id > 0 ) ){
2073: $user_id = get_current_user_id();
2074: }
2075:
2076: $supported_post_types = array( 'course', 'lesson' );
2077: $post_type = get_post_type( $post_id );
2078: if( empty( $post_id ) || empty( $data_key )
2079: || ! is_int( $post_id ) || ! ( intval( $post_id ) > 0 ) || ! ( intval( $user_id ) > 0 )
2080: || ! get_userdata( $user_id )
2081: || !in_array( $post_type, $supported_post_types ) ){
2082:
2083: return false;
2084: }
2085:
2086:
2087:
2088: $status_function = 'user_'.$post_type.'_status';
2089: $sensei_user_status = self::$status_function( $post_id ,$user_id );
2090: if( ! isset( $sensei_user_status->comment_ID ) ){
2091: return false;
2092: }
2093:
2094: $sensei_user_activity_id = $sensei_user_status->comment_ID;
2095: $deleted = delete_comment_meta( $sensei_user_activity_id , $data_key );
2096:
2097: return $deleted;
2098:
2099: }
2100:
2101:
2102: 2103: 2104: 2105: 2106: 2107: 2108: 2109: 2110: 2111: 2112: 2113: 2114: 2115: 2116: 2117: 2118: 2119:
2120: public static function generate_drop_down( $selected_value, $options = array() , $attributes = array(), $enable_none_option = true ) {
2121:
2122: $drop_down_element = '';
2123:
2124:
2125: if( !isset( $attributes['name'] ) || empty( $attributes['name'] ) ) {
2126:
2127: $attributes['name'] = 'sensei-options';
2128:
2129: }
2130:
2131: if( !isset( $attributes['id'] ) || empty( $attributes['id'] ) ) {
2132:
2133: $attributes['id'] = 'sensei-options';
2134:
2135: }
2136:
2137: if( !isset( $attributes['class'] ) || empty( $attributes['class'] ) ) {
2138:
2139: $attributes['class'] ='chosen_select widefat';
2140:
2141: }
2142:
2143:
2144: $combined_attributes = '';
2145: foreach( $attributes as $attribute => $value ){
2146:
2147: $combined_attributes .= $attribute . '="'.$value.'"' . ' ';
2148:
2149: }
2150:
2151:
2152:
2153: $drop_down_element .= '<select '. $combined_attributes . ' >' . "\n";
2154:
2155:
2156: if( $enable_none_option ) {
2157: $drop_down_element .= '<option value="">' . __('None', 'woothemes-sensei') . '</option>';
2158: }
2159:
2160: if ( count( $options ) > 0 ) {
2161:
2162: foreach ($options as $value => $option ){
2163:
2164: $element = '';
2165: $element.= '<option value="' . esc_attr( $value ) . '"';
2166: $element .= selected( $value, $selected_value, false ) . '>';
2167: $element .= esc_html( $option ) . '</option>' . "\n";
2168:
2169:
2170: $drop_down_element.= $element;
2171: }
2172:
2173: }
2174:
2175: $drop_down_element .= '</select>' . "\n";
2176:
2177: return $drop_down_element;
2178:
2179: }
2180:
2181: 2182: 2183: 2184: 2185: 2186: 2187: 2188: 2189: 2190: 2191: 2192: 2193: 2194:
2195: public static function round( $val, $precision = 0, $mode = PHP_ROUND_HALF_UP, $context = '' ){
2196:
2197: 2198: 2199: 2200: 2201:
2202: $precision = apply_filters( 'sensei_round_precision', $precision , $val, $context, $mode );
2203:
2204: 2205: 2206: 2207: 2208: 2209: 2210: 2211:
2212: $mode = apply_filters( 'sensei_round_mode', $mode , $val, $context, $precision );
2213:
2214: if ( version_compare(PHP_VERSION, '5.3.0') >= 0 ) {
2215:
2216: return round( $val, $precision, $mode );
2217:
2218: }else{
2219:
2220: return round( $val, $precision );
2221:
2222: }
2223:
2224: }
2225:
2226: 2227: 2228: 2229: 2230: 2231:
2232: public static function get_current_url(){
2233:
2234: global $wp;
2235: $current_url = trailingslashit( home_url( $wp->request ) );
2236: if ( isset( $_GET ) ) {
2237:
2238: foreach ($_GET as $param => $val ) {
2239:
2240: $current_url = add_query_arg( $param, $val , $current_url );
2241:
2242: }
2243: }
2244:
2245: return $current_url;
2246: }
2247:
2248: 2249: 2250: 2251: 2252:
2253: public static function restore_wp_query() {
2254:
2255: wp_reset_query();
2256:
2257: }
2258:
2259: 2260: 2261: 2262: 2263: 2264: 2265: 2266: 2267: 2268: 2269:
2270: public static function array_zip_merge( $array_a, $array_b ){
2271:
2272: if( ! is_array( $array_a ) || ! is_array( $array_b ) ){
2273: trigger_error('array_zip_merge requires both arrays to be indexed arrays ');
2274: }
2275:
2276: $merged_array = array();
2277: $total_elements = count( $array_a ) + count( $array_b );
2278:
2279:
2280: for ( $i = 0; $i < $total_elements; $i++) {
2281:
2282:
2283: if( isset( $array_a[ $i ] ) ){
2284: $merged_array[] = $array_a[ $i ] ;
2285: }
2286:
2287:
2288:
2289: if( isset( $array_b[ $i ] ) ){
2290: $merged_array[] = $array_b[ $i ] ;
2291: }
2292:
2293: }
2294:
2295: return $merged_array;
2296: }
2297:
2298: }
2299:
2300: 2301: 2302: 2303: 2304:
2305: class WooThemes_Sensei_Utils extends Sensei_Utils{}