PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.0.3
Tutor LMS – eLearning and online course solution v1.0.3
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Utils.php
tutor / classes Last commit date
Addons.php 7 years ago Admin.php 7 years ago Ajax.php 7 years ago Assets.php 7 years ago Course.php 7 years ago Gutenberg.php 7 years ago Instructor.php 7 years ago Instructors_List.php 7 years ago Lesson.php 7 years ago Options.php 7 years ago Post_types.php 7 years ago Q_and_A.php 7 years ago Question.php 7 years ago Question_Answers_List.php 7 years ago Quiz.php 7 years ago Quiz_Attempts_List.php 7 years ago Rewrite_Rules.php 7 years ago Shortcode.php 7 years ago Student.php 7 years ago Students_List.php 7 years ago Template.php 7 years ago Theme_Compatibility.php 7 years ago Tools.php 7 years ago Tutor_Base.php 7 years ago Tutor_List_Table.php 7 years ago User.php 7 years ago Utils.php 7 years ago Video_Stream.php 7 years ago init.php 7 years ago
Utils.php
3598 lines
1 <?php
2 namespace TUTOR;
3
4 if ( ! defined( 'ABSPATH' ) )
5 exit;
6
7
8 class Utils {
9 /**
10 * @param null $key
11 * @param bool $default
12 *
13 * @return array|bool|mixed
14 *
15 * Get option data
16 *
17 * @since v.1.0.0
18 */
19 public function get_option($key = null, $default = false){
20 $option = (array) maybe_unserialize(get_option('tutor_option'));
21
22 if (empty($option) || ! is_array($option)){
23 return $default;
24 }
25 if ( ! $key){
26 return $option;
27 }
28 if (array_key_exists($key, $option)){
29 return apply_filters($key, $option[$key]);
30 }
31 //Access array value via dot notation, such as option->get('value.subvalue')
32 if (strpos($key, '.')){
33 $option_key_array = explode('.', $key);
34
35 $new_option = $option;
36 foreach ($option_key_array as $dotKey){
37 if (isset($new_option[$dotKey])){
38 $new_option = $new_option[$dotKey];
39 }else{
40 return $default;
41 }
42 }
43 return apply_filters($key, $new_option);
44 }
45
46 return $default;
47 }
48
49 /**
50 * @param null $key
51 * @param bool $value
52 *
53 * Update Option
54 *
55 * @since v.1.0.0
56 */
57
58 public function update_option($key = null, $value = false){
59 $option = (array) maybe_unserialize(get_option('tutor_option'));
60 $option[$key] = $value;
61 update_option('tutor_option', $option);
62 }
63
64 /**
65 * @param null $key
66 * @param array $array
67 *
68 * @return array|bool|mixed
69 *
70 * get array value by dot notation
71 *
72 * @since v.1.0.0
73 *
74 */
75
76 public function avalue_dot($key = null, $array = array()){
77 $array = (array) $array;
78 if ( ! $key || ! count($array) ){
79 return false;
80 }
81 $option_key_array = explode('.', $key);
82
83 $value = $array;
84
85 foreach ($option_key_array as $dotKey){
86 if (isset($value[$dotKey])){
87 $value = $value[$dotKey];
88 }else{
89 return false;
90 }
91 }
92 return $value;
93 }
94
95 /**
96 * @return array
97 *
98 * Get all pages
99 *
100 * @since v.1.0.0
101 */
102 public function get_pages(){
103 $pages = array();
104 $wp_pages = get_pages();
105 if (is_array($wp_pages) && count($wp_pages)){
106 foreach ($wp_pages as $page){
107 $pages[$page->ID] = $page->post_title;
108 }
109 }
110 return $pages;
111 }
112
113 /**
114 * @return string
115 *
116 * Get course archive URL
117 *
118 * @since v.1.0.0
119 */
120 public function course_archive_page_url(){
121 $course_post_type = tutor()->course_post_type;
122 $course_page_url = trailingslashit(home_url()).$course_post_type;
123
124 $course_archive_page = $this->get_option('course_archive_page');
125 if ($course_archive_page && $course_archive_page !== '-1'){
126 $course_page_url = get_permalink($course_archive_page);
127 }
128 return trailingslashit($course_page_url);
129 }
130
131 /**
132 * @param int $student_id
133 *
134 * @return string
135 *
136 * Get student URL
137 *
138 * @since v.1.0.0
139 */
140
141 public function profile_url($student_id = 0){
142 $site_url = trailingslashit(home_url()).'profile/';
143 $user_name = '';
144
145 $student_id = $this->get_user_id($student_id);
146 if ($student_id){
147 global $wpdb;
148 $user = $wpdb->get_row("SELECT user_login from {$wpdb->users} WHERE ID = {$student_id} ");
149 if ($user){
150 $user_name = $user->user_login;
151 }
152 }else{
153 $user_name = 'user_name';
154 }
155
156 return $site_url.$user_name;
157 }
158
159 /**
160 * @param string $user_login
161 *
162 * @return array|null|object
163 *
164 * Get user by user login
165 *
166 * @since v.1.0.0
167 */
168 public function get_user_by_login($user_login = ''){
169 global $wpdb;
170 $user_login = sanitize_text_field($user_login);
171 $user = $wpdb->get_row("SELECT * from {$wpdb->users} WHERE user_login = '{$user_login}'");
172 return $user;
173 }
174
175 /**
176 * @return bool
177 *
178 * Check if WooCommerce Activated
179 *
180 * @since v.1.0.0
181 */
182
183 public function has_wc(){
184 $activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ));
185 //$depends = array('woocommerce/woocommerce.php', 'tutor-woocommerce/tutor-woocommerce.php');
186 $depends = array('woocommerce/woocommerce.php');
187 $has = count(array_intersect($depends, $activated_plugins)) == count($depends);
188
189 return $has;
190 }
191
192 /**
193 * @return bool
194 *
195 * determine if EDD plugin activated
196 *
197 * @since v.1.0.0
198 */
199 public function has_edd(){
200 $activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ));
201 //$depends = array('easy-digital-downloads/easy-digital-downloads.php', 'tutor-edd/tutor-edd.php');
202 $depends = array('easy-digital-downloads/easy-digital-downloads.php');
203 $has = count(array_intersect($depends, $activated_plugins)) == count($depends);
204
205 return $has;
206 }
207
208 /**
209 * @return mixed
210 *
211 * @since v.1.0.0
212 */
213 public function languages(){
214 $language_codes = array(
215 'en' => 'English' ,
216 'aa' => 'Afar' ,
217 'ab' => 'Abkhazian' ,
218 'af' => 'Afrikaans' ,
219 'am' => 'Amharic' ,
220 'ar' => 'Arabic' ,
221 'as' => 'Assamese' ,
222 'ay' => 'Aymara' ,
223 'az' => 'Azerbaijani' ,
224 'ba' => 'Bashkir' ,
225 'be' => 'Byelorussian' ,
226 'bg' => 'Bulgarian' ,
227 'bh' => 'Bihari' ,
228 'bi' => 'Bislama' ,
229 'bn' => 'Bengali/Bangla' ,
230 'bo' => 'Tibetan' ,
231 'br' => 'Breton' ,
232 'ca' => 'Catalan' ,
233 'co' => 'Corsican' ,
234 'cs' => 'Czech' ,
235 'cy' => 'Welsh' ,
236 'da' => 'Danish' ,
237 'de' => 'German' ,
238 'dz' => 'Bhutani' ,
239 'el' => 'Greek' ,
240 'eo' => 'Esperanto' ,
241 'es' => 'Spanish' ,
242 'et' => 'Estonian' ,
243 'eu' => 'Basque' ,
244 'fa' => 'Persian' ,
245 'fi' => 'Finnish' ,
246 'fj' => 'Fiji' ,
247 'fo' => 'Faeroese' ,
248 'fr' => 'French' ,
249 'fy' => 'Frisian' ,
250 'ga' => 'Irish' ,
251 'gd' => 'Scots/Gaelic' ,
252 'gl' => 'Galician' ,
253 'gn' => 'Guarani' ,
254 'gu' => 'Gujarati' ,
255 'ha' => 'Hausa' ,
256 'hi' => 'Hindi' ,
257 'hr' => 'Croatian' ,
258 'hu' => 'Hungarian' ,
259 'hy' => 'Armenian' ,
260 'ia' => 'Interlingua' ,
261 'ie' => 'Interlingue' ,
262 'ik' => 'Inupiak' ,
263 'in' => 'Indonesian' ,
264 'is' => 'Icelandic' ,
265 'it' => 'Italian' ,
266 'iw' => 'Hebrew' ,
267 'ja' => 'Japanese' ,
268 'ji' => 'Yiddish' ,
269 'jw' => 'Javanese' ,
270 'ka' => 'Georgian' ,
271 'kk' => 'Kazakh' ,
272 'kl' => 'Greenlandic' ,
273 'km' => 'Cambodian' ,
274 'kn' => 'Kannada' ,
275 'ko' => 'Korean' ,
276 'ks' => 'Kashmiri' ,
277 'ku' => 'Kurdish' ,
278 'ky' => 'Kirghiz' ,
279 'la' => 'Latin' ,
280 'ln' => 'Lingala' ,
281 'lo' => 'Laothian' ,
282 'lt' => 'Lithuanian' ,
283 'lv' => 'Latvian/Lettish' ,
284 'mg' => 'Malagasy' ,
285 'mi' => 'Maori' ,
286 'mk' => 'Macedonian' ,
287 'ml' => 'Malayalam' ,
288 'mn' => 'Mongolian' ,
289 'mo' => 'Moldavian' ,
290 'mr' => 'Marathi' ,
291 'ms' => 'Malay' ,
292 'mt' => 'Maltese' ,
293 'my' => 'Burmese' ,
294 'na' => 'Nauru' ,
295 'ne' => 'Nepali' ,
296 'nl' => 'Dutch' ,
297 'no' => 'Norwegian' ,
298 'oc' => 'Occitan' ,
299 'om' => '(Afan)/Oromoor/Oriya' ,
300 'pa' => 'Punjabi' ,
301 'pl' => 'Polish' ,
302 'ps' => 'Pashto/Pushto' ,
303 'pt' => 'Portuguese' ,
304 'qu' => 'Quechua' ,
305 'rm' => 'Rhaeto-Romance' ,
306 'rn' => 'Kirundi' ,
307 'ro' => 'Romanian' ,
308 'ru' => 'Russian' ,
309 'rw' => 'Kinyarwanda' ,
310 'sa' => 'Sanskrit' ,
311 'sd' => 'Sindhi' ,
312 'sg' => 'Sangro' ,
313 'sh' => 'Serbo-Croatian' ,
314 'si' => 'Singhalese' ,
315 'sk' => 'Slovak' ,
316 'sl' => 'Slovenian' ,
317 'sm' => 'Samoan' ,
318 'sn' => 'Shona' ,
319 'so' => 'Somali' ,
320 'sq' => 'Albanian' ,
321 'sr' => 'Serbian' ,
322 'ss' => 'Siswati' ,
323 'st' => 'Sesotho' ,
324 'su' => 'Sundanese' ,
325 'sv' => 'Swedish' ,
326 'sw' => 'Swahili' ,
327 'ta' => 'Tamil' ,
328 'te' => 'Tegulu' ,
329 'tg' => 'Tajik' ,
330 'th' => 'Thai' ,
331 'ti' => 'Tigrinya' ,
332 'tk' => 'Turkmen' ,
333 'tl' => 'Tagalog' ,
334 'tn' => 'Setswana' ,
335 'to' => 'Tonga' ,
336 'tr' => 'Turkish' ,
337 'ts' => 'Tsonga' ,
338 'tt' => 'Tatar' ,
339 'tw' => 'Twi' ,
340 'uk' => 'Ukrainian' ,
341 'ur' => 'Urdu' ,
342 'uz' => 'Uzbek' ,
343 'vi' => 'Vietnamese' ,
344 'vo' => 'Volapuk' ,
345 'wo' => 'Wolof' ,
346 'xh' => 'Xhosa' ,
347 'yo' => 'Yoruba' ,
348 'zh' => 'Chinese' ,
349 'zu' => 'Zulu' ,
350 );
351
352 return apply_filters('tutor/utils/languages', $language_codes);
353 }
354
355
356 /**
357 * @param string $value
358 *
359 * Check raw data
360 *
361 * @since v.1.0.0
362 */
363 public function print_view($value = ''){
364 echo '<pre>';
365 print_r($value);
366 echo '</pre>';
367 }
368
369 /**
370 * @param array $excludes
371 *
372 * @return array|null|object
373 *
374 * Get courses
375 *
376 * @since v.1.0.0
377 */
378
379 public function get_courses($excludes = array()){
380 global $wpdb;
381
382
383 $excludes = (array) $excludes;
384 $exclude_query = '';
385 if (count($excludes)){
386 $exclude_query = implode("','", $excludes);
387 }
388
389 $course_post_type = tutor()->course_post_type;
390 $query = $wpdb->get_results("SELECT ID, post_author, post_title, post_name,post_status, menu_order
391 from {$wpdb->posts} WHERE post_status = 'publish'
392 AND ID NOT IN('$exclude_query')
393 AND post_type = '{$course_post_type}' ");
394 return $query;
395 }
396
397 /**
398 * @param int $instructor_id
399 *
400 * @return array|null|object
401 *
402 * Get courses for instructors
403 *
404 * @since v.1.0.0
405 */
406 public function get_courses_for_instructors($instructor_id = 0){
407 global $wpdb;
408
409 $instructor_id = $this->get_user_id($instructor_id);
410
411 $course_post_type = tutor()->course_post_type;
412 $query = $wpdb->get_results("SELECT ID, post_author, post_title, post_name,post_status, menu_order
413 from {$wpdb->posts}
414 WHERE post_author = {$instructor_id}
415 AND post_status IN ('publish', 'pending')
416 AND post_type = '{$course_post_type}' ");
417 return $query;
418 }
419
420 /**
421 * @param $instructor_id
422 *
423 * @return null|string
424 *
425 * Get course count by instructor
426 *
427 * @since v.1.0.0
428 */
429
430 public function get_course_count_by_instructor($instructor_id){
431 global $wpdb;
432
433 $course_post_type = tutor()->course_post_type;
434 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts}
435 INNER JOIN {$wpdb->usermeta} ON user_id = {$instructor_id} AND meta_key = '_tutor_instructor_course_id' AND meta_value = ID
436 WHERE post_status = 'publish'
437 AND post_type = '{$course_post_type}' ; ");
438
439 return $count;
440 }
441
442 /**
443 * @param $instructor_id
444 *
445 * @return array|null|object
446 *
447 * Get courses by a instructor
448 *
449 * @since v.1.0.0
450 */
451 public function get_courses_by_instructor($instructor_id){
452 global $wpdb;
453
454 $course_post_type = tutor()->course_post_type;
455
456 $querystr = "
457 SELECT $wpdb->posts.*
458 FROM $wpdb->posts
459 INNER JOIN {$wpdb->usermeta} ON $wpdb->usermeta.user_id = {$instructor_id} AND $wpdb->usermeta.meta_key = '_tutor_instructor_course_id' AND $wpdb->usermeta.meta_value = $wpdb->posts.ID
460
461
462 WHERE $wpdb->posts.post_status = 'publish'
463 AND $wpdb->posts.post_type = '{$course_post_type}'
464 AND $wpdb->posts.post_date < NOW()
465 ORDER BY $wpdb->posts.post_date DESC";
466
467 $pageposts = $wpdb->get_results($querystr, OBJECT);
468 return $pageposts;
469 }
470
471 /**
472 * @return mixed
473 *
474 * Get archive page course count
475 *
476 * @since v.1.0.0
477 */
478 public function get_archive_page_course_count(){
479 global $wp_query;
480 return $wp_query->post_count;
481 }
482
483 /**
484 * @return null|string
485 *
486 * Get course count
487 *
488 * @since v.1.0.0
489 */
490 public function get_course_count(){
491 global $wpdb;
492
493 $course_post_type = tutor()->course_post_type;
494 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = '{$course_post_type}'; ");
495 return $count;
496 }
497
498 /**
499 * @return null|string
500 *
501 * Get lesson count
502 *
503 * @since v.1.0.0
504 */
505 public function get_lesson_count(){
506 global $wpdb;
507
508 $lesson_post_type = tutor()->lesson_post_type;
509 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = '{$lesson_post_type}'; ");
510 return $count;
511 }
512
513 /**
514 * @param int $course_id
515 * @param int $limit
516 *
517 * @return \WP_Query
518 *
519 * Get lesson
520 *
521 * @since v.1.0.0
522 */
523 public function get_lesson($course_id = 0, $limit = 10){
524 $course_id = $this->get_post_id($course_id);
525
526 $lesson_post_type = tutor()->lesson_post_type;
527 $args = array(
528 'post_status' => 'publish',
529 'post_type' => $lesson_post_type,
530 'posts_per_page' => $limit,
531 'meta_query' => array(
532 array(
533 'key' => '_tutor_course_id_for_lesson',
534 'value' => $course_id,
535 'compare' => '=',
536 ),
537 ),
538 );
539 $query = new \WP_Query($args);
540
541 return $query;
542 }
543
544 /**
545 * @param int $course_id
546 *
547 * @return int
548 *
549 * Get total lesson count by a course
550 *
551 * @since v.1.0.0
552 */
553 public function get_lesson_count_by_course($course_id = 0){
554 $course_id = $this->get_post_id($course_id);
555 global $wpdb;
556
557 $count_lesson = $wpdb->get_var("select count(meta_id) from {$wpdb->postmeta} where meta_key = '_tutor_course_id_for_lesson' AND meta_value = {$course_id} ");
558
559 return (int) $count_lesson;
560 }
561
562 /**
563 * @param int $course_id
564 * @param int $user_id
565 *
566 * @return int
567 *
568 * Get completed lesson total number by a course
569 *
570 * @since v.1.0.0
571 */
572 public function get_completed_lesson_count_by_course($course_id = 0, $user_id = 0){
573 $course_id = $this->get_post_id($course_id);
574 $user_id = $this->get_user_id($user_id);
575 global $wpdb;
576
577 $completed_lesson_ids = $wpdb->get_col("select post_id from {$wpdb->postmeta} where meta_key = '_tutor_course_id_for_lesson' AND meta_value = {$course_id} ");
578
579 $count = 0;
580 if (is_array($completed_lesson_ids) && count($completed_lesson_ids)){
581 $completed_lesson_meta_ids = array();
582 foreach ($completed_lesson_ids as $lesson_id){
583 $completed_lesson_meta_ids[] = '_tutor_completed_lesson_id_'.$lesson_id;
584 }
585 $in_ids = implode("','", $completed_lesson_meta_ids);
586
587 $count = (int) $wpdb->get_var("select count(umeta_id) from {$wpdb->usermeta} WHERE user_id = '{$user_id}' AND meta_key in('{$in_ids}') ");
588 }
589
590 return $count;
591 }
592
593 /**
594 * @param int $course_id
595 * @param int $user_id
596 *
597 * @return float|int
598 *
599 * @since v.1.0.0
600 */
601 public function get_course_completed_percent($course_id = 0, $user_id = 0){
602 $course_id = $this->get_post_id($course_id);
603 $user_id = $this->get_user_id($user_id);
604
605 $total_lesson = $this->get_lesson_count_by_course($course_id);
606 $completed_lesson = $this->get_completed_lesson_count_by_course($course_id, $user_id);
607
608 if ($total_lesson > 0 && $completed_lesson > 0){
609 return number_format(($completed_lesson * 100) / $total_lesson, 1);
610 }
611
612 return 0;
613 }
614
615 /**
616 * @param int $course_id
617 *
618 * @return \WP_Query
619 *
620 * Get all topics by given course ID
621 *
622 * @since v.1.0.0
623 */
624 public function get_topics($course_id = 0){
625 $course_id = $this->get_post_id($course_id);
626
627 $args = array(
628 'post_type' => 'topics',
629 'post_parent' => $course_id,
630 'orderby' => 'menu_order',
631 'order' => 'ASC',
632 'posts_per_page' => -1,
633 );
634
635 $query = new \WP_Query($args);
636 return $query;
637 }
638
639 /**
640 * @param $course_ID
641 *
642 * @return int
643 *
644 * Get next topic order id
645 *
646 * @since v.1.0.0
647 */
648 public function get_next_topic_order_id($course_ID){
649 global $wpdb;
650
651 $last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$course_ID} AND post_type = 'topics';");
652 return $last_order + 1;
653 }
654
655 /**
656 * @param $topic_ID
657 *
658 * @return int
659 *
660 * Get next course content order id
661 *
662 * @since v.1.0.0
663 */
664 public function get_next_course_content_order_id($topic_ID){
665 global $wpdb;
666
667 $last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$topic_ID};");
668 return $last_order + 1;
669 }
670
671 /**
672 * @param int $topics_id
673 * @param int $limit
674 *
675 * @return \WP_Query
676 *
677 * Get lesson by topic
678 *
679 * @since v.1.0.0
680 */
681 public function get_lessons_by_topic($topics_id = 0, $limit = 10){
682 $topics_id = $this->get_post_id($topics_id);
683
684 $lesson_post_type = tutor()->lesson_post_type;
685 $args = array(
686 'post_type' => $lesson_post_type,
687 'post_parent' => $topics_id,
688 'posts_per_page' => $limit,
689 'orderby' => 'menu_order',
690 'order' => 'ASC',
691 );
692
693 $query = new \WP_Query($args);
694
695 return $query;
696 }
697
698 /**
699 * @param int $topics_id
700 * @param int $limit
701 *
702 * @return \WP_Query
703 *
704 * Get course content by topic
705 *
706 * @since v.1.0.0
707 */
708 public function get_course_contents_by_topic($topics_id = 0, $limit = 10){
709 $topics_id = $this->get_post_id($topics_id);
710
711 $lesson_post_type = tutor()->lesson_post_type;
712 $args = array(
713 'post_type' => array($lesson_post_type, 'tutor_quiz'),
714 'post_parent' => $topics_id,
715 'posts_per_page' => $limit,
716 'orderby' => 'menu_order',
717 'order' => 'ASC',
718 );
719
720 $query = new \WP_Query($args);
721
722 return $query;
723 }
724
725 /**
726 * @param string $request_method
727 *
728 * Check actions nonce
729 *
730 * @since v.1.0.0
731 */
732 public function checking_nonce($request_method = 'post'){
733 if ($request_method === 'post'){
734 if (!isset($_POST[tutor()->nonce]) || !wp_verify_nonce($_POST[tutor()->nonce], tutor()->nonce_action)) {
735 exit();
736 }
737 }else{
738 if (!isset($_GET[tutor()->nonce]) || !wp_verify_nonce($_GET[tutor()->nonce], tutor()->nonce_action)) {
739 exit();
740 }
741 }
742 }
743
744 /**
745 * @param int $course_id
746 *
747 * @return bool
748 *
749 * @since v.1.0.0
750 */
751 public function is_course_purchasable($course_id = 0){
752 return apply_filters('is_course_purchasable', false, $course_id);
753 }
754
755 /**
756 * @param int $course_id
757 *
758 * @return null|string
759 *
760 * get course price in digits format if any
761 *
762 * @since v.1.0.0
763 */
764
765 public function get_course_price($course_id = 0){
766 $course_id = $this->get_post_id($course_id);
767
768 $price = null;
769
770 if ($this->is_course_purchasable()) {
771 if ($this->has_wc()){
772 $product_id = tutor_utils()->get_course_product_id($course_id);
773 $product = wc_get_product( $product_id );
774
775 if ( $product ) {
776 $price = $product->get_price();
777 }
778 }else{
779 $price = apply_filters('get_tutor_course_price', null, $course_id);
780 }
781
782 }
783
784 return $price;
785 }
786
787 /**
788 * @param int $course_id
789 *
790 * @return array|bool|null|object
791 *
792 * Check if current user has been enrolled or not
793 *
794 * @since v.1.0.0
795 */
796
797 public function is_enrolled($course_id = 0, $user_id = 0){
798 $course_id = $this->get_post_id($course_id);
799 $user_id = $this->get_user_id($user_id);
800
801 if (is_user_logged_in()) {
802 global $wpdb;
803
804 $getEnrolledInfo = $wpdb->get_row( "select ID, post_author, post_date,post_date_gmt,post_title from {$wpdb->posts} WHERE post_type = 'tutor_enrolled' AND post_parent = {$course_id} AND post_author = {$user_id} AND post_status = 'completed'; " );
805
806 if ( $getEnrolledInfo ) {
807 return $getEnrolledInfo;
808 }
809 }
810 return false;
811 }
812
813 /**
814 * @param int $course_id
815 * @param int $user_id
816 *
817 * @return array|bool|null|object|void
818 *
819 * Has any enrolled for a user in a course
820 *
821 * @since v.1.0.0
822 */
823 public function has_any_enrolled($course_id = 0, $user_id = 0){
824 $course_id = $this->get_post_id($course_id);
825 $user_id = $this->get_user_id($user_id);
826
827 if (is_user_logged_in()) {
828 global $wpdb;
829
830 $getEnrolledInfo = $wpdb->get_row( "select ID, post_author, post_date,post_date_gmt,post_title from {$wpdb->posts} WHERE post_type = 'tutor_enrolled' AND post_parent = {$course_id} AND post_author = {$user_id}; " );
831
832 if ( $getEnrolledInfo ) {
833 return $getEnrolledInfo;
834 }
835 }
836 return false;
837 }
838
839 /**
840 * @param int $lesson_id
841 * @param int $user_id
842 *
843 * @return array|bool|null|object
844 *
845 * Get the course Enrolled confirmation by lesson ID
846 *
847 * @since v.1.0.0
848 */
849
850 public function is_course_enrolled_by_lesson($lesson_id = 0, $user_id = 0){
851 $lesson_id = $this->get_post_id($lesson_id);
852 $user_id = $this->get_user_id($user_id);
853
854 return $this->is_enrolled($this->get_course_id_by_lesson($lesson_id));
855 }
856
857 /**
858 * @param int $lesson_id
859 *
860 * @return bool|mixed
861 *
862 * Get the course ID by Lesson
863 *
864 * @since v.1.0.0
865 */
866 public function get_course_id_by_lesson($lesson_id = 0){
867 $lesson_id = $this->get_post_id($lesson_id);
868 return get_post_meta($lesson_id, '_tutor_course_id_for_lesson', true);
869 }
870
871 /**
872 * @param int $course_id
873 *
874 * @return bool|false|string
875 *
876 * Get first lesson of a course
877 *
878 * @since v.1.0.0
879 */
880 public function get_course_first_lesson($course_id = 0){
881 $course_id = $this->get_post_id($course_id);
882 global $wpdb;
883
884 $lesson_id = $wpdb->get_var("
885 SELECT post_id as lesson_id
886 FROM $wpdb->postmeta
887 INNER JOIN {$wpdb->posts} ON post_id = {$wpdb->posts}.ID
888 WHERE meta_key = '_tutor_course_id_for_lesson' AND meta_value = {$course_id}
889
890 ORDER BY menu_order ASC LIMIT 1
891 ");
892
893 /*
894 $lesson_id = $wpdb->get_var(" select main_posts.ID from {$wpdb->posts} main_posts
895 WHERE post_parent =
896 (SELECT sub_posts.ID FROM {$wpdb->posts} sub_posts
897 WHERE post_type = 'topics' AND
898 sub_posts.post_parent = {$course_id} ORDER BY sub_posts.menu_order ASC LIMIT 1 )
899 ORDER BY main_posts.menu_order ASC LIMIT 1 ;");
900 */
901
902 if ($lesson_id){
903 return get_permalink($lesson_id);
904 }
905 return false;
906 }
907
908 /**
909 *
910 * Get course sub pages in course dashboard
911 *
912 * @since v.1.0.0
913 */
914 public function course_sub_pages(){
915 $nav_items = array(
916 'overview' => __('Overview', 'tutor'),
917 );
918
919 $enable_q_and_a_on_course = tutor_utils()->get_option('enable_q_and_a_on_course');
920 if ($enable_q_and_a_on_course){
921 $nav_items['questions'] = __('Q&A', 'tutor');
922 }
923 $nav_items['announcements'] = __('Announcements', 'tutor');
924
925 return apply_filters('tutor_course/single/enrolled/nav_items', $nav_items);
926 }
927
928 /**
929 * @param int $post_id
930 *
931 * @return bool|array
932 *
933 * @since v.1.0.0
934 */
935 public function get_video($post_id = 0){
936 $post_id = $this->get_post_id($post_id);
937 $attachments = get_post_meta($post_id, '_video', true);
938 if ($attachments) {
939 $attachments = maybe_unserialize($attachments);
940 }
941 return $attachments;
942 }
943
944 /**
945 * @param int $post_id
946 * @param array $video_data
947 *
948 * @return bool
949 *
950 * Update the video Info
951 */
952 public function update_video($post_id = 0, $video_data = array()){
953 $post_id = $this->get_post_id($post_id);
954
955 if (is_array($video_data) && count($video_data)){
956 update_post_meta($post_id, '_video', $video_data);
957 }
958 }
959
960 /**
961 * @param int $post_id
962 *
963 * @return bool|mixed
964 *
965 * @since v.1.0.0
966 */
967 public function get_attachments($post_id = 0){
968 $post_id = $this->get_post_id($post_id);
969 $attachments_arr = array();
970 $attachments = maybe_unserialize(get_post_meta($post_id, '_tutor_attachments', true));
971
972 $font_icons = apply_filters('tutor_file_types_icon', array(
973 'archive',
974 'audio',
975 'code',
976 'default',
977 'document',
978 'interactive',
979 'spreadsheet',
980 'text',
981 'video',
982 'image',
983 ));
984
985 if ( is_array($attachments) && count($attachments)) {
986 foreach ( $attachments as $attachment ) {
987 $url = wp_get_attachment_url( $attachment );
988 $file_type = wp_check_filetype( $url );
989 $ext = $file_type['ext'];
990 $title = get_the_title($attachment);
991
992 $file_path = get_attached_file( $attachment );
993 $size_bytes = file_exists($file_path) ? filesize( $file_path ) : 0;
994 $size = size_format( $size_bytes, 2 );
995 $type = wp_ext2type( $ext );
996
997 $icon = 'default';
998 if ( $type && in_array( $type, $font_icons ) ) {
999 $icon = $type;
1000 }
1001
1002 $data = array(
1003 'post_id' => $post_id,
1004 'id' => $attachment,
1005 'url' => $url,
1006 'name' => $title . '.' . $ext,
1007 'title' => $title,
1008 'ext' => $ext,
1009 'size' => $size,
1010 'size_bytes' => $size_bytes,
1011 'icon' => $icon,
1012 );
1013
1014 $attachments_arr[] = (object) apply_filters( 'tutor/posts/attachments', $data );
1015 }
1016 }
1017
1018 return $attachments_arr;
1019 }
1020
1021
1022 /**
1023 * @param $seconds
1024 *
1025 * @return string
1026 *
1027 * return seconds to formatted playtime
1028 *
1029 * @since v.1.0.0
1030 */
1031 public function playtime_string($seconds) {
1032 $sign = (($seconds < 0) ? '-' : '');
1033 $seconds = round(abs($seconds));
1034 $H = (int) floor( $seconds / 3600);
1035 $M = (int) floor(($seconds - (3600 * $H) ) / 60);
1036 $S = (int) round( $seconds - (3600 * $H) - (60 * $M) );
1037 return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
1038 }
1039
1040 /**
1041 * @param $seconds
1042 *
1043 * @return array
1044 *
1045 * Get the playtime in array
1046 *
1047 * @since v.1.0.0
1048 */
1049 public function playtime_array($seconds){
1050 $run_time_format = array(
1051 'hours' => '00',
1052 'minutes' => '00',
1053 'seconds' => '00',
1054 );
1055
1056 if ($seconds <= 0 ){
1057 return $run_time_format;
1058 }
1059
1060 $playTimeString = $this->playtime_string($seconds);
1061 $timeInArray = explode(':', $playTimeString);
1062
1063 $run_time_size = count($timeInArray);
1064 if ($run_time_size === 3){
1065 $run_time_format['hours'] = $timeInArray[0];
1066 $run_time_format['minutes'] = $timeInArray[1];
1067 $run_time_format['seconds'] = $timeInArray[2];
1068 }elseif($run_time_size === 2){
1069 $run_time_format['minutes'] = $timeInArray[0];
1070 $run_time_format['seconds'] = $timeInArray[1];
1071 }
1072
1073 return $run_time_format;
1074 }
1075
1076 /**
1077 * @param $seconds
1078 *
1079 * @return string
1080 *
1081 * Convert seconds to human readable time
1082 *
1083 * @since v.1.0.0
1084 */
1085 public function seconds_to_time_context($seconds) {
1086 $sign = (($seconds < 0) ? '-' : '');
1087 $seconds = round(abs($seconds));
1088 $H = (int) floor( $seconds / 3600);
1089 $M = (int) floor(($seconds - (3600 * $H) ) / 60);
1090 $S = (int) round( $seconds - (3600 * $H) - (60 * $M) );
1091
1092 return $sign.($H ? $H.'h ' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).'m '.str_pad($S, 2, 0, STR_PAD_LEFT).'s';
1093 }
1094
1095 /**
1096 * @param int $lesson_id
1097 *
1098 * @return bool|object
1099 *
1100 * @since v.1.0.0
1101 */
1102
1103 public function get_video_info($lesson_id = 0){
1104 $lesson_id = $this->get_post_id($lesson_id);
1105 $video = $this->get_video($lesson_id);
1106
1107 if ( ! $video){
1108 return false;
1109 }
1110
1111 $info = array(
1112 'playtime' => '00:00',
1113 );
1114
1115 $types = apply_filters('tutor_video_types', array("mp4"=>"video/mp4", "webm"=>"video/webm", "ogg"=>"video/ogg"));
1116
1117 $videoSource = $this->avalue_dot('source', $video);
1118 if ($videoSource === 'html5'){
1119 $sourceVideoID = $this->avalue_dot('source_video_id', $video);
1120 $video_info = get_post_meta($sourceVideoID, '_wp_attachment_metadata', true);
1121
1122 if ($video_info){
1123 $path = get_attached_file($sourceVideoID);
1124 $info['playtime'] = $video_info['length_formatted'];
1125 $info['path'] = $path;
1126 $info['url'] = wp_get_attachment_url($sourceVideoID);
1127 $info['ext'] = strtolower(pathinfo($path, PATHINFO_EXTENSION));
1128 $info['type'] = $types[$info['ext']];
1129 }
1130 }
1131
1132 if ($videoSource !== 'html5'){
1133 $video = maybe_unserialize(get_post_meta($lesson_id, '_video', true));
1134
1135 $runtimeHours = tutor_utils()->avalue_dot('runtime.hours', $video);
1136 $runtimeMinutes = tutor_utils()->avalue_dot('runtime.minutes', $video);
1137 $runtimeSeconds = tutor_utils()->avalue_dot('runtime.seconds', $video);
1138
1139 $runtimeHours = $runtimeHours ? $runtimeHours : '00';
1140 $runtimeMinutes = $runtimeMinutes ? $runtimeMinutes : '00';
1141 $runtimeSeconds = $runtimeSeconds ? $runtimeSeconds : '00';
1142
1143 $info['playtime'] = "$runtimeHours:$runtimeMinutes:$runtimeSeconds";
1144 }
1145
1146 $info = array_merge($info, $video);
1147
1148 return (object) $info;
1149 }
1150
1151 /**
1152 * @param int $post_id
1153 *
1154 * @return bool
1155 *
1156 * Ensure if attached video is self hosted or not
1157 *
1158 * @since v.1.0.0
1159 */
1160 public function is_html5_video($post_id = 0){
1161 $post_id = $this->get_post_id($post_id);
1162
1163 $video = $this->get_video($post_id);
1164 if ( ! $video){
1165 return false;
1166 }
1167 $videoSource = $this->avalue_dot('source', $video);
1168 return $videoSource === 'html5';
1169 }
1170
1171 /**
1172 *
1173 * return lesson type icon
1174 *
1175 * @param int $lesson_id
1176 * @param bool $html
1177 * @param bool $echo
1178 *
1179 * @return string
1180 *
1181 * @since v.1.0.0
1182 */
1183
1184 public function get_lesson_type_icon($lesson_id = 0, $html = false, $echo = false){
1185 $post_id = $this->get_post_id($lesson_id);
1186 $video = tutor_utils()->get_video_info($post_id);
1187
1188 $play_time = false;
1189 if ($video){
1190 $play_time = $video->playtime;
1191 }
1192
1193 $tutor_lesson_type_icon = $play_time ? 'youtube' : 'document';
1194
1195 if ($html){
1196 $tutor_lesson_type_icon = "<i class='tutor-icon-$tutor_lesson_type_icon'></i> ";
1197 }
1198
1199 if ($tutor_lesson_type_icon){
1200 echo $tutor_lesson_type_icon;
1201 }
1202
1203 return $tutor_lesson_type_icon;
1204 }
1205
1206 /**
1207 * @param int $lesson_id
1208 * @param int $user_id
1209 *
1210 * @return bool|mixed
1211 *
1212 * @since v.1.0.0
1213 */
1214
1215 public function is_completed_lesson($lesson_id = 0, $user_id = 0){
1216 $lesson_id = $this->get_post_id($lesson_id);
1217 $user_id = $this->get_user_id($user_id);
1218
1219 $is_completed = get_user_meta($user_id, '_tutor_completed_lesson_id_'.$lesson_id, true);
1220
1221 if ($is_completed){
1222 return $is_completed;
1223 }
1224
1225 return false;
1226 }
1227
1228 /**
1229 * @param int $course_id
1230 * @param int $user_id
1231 *
1232 * @return array|bool|null|object|void
1233 *
1234 * Determine if a course completed
1235 *
1236 * @since v.1.0.0
1237 */
1238
1239 public function is_completed_course($course_id = 0, $user_id = 0){
1240 global $wpdb;
1241 $course_id = $this->get_post_id($course_id);
1242 $user_id = $this->get_user_id($user_id);
1243
1244 $is_completed = $wpdb->get_row("SELECT comment_ID,
1245 comment_post_ID as course_id,
1246 comment_author as completed_user_id,
1247 comment_date as completion_date,
1248 comment_content as completed_hash
1249 from {$wpdb->comments}
1250 WHERE comment_agent = 'TutorLMSPlugin'
1251 AND comment_type = 'course_completed'
1252 AND comment_post_ID = {$course_id}
1253 AND user_id = {$user_id} ;");
1254
1255 if ($is_completed){
1256 return $is_completed;
1257 }
1258
1259 return false;
1260 }
1261
1262 /**
1263 * @param array $input
1264 *
1265 * @return array
1266 *
1267 * Sanitize input array
1268 *
1269 * @since v.1.0.0
1270 */
1271 public function sanitize_array($input = array()){
1272 $array = array();
1273
1274 if (is_array($input) && count($input)){
1275 foreach ($input as $key => $value){
1276 if (is_array($value)){
1277 $array[$key] = $this->sanitize_array($value);
1278 }else{
1279 $key = sanitize_text_field($key);
1280 $value = sanitize_text_field($value);
1281 $array[$key] = $value;
1282 }
1283 }
1284 }
1285
1286 return $array;
1287 }
1288
1289 /**
1290 * @param int $post_id
1291 *
1292 * @return array|bool
1293 *
1294 * Determine if has any video in single
1295 *
1296 * @since v.1.0.0
1297 */
1298
1299 public function has_video_in_single($post_id = 0){
1300 if (is_single()) {
1301 $post_id = $this->get_post_id($post_id);
1302
1303 $video = $this->get_video( $post_id );
1304 if ( $video ) {
1305 return $video;
1306 }
1307 }
1308 return false;
1309
1310 }
1311
1312 /**
1313 * @param int $start
1314 * @param int $limit
1315 * @param string $search_term
1316 * @param int $course_id
1317 *
1318 * @return array|null|object
1319 *
1320 *
1321 * Get the enrolled students for all courses.
1322 *
1323 * Pass course id in 4th parameter to get students course wise.
1324 *
1325 * @since v.1.0.0
1326 */
1327 public function get_students($start = 0, $limit = 10, $search_term = ''){
1328 $meta_key = '_is_tutor_student';
1329
1330 global $wpdb;
1331
1332 if ($search_term){
1333 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
1334 }
1335
1336 $students = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
1337 INNER JOIN {$wpdb->usermeta}
1338 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
1339 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
1340 ORDER BY {$wpdb->usermeta}.meta_value DESC
1341 LIMIT {$start}, {$limit} ");
1342
1343 return $students;
1344 }
1345
1346 /**
1347 * @return int
1348 *
1349 * @since v.1.0.0
1350 *
1351 * get the total students
1352 * pass course id to get course wise total students
1353 *
1354 * @since v.1.0.0
1355 */
1356 public function get_total_students($search_term = ''){
1357 $meta_key = '_is_tutor_student';
1358
1359 global $wpdb;
1360
1361 if ($search_term){
1362 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
1363 }
1364
1365 $count = $wpdb->get_var("SELECT COUNT({$wpdb->users}.ID) FROM {$wpdb->users} INNER JOIN {$wpdb->usermeta} ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id ) WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) $search_term ");
1366
1367 return (int) $count;
1368 }
1369
1370 /**
1371 * @param int $user_id
1372 *
1373 * @return array
1374 *
1375 * Get complete courses ids by user
1376 *
1377 * @since v.1.0.0
1378 */
1379 public function get_completed_courses_ids_by_user($user_id = 0){
1380 global $wpdb;
1381
1382 $user_id = $this->get_user_id($user_id);
1383
1384 $course_ids = (array) $wpdb->get_col("SELECT comment_post_ID as course_id
1385 from {$wpdb->comments}
1386 WHERE comment_agent = 'TutorLMSPlugin'
1387 AND comment_type = 'course_completed'
1388 AND user_id = {$user_id} ;");
1389
1390 return $course_ids;
1391 }
1392
1393 /**
1394 * @param int $user_id
1395 *
1396 * @return bool|\WP_Query
1397 *
1398 * Return courses by user_id
1399 *
1400 * @since v.1.0.0
1401 */
1402 public function get_courses_by_user($user_id = 0){
1403 $user_id = $this->get_user_id($user_id);
1404 $course_ids = $this->get_completed_courses_ids_by_user($user_id);
1405
1406 if (count($course_ids)){
1407 $course_post_type = tutor()->course_post_type;
1408 $course_args = array(
1409 'post_type' => $course_post_type,
1410 'post_status' => 'publish',
1411 'post__in' => $course_ids,
1412 );
1413
1414 return new \WP_Query($course_args);
1415 }
1416
1417 return false;
1418 }
1419
1420 /**
1421 * @param int $user_id
1422 *
1423 * @return bool|\WP_Query
1424 *
1425 * Get the active course by user
1426 *
1427 * @since v.1.0.0
1428 */
1429
1430 public function get_active_courses_by_user($user_id = 0){
1431 $user_id = $this->get_user_id($user_id);
1432
1433 $course_ids = $this->get_completed_courses_ids_by_user($user_id);
1434 $enrolled_course_ids = $this->get_enrolled_courses_ids_by_user($user_id);
1435 $active_courses = array_diff($enrolled_course_ids, $course_ids);
1436
1437 if (count($active_courses)){
1438 $course_post_type = tutor()->course_post_type;
1439 $course_args = array(
1440 'post_type' => $course_post_type,
1441 'post_status' => 'publish',
1442 'post__in' => $active_courses,
1443 );
1444
1445 return new \WP_Query($course_args);
1446 }
1447
1448 return false;
1449 }
1450
1451 /**
1452 * @param int $user_id
1453 *
1454 * @return array
1455 *
1456 * Get enrolled course ids by a user
1457 *
1458 * @since v.1.0.0
1459 */
1460
1461 public function get_enrolled_courses_ids_by_user($user_id = 0){
1462 global $wpdb;
1463 $user_id = $this->get_user_id($user_id);
1464 $course_ids = $wpdb->get_col("select post_parent from {$wpdb->posts} WHERE post_type = 'tutor_enrolled' AND post_author = {$user_id} AND post_status = 'completed'; ");
1465
1466 return $course_ids;
1467 }
1468
1469 /**
1470 * @param int $course_id
1471 *
1472 * @return int
1473 *
1474 * Get the total enrolled users at course
1475 */
1476 public function count_enrolled_users_by_course($course_id = 0){
1477 global $wpdb;
1478 $course_id = $this->get_post_id($course_id);
1479
1480 $course_ids = $wpdb->get_var("select COUNT(ID) from {$wpdb->posts} WHERE post_type = 'tutor_enrolled' AND post_parent = {$course_id} AND post_status = 'completed'; ");
1481
1482 return (int) $course_ids;
1483 }
1484
1485 /**
1486 * @param int $user_id
1487 *
1488 * @return bool|\WP_Query
1489 *
1490 * Get the enrolled courses by user
1491 */
1492 public function get_enrolled_courses_by_user($user_id = 0){
1493 global $wpdb;
1494
1495 $user_id = $this->get_user_id($user_id);
1496 $course_ids = $this->get_enrolled_courses_ids_by_user($user_id);
1497
1498 if (count($course_ids)){
1499 $course_post_type = tutor()->course_post_type;
1500 $course_args = array(
1501 'post_type' => $course_post_type,
1502 'post_status' => 'publish',
1503 'post__in' => $course_ids,
1504 );
1505 return new \WP_Query($course_args);
1506 }
1507 return false;
1508 }
1509
1510
1511 /**
1512 * @param int $post_id
1513 *
1514 * @return string
1515 *
1516 * Get the video streaming URL by post/lesson/course ID
1517 */
1518 public function get_video_stream_url($post_id = 0){
1519 $post_id = $this->get_post_id($post_id);
1520 $post = get_post($post_id);
1521
1522 if ($post->post_type === tutor()->lesson_post_type ){
1523 $video_url = trailingslashit(home_url()).'video-url/'.$post->post_name;
1524 }else{
1525 $video_info = tutor_utils()->get_video_info($post_id);
1526 $video_url = $video_info->url;
1527 }
1528
1529 return $video_url;
1530 }
1531
1532 /**
1533 * @param int $lesson_id
1534 * @param int $user_id
1535 *
1536 * @return array|bool|mixed
1537 *
1538 * Get student lesson reading current info
1539 *
1540 * @since v.1.0.0
1541 */
1542 public function get_lesson_reading_info_full($lesson_id = 0, $user_id = 0){
1543 $lesson_id = $this->get_post_id($lesson_id);
1544 $user_id = $this->get_user_id($user_id);
1545
1546 $lesson_info = (array) maybe_unserialize(get_user_meta($user_id, '_lesson_reading_info', true));
1547 return $this->avalue_dot($lesson_id, $lesson_info);
1548 }
1549
1550 /**
1551 * @param int $post_id
1552 *
1553 * @return bool|false|int
1554 *
1555 * Get current post id or given post id
1556 *
1557 * @since v.1.0.0
1558 */
1559 public function get_post_id($post_id = 0){
1560 if ( ! $post_id){
1561 $post_id = get_the_ID();
1562 if ( ! $post_id){
1563 return false;
1564 }
1565 }
1566
1567 return $post_id;
1568 }
1569
1570 /**
1571 * @param int $user_id
1572 *
1573 * @return bool|int
1574 *
1575 * Get current user or given user ID
1576 *
1577 * @since v.1.0.0
1578 */
1579 public function get_user_id($user_id = 0){
1580 if ( ! $user_id){
1581 $user_id = get_current_user_id();
1582 if ( ! $user_id){
1583 return false;
1584 }
1585 }
1586
1587 return $user_id;
1588 }
1589
1590 /**
1591 * @param int $lesson_id
1592 * @param int $user_id
1593 * @param string $key
1594 *
1595 * @return array|bool|mixed
1596 *
1597 * Get lesson reading info by key
1598 *
1599 * @since v.1.0.0
1600 */
1601
1602 public function get_lesson_reading_info($lesson_id = 0, $user_id = 0, $key = ''){
1603 $lesson_id = $this->get_post_id($lesson_id);
1604 $user_id = $this->get_user_id($user_id);
1605
1606 $lesson_info = $this->get_lesson_reading_info_full($lesson_id, $user_id);
1607
1608 return $this->avalue_dot($key, $lesson_info);
1609 }
1610
1611 /**
1612 * @param int $lesson_id
1613 * @param int $user_id
1614 * @param array $data
1615 *
1616 * @return bool
1617 *
1618 * Update student lesson reading info
1619 *
1620 * @since v.1.0.0
1621 */
1622 public function update_lesson_reading_info($lesson_id = 0, $user_id = 0, $key = '', $value = ''){
1623 $lesson_id = $this->get_post_id($lesson_id);
1624 $user_id = $this->get_user_id($user_id);
1625
1626 if ($key && $value){
1627 $lesson_info = (array) maybe_unserialize(get_user_meta($user_id, '_lesson_reading_info', true));
1628 $lesson_info[$lesson_id][$key] = $value;
1629 update_user_meta($user_id, '_lesson_reading_info', $lesson_info);
1630 }
1631 }
1632
1633 /**
1634 * @param string $url
1635 *
1636 * @return bool
1637 *
1638 * Get the Youtube Video ID from URL
1639 *
1640 * @since v.1.0.0
1641 */
1642 public function get_youtube_video_id($url = ''){
1643 if (!$url){
1644 return false;
1645 }
1646 preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
1647
1648 if (isset($match[1])) {
1649 $youtube_id = $match[1];
1650 return $youtube_id;
1651 }
1652
1653 return false;
1654 }
1655
1656 /**
1657 * @param string $url
1658 *
1659 * @return bool
1660 *
1661 * Get the vimeo video id from URL
1662 *
1663 * @since v.1.0.0
1664 */
1665 public function get_vimeo_video_id($url = ''){
1666 if (preg_match('%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(?:[?]?.*)$%im', $url, $match)) {
1667 if (isset($match[3])){
1668 return $match[3];
1669 }
1670 }
1671 return false;
1672 }
1673
1674 /**
1675 * @param int $post_id
1676 *
1677 * Mark lesson complete
1678 *
1679 * @since v.1.0.0
1680 */
1681 public function mark_lesson_complete($post_id = 0, $user_id = 0){
1682 $post_id = $this->get_post_id($post_id);
1683 $user_id = $this->get_user_id($user_id);
1684 update_user_meta($user_id, '_tutor_completed_lesson_id_'.$post_id, time());
1685 }
1686
1687 /**
1688 * Saving enroll information to posts table
1689 * post_author = enrolled_student_id (wp_users id)
1690 * post_parent = enrolled course id
1691 *
1692 * @type: call when need
1693 * @return bool;
1694 *
1695 * @since v.1.0.0
1696 */
1697 public function do_enroll($course_id = 0, $order_id = 0){
1698 if ( ! $course_id){
1699 return false;
1700 }
1701
1702 do_action('tutor_before_enroll', $course_id);
1703 $user_id = get_current_user_id();
1704 $title = __('Course Enrolled', 'tutor')." &ndash; ".date_i18n(get_option('date_format')) .' @ '.date_i18n(get_option('time_format') ) ;
1705
1706 $enrolment_status = 'completed';
1707
1708 if ($this->is_course_purchasable($course_id)) {
1709 /**
1710 * We need to verify this enrollment, we will change the status later after payment confirmation
1711 */
1712 $enrolment_status = 'pending';
1713 }
1714
1715 $enroll_data = apply_filters('tutor_enroll_data',
1716 array(
1717 'post_type' => 'tutor_enrolled',
1718 'post_title' => $title,
1719 'post_status' => $enrolment_status,
1720 'post_author' => $user_id,
1721 'post_parent' => $course_id,
1722 )
1723 );
1724
1725 // Insert the post into the database
1726 $isEnrolled = wp_insert_post( $enroll_data );
1727 if ($isEnrolled) {
1728 do_action('tutor_after_enroll', $course_id, $isEnrolled);
1729
1730 //Mark Current User as Students with user meta data
1731 update_user_meta( $user_id, '_is_tutor_student', time() );
1732
1733 if ($order_id) {
1734 //Mark order for course and user
1735 $product_id = $this->get_course_product_id($course_id);
1736 update_post_meta( $isEnrolled, '_tutor_enrolled_by_order_id', $order_id );
1737 update_post_meta( $isEnrolled, '_tutor_enrolled_by_product_id', $product_id );
1738 update_post_meta( $order_id, '_is_tutor_order_for_course', time() );
1739 update_post_meta( $order_id, '_tutor_order_for_course_id_'.$course_id, $isEnrolled );
1740 }
1741 return true;
1742 }
1743
1744 return false;
1745 }
1746
1747 /**
1748 * @param $order_id
1749 *
1750 * Complete course enrollment and do some task
1751 *
1752 * @since v.1.0.0
1753 */
1754 public function complete_course_enroll($order_id){
1755 if ( ! tutor_utils()->is_tutor_order($order_id)){
1756 return;
1757 }
1758
1759 global $wpdb;
1760
1761 $enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id($order_id);
1762 if ($enrolled_ids_with_course){
1763 $enrolled_ids = wp_list_pluck($enrolled_ids_with_course, 'enrolled_id');
1764
1765 if (is_array($enrolled_ids) && count($enrolled_ids)){
1766 foreach ($enrolled_ids as $enrolled_id){
1767 $wpdb->update( $wpdb->posts, array( 'post_status' => 'completed' ), array( 'ID' => $enrolled_id ) );
1768 }
1769 }
1770 }
1771 }
1772
1773 /**
1774 * @param $order_id
1775 *
1776 * @return array|bool
1777 *
1778 * @since v.1.0.0
1779 */
1780 public function get_course_enrolled_ids_by_order_id($order_id){
1781 global $wpdb;
1782 //Getting all of courses ids within this order
1783
1784 $courses_ids = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE post_id = {$order_id} AND meta_key LIKE '_tutor_order_for_course_id_%' ");
1785
1786 if (is_array($courses_ids) && count($courses_ids)){
1787 $course_enrolled_by_order = array();
1788 foreach ($courses_ids as $courses_id){
1789 $course_id = str_replace('_tutor_order_for_course_id_', '',$courses_id->meta_key);
1790 //array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id))
1791 $course_enrolled_by_order[$courses_id->post_id] = array('course_id' => $course_id, 'enrolled_id' => $courses_id->meta_value);
1792 }
1793 return $course_enrolled_by_order;
1794 }
1795 return false;
1796 }
1797
1798 /**
1799 * Get wc product in efficient query
1800 *
1801 * @since v.1.0.0
1802 */
1803
1804 /**
1805 * @return array|null|object
1806 *
1807 * WooCommerce specific utils
1808 */
1809 public function get_wc_products_db(){
1810 global $wpdb;
1811 $query = $wpdb->get_results("SELECT ID, post_title from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'product' ");
1812
1813 return $query;
1814 }
1815
1816 /**
1817 * @param int $course_id
1818 *
1819 * @return int
1820 *
1821 * Get course productID
1822 *
1823 * @since v.1.0.0
1824 */
1825 public function get_course_product_id($course_id = 0){
1826 $course_id = $this->get_post_id($course_id);
1827 return (int) get_post_meta($course_id, '_tutor_course_product_id', true);
1828 }
1829
1830 /**
1831 * @param int $product_id
1832 *
1833 * @return array|null|object|void
1834 *
1835 * Get Product belongs with course
1836 *
1837 * @since v.1.0.0
1838 */
1839
1840 public function product_belongs_with_course($product_id = 0){
1841 global $wpdb;
1842
1843 $query = $wpdb->get_row("select * from {$wpdb->postmeta} WHERE meta_key='_tutor_course_product_id' AND meta_value = {$product_id} limit 1 ");
1844 return $query;
1845 }
1846
1847 /**
1848 * #End WooCommerce specific utils
1849 *
1850 * @since v.1.0.0
1851 */
1852
1853 public function get_enrolled_statuses(){
1854 return array (
1855 'pending',
1856 'processing',
1857 'on-hold',
1858 'completed',
1859 'cancelled',
1860 'refunded',
1861 'failed',
1862 );
1863 }
1864
1865 /**
1866 * @param $order_id
1867 *
1868 * @return mixed
1869 *
1870 * determine is this a tutor order
1871 *
1872 * @since v.1.0.0
1873 */
1874 public function is_tutor_order($order_id){
1875 return get_post_meta($order_id, '_is_tutor_order_for_course', true);
1876 }
1877
1878 /**
1879 * @return mixed
1880 *
1881 * Tutor Dashboard Pages
1882 *
1883 * @since v.1.0.0
1884 */
1885
1886 public function tutor_student_dashboard_pages(){
1887 $nav_items = array(
1888 'index' => __('Home', 'tutor'),
1889 'my-courses' => __('My Courses', 'tutor'),
1890 'active-courses' => __('Active Courses', 'tutor'),
1891 'completed-courses' => __('Completed Courses', 'tutor'),
1892 'wishlist' => __('WishList', 'tutor'),
1893 );
1894
1895 return apply_filters('tutor_dashboard/student/pages', $nav_items);
1896 }
1897
1898 /**
1899 * @param string $page_key
1900 * @param int $page_id
1901 *
1902 * @return string
1903 *
1904 * Get tutor dashboard page single URL
1905 *
1906 * @since v.1.0.0
1907 */
1908 public function get_tutor_dashboard_page_permalink($page_key = '', $page_id = 0){
1909 if ($page_key === 'index'){
1910 $page_key = '';
1911 }
1912 $page_id = $this->get_post_id($page_id);
1913 return trailingslashit(get_permalink($page_id)).$page_key;
1914 }
1915
1916 /**
1917 * @param string $input
1918 *
1919 * @return array|bool|mixed|string
1920 *
1921 * Get old input
1922 *
1923 * @since v.1.0.0
1924 */
1925 public function input_old($input = ''){
1926 $value = $this->avalue_dot($input, $_REQUEST);
1927 if ($value){
1928 return $value;
1929 }
1930 return '';
1931 }
1932
1933 /**
1934 * @param int $user_id
1935 *
1936 * @return mixed
1937 *
1938 * Determine if is instructor or not
1939 *
1940 * @since v.1.0.0
1941 */
1942 public function is_instructor($user_id = 0){
1943 $user_id = $this->get_user_id($user_id);
1944 return get_user_meta($user_id, '_is_tutor_instructor', true);
1945 }
1946
1947 /**
1948 * @param int $user_id
1949 * @param bool $status_name
1950 *
1951 * @return bool|mixed
1952 *
1953 * Instructor status
1954 *
1955 * @since v.1.0.0
1956 */
1957 public function instructor_status($user_id = 0, $status_name = true){
1958 $user_id = $this->get_user_id($user_id);
1959
1960 $instructor_status = apply_filters('tutor_instructor_statuses', array(
1961 'pending' => __('Pending', 'tutor'),
1962 'approved' => __('Approved', 'tutor'),
1963 'blocked' => __('Blocked', 'tutor'),
1964 ));
1965
1966 $status = get_user_meta($user_id, '_tutor_instructor_status', true);
1967
1968 if (isset($instructor_status[$status])){
1969 if ( ! $status_name){
1970 return $status;
1971 }
1972 return $instructor_status[$status];
1973 }
1974 return false;
1975 }
1976
1977 /**
1978 * @param string $search_term
1979 *
1980 * @return int
1981 *
1982 * Get total number of instructors
1983 *
1984 * @since v.1.0.0
1985 */
1986
1987 public function get_total_instructors($search_term = ''){
1988 $meta_key = '_is_tutor_instructor';
1989
1990 global $wpdb;
1991
1992 if ($search_term){
1993 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
1994 }
1995
1996 $count = $wpdb->get_var("SELECT COUNT({$wpdb->users}.ID) FROM {$wpdb->users} INNER JOIN {$wpdb->usermeta} ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id ) WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) $search_term ");
1997
1998 return (int) $count;
1999 }
2000
2001 /**
2002 * @param int $start
2003 * @param int $limit
2004 * @param string $search_term
2005 *
2006 * @return array|null|object
2007 *
2008 * Get all instructors
2009 *
2010 * @since v.1.0.0
2011 */
2012 public function get_instructors($start = 0, $limit = 10, $search_term = ''){
2013 $meta_key = '_is_tutor_instructor';
2014 global $wpdb;
2015
2016 if ($search_term){
2017 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2018 }
2019
2020 $instructors = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
2021 INNER JOIN {$wpdb->usermeta}
2022 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
2023 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
2024 ORDER BY {$wpdb->usermeta}.meta_value DESC
2025 LIMIT {$start}, {$limit} ");
2026
2027 return $instructors;
2028 }
2029
2030 /**
2031 * @param int $course_id
2032 *
2033 * @return array|bool|null|object
2034 *
2035 * Get all instructors by course
2036 *
2037 * @since v.1.0.0
2038 */
2039 public function get_instructors_by_course($course_id = 0){
2040 global $wpdb;
2041 $course_id = $this->get_post_id($course_id);
2042
2043 $instructors = $wpdb->get_results("select ID, display_name,
2044 get_course.meta_value as taught_course_id,
2045 tutor_job_title.meta_value as tutor_profile_job_title,
2046 tutor_bio.meta_value as tutor_profile_bio,
2047 tutor_photo.meta_value as tutor_profile_photo
2048 from {$wpdb->users}
2049 INNER JOIN {$wpdb->usermeta} get_course ON ID = get_course.user_id AND get_course.meta_key = '_tutor_instructor_course_id' AND get_course.meta_value = {$course_id}
2050 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2051 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2052 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2053 ");
2054
2055 if (is_array($instructors) && count($instructors)){
2056 return $instructors;
2057 }
2058
2059 return false;
2060 }
2061
2062 /**
2063 * @param $instructor_id
2064 *
2065 * Get total Students by instructor
2066 * 1 enrollment = 1 student, so total enrolled for a equivalent total students (Tricks)
2067 *
2068 * @return int
2069 *
2070 * @since v.1.0.0
2071 */
2072
2073 public function get_total_students_by_instructor($instructor_id){
2074 global $wpdb;
2075
2076 $course_post_type = tutor()->course_post_type;
2077 $count = $wpdb->get_var("SELECT COUNT(courses.ID) from {$wpdb->posts} courses
2078
2079 INNER JOIN {$wpdb->posts} enrolled ON courses.ID = enrolled.post_parent AND enrolled.post_type = 'tutor_enrolled'
2080 WHERE courses.post_status = 'publish'
2081 AND courses.post_type = '{$course_post_type}'
2082 AND courses.post_author = {$instructor_id} ; ");
2083 return (int) $count;
2084 }
2085
2086 /**
2087 * @param float $input
2088 *
2089 * @return float|string
2090 *
2091 * Get rating format from value
2092 *
2093 * @since v.1.0.0
2094 */
2095 public function get_rating_value($input = 0.00){
2096
2097 if ( $input > 0){
2098 $input = number_format($input, 2);
2099 $int_value = (int) $input;
2100 $fraction = $input - $int_value;
2101
2102 if ($fraction == 0){
2103 $fraction = 0.00;
2104 }elseif($fraction > 0.5){
2105 $fraction = 1;
2106 }else{
2107 $fraction = 0.5;
2108 }
2109
2110 return number_format( ($int_value + $fraction), 2);
2111 }
2112 return 0.00;
2113 }
2114
2115 /**
2116 * @param float $current_rating
2117 * @param bool $echo
2118 *
2119 * @return string
2120 *
2121 * Generate star rating based in given rating value
2122 *
2123 * @since v.1.0.0
2124 */
2125 public function star_rating_generator($current_rating = 0.00, $echo = true){
2126 $output = '';
2127
2128 for ($i = 1; $i <=5 ; $i++){
2129 $intRating = (int) $current_rating;
2130
2131 if ($intRating >= $i){
2132 $output.= '<i class="tutor-icon-star-full" data-rating-value="'.$i.'"></i>';
2133 } else{
2134 if ( ($current_rating - $i) == -0.5){
2135 $output.= '<i class="tutor-icon-star-half" data-rating-value="'.$i.'"></i>';
2136 }else{
2137 $output.= '<i class="tutor-icon-star-line" data-rating-value="'.$i.'"></i>';
2138 }
2139 }
2140 }
2141
2142 if ($echo){
2143 echo $output;
2144 }
2145 return $output;
2146 }
2147
2148 /**
2149 * @param null $name
2150 *
2151 * @return string
2152 *
2153 * Generate text to avatar
2154 *
2155 * @since v.1.0.0
2156 */
2157 public function get_tutor_avatar($user_id = null, $size = 'thumbnail'){
2158 global $wpdb;
2159
2160 if ( ! $user_id){
2161 return '';
2162 }
2163
2164 $user = $this->get_tutor_user($user_id);
2165 if ($user->tutor_profile_photo){
2166 return '<img src="'.wp_get_attachment_image_url($user->tutor_profile_photo, $size).'" class="tutor-image-avatar" alt="" /> ';
2167 }
2168
2169 $name = $user->display_name;
2170 $arr = explode(' ', trim($name));
2171
2172 if (count($arr) > 1){
2173 $first_char = substr($arr[0], 0, 1) ;
2174 $second_char = substr($arr[1], 0, 1) ;
2175 }else{
2176 $first_char = substr($arr[0], 0, 1) ;
2177 $second_char = substr($arr[0], 1, 1) ;
2178 }
2179
2180 $initial_avatar = strtoupper($first_char.$second_char);
2181
2182 $bg_color = '#'.substr(md5($initial_avatar), 0, 6);
2183 $initial_avatar = "<span class='tutor-text-avatar' style='background-color: {$bg_color}; color: #fff8e5'>{$initial_avatar}</span>";
2184
2185 return $initial_avatar;
2186 }
2187
2188 /**
2189 * @param $user_id
2190 *
2191 * @return array|null|object|void
2192 *
2193 * Get tutor user
2194 *
2195 * @since v.1.0.0
2196 */
2197
2198 public function get_tutor_user($user_id){
2199 global $wpdb;
2200
2201 $user = $wpdb->get_row("select ID, display_name,
2202 tutor_job_title.meta_value as tutor_profile_job_title,
2203 tutor_bio.meta_value as tutor_profile_bio,
2204 tutor_photo.meta_value as tutor_profile_photo
2205
2206 from {$wpdb->users}
2207 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2208 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2209 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2210
2211 WHERE ID = {$user_id} ");
2212 return $user;
2213 }
2214
2215 /**
2216 * @param int $course_id
2217 * @param int $offset
2218 * @param int $limit
2219 *
2220 * @return array|null|object
2221 *
2222 * get course reviews
2223 *
2224 * @since v.1.0.0
2225 */
2226 public function get_course_reviews($course_id = 0, $offset = 0, $limit = 150){
2227 $course_id = $this->get_post_id($course_id);
2228 global $wpdb;
2229
2230 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2231 {$wpdb->comments}.comment_post_ID,
2232 {$wpdb->comments}.comment_author,
2233 {$wpdb->comments}.comment_author_email,
2234 {$wpdb->comments}.comment_date,
2235 {$wpdb->comments}.comment_content,
2236 {$wpdb->comments}.user_id,
2237 {$wpdb->commentmeta}.meta_value as rating,
2238 {$wpdb->users}.display_name
2239
2240 from {$wpdb->comments}
2241 INNER JOIN {$wpdb->commentmeta}
2242 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2243 INNER JOIN {$wpdb->users}
2244 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2245 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2246 AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2247 );
2248
2249 return $reviews;
2250 }
2251
2252 /**
2253 * @param int $course_id
2254 *
2255 * @return object
2256 *
2257 * Get course rating
2258 *
2259 * @since v.1.0.0
2260 */
2261 public function get_course_rating($course_id = 0){
2262 $course_id = $this->get_post_id($course_id);
2263
2264 $ratings = array(
2265 'rating_count' => 0,
2266 'rating_sum' => 0,
2267 'rating_avg' => 0.00,
2268 );
2269
2270 global $wpdb;
2271
2272 $rating = $wpdb->get_row("select COUNT(meta_value) as rating_count, SUM(meta_value) as rating_sum from {$wpdb->comments}
2273 INNER JOIN {$wpdb->commentmeta}
2274 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2275 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2276 AND meta_key = 'tutor_rating' ;"
2277 );
2278
2279 if ($rating->rating_count){
2280 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2281
2282 $ratings = array(
2283 'rating_count' => $rating->rating_count,
2284 'rating_sum' => $rating->rating_sum,
2285 'rating_avg' => $avg_rating,
2286 );
2287 }
2288
2289 return (object) $ratings;
2290 }
2291
2292 /**
2293 * @param int $user_id
2294 * @param int $offset
2295 * @param int $limit
2296 *
2297 * @return array|null|object
2298 *
2299 * Get reviews by a user
2300 *
2301 * @since v.1.0.0
2302 */
2303 public function get_reviews_by_user($user_id = 0, $offset = 0, $limit = 150){
2304 $user_id = $this->get_user_id($user_id);
2305 global $wpdb;
2306
2307 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2308 {$wpdb->comments}.comment_post_ID,
2309 {$wpdb->comments}.comment_author,
2310 {$wpdb->comments}.comment_author_email,
2311 {$wpdb->comments}.comment_date,
2312 {$wpdb->comments}.comment_content,
2313 {$wpdb->comments}.user_id,
2314 {$wpdb->commentmeta}.meta_value as rating,
2315 {$wpdb->users}.display_name
2316
2317 from {$wpdb->comments}
2318 INNER JOIN {$wpdb->commentmeta}
2319 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2320 INNER JOIN {$wpdb->users}
2321 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2322 WHERE {$wpdb->comments}.user_id = {$user_id}
2323 AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2324 );
2325
2326 return $reviews;
2327 }
2328
2329 /**
2330 * @param $instructor_id
2331 *
2332 * @return object
2333 *
2334 * Get instructors rating
2335 *
2336 * @since v.1.0.0
2337 */
2338 public function get_instructor_ratings($instructor_id){
2339 global $wpdb;
2340
2341 $ratings = array(
2342 'rating_count' => 0,
2343 'rating_sum' => 0,
2344 'rating_avg' => 0.00,
2345 );
2346
2347 $rating = $wpdb->get_row("SELECT COUNT(rating.meta_value) as rating_count, SUM(rating.meta_value) as rating_sum
2348 FROM {$wpdb->usermeta} courses
2349 INNER JOIN {$wpdb->comments} reviews ON courses.meta_value = reviews.comment_post_ID AND reviews.comment_type = 'tutor_course_rating'
2350 INNER JOIN {$wpdb->commentmeta} rating ON reviews.comment_ID = rating.comment_id AND rating.meta_key = 'tutor_rating'
2351 WHERE courses.user_id = {$instructor_id} AND courses.meta_key = '_tutor_instructor_course_id'");
2352
2353 if ($rating->rating_count){
2354 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2355
2356 $ratings = array(
2357 'rating_count' => $rating->rating_count,
2358 'rating_sum' => $rating->rating_sum,
2359 'rating_avg' => $avg_rating,
2360 );
2361 }
2362
2363 return (object) $ratings;
2364 }
2365
2366 /**
2367 * @param int $course_id
2368 * @param int $user_id
2369 *
2370 * @return object
2371 *
2372 * Get course rating by user
2373 *
2374 * @since v.1.0.0
2375 */
2376 public function get_course_rating_by_user($course_id = 0, $user_id = 0){
2377 $course_id = $this->get_post_id($course_id);
2378 $user_id = $this->get_user_id($user_id);
2379
2380 $ratings = array(
2381 'rating' => 0,
2382 'review' => '',
2383 );
2384
2385 global $wpdb;
2386
2387 $rating = $wpdb->get_row("select meta_value as rating, comment_content as review from {$wpdb->comments}
2388 INNER JOIN {$wpdb->commentmeta}
2389 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2390 WHERE {$wpdb->comments}.comment_post_ID = {$course_id} AND user_id = {$user_id}
2391 AND meta_key = 'tutor_rating' ;"
2392 );
2393
2394 if ($rating){
2395 $rating_format = number_format($rating->rating, 2);
2396
2397 $ratings = array(
2398 'rating' => $rating_format,
2399 'review' => $rating->review,
2400 );
2401 }
2402 return (object) $ratings;
2403 }
2404
2405 /**
2406 * @param int $user_id
2407 *
2408 * @return null|string
2409 *
2410 * @since v.1.0.0
2411 */
2412 public function count_reviews_wrote_by_user($user_id = 0){
2413 global $wpdb;
2414 $user_id = $this->get_user_id($user_id);
2415
2416 $count_reviews = $wpdb->get_var("SELECT COUNT(comment_ID) from {$wpdb->comments} WHERE user_id = {$user_id} AND comment_type = 'tutor_course_rating' ");
2417 return $count_reviews;
2418 }
2419
2420 /**
2421 * @param $size
2422 *
2423 * @return bool|int|string
2424 *
2425 * This function transforms the php.ini notation for numbers (like '2M') to an integer.
2426 *
2427 * @since v.1.0.0
2428 */
2429
2430 function let_to_num( $size ) {
2431 $l = substr( $size, -1 );
2432 $ret = substr( $size, 0, -1 );
2433 $byte = 1024;
2434
2435 switch ( strtoupper( $l ) ) {
2436 case 'P':
2437 $ret *= 1024;
2438 // No break.
2439 case 'T':
2440 $ret *= 1024;
2441 // No break.
2442 case 'G':
2443 $ret *= 1024;
2444 // No break.
2445 case 'M':
2446 $ret *= 1024;
2447 // No break.
2448 case 'K':
2449 $ret *= 1024;
2450 // No break.
2451 }
2452 return $ret;
2453 }
2454
2455 /**
2456 * @return array
2457 *
2458 * Get Database version
2459 *
2460 * @since v.1.0.0
2461 */
2462 function get_db_version() {
2463 global $wpdb;
2464
2465 if ( empty( $wpdb->is_mysql ) ) {
2466 return array(
2467 'string' => '',
2468 'number' => '',
2469 );
2470 }
2471
2472 if ( $wpdb->use_mysqli ) {
2473 $server_info = mysqli_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2474 } else {
2475 $server_info = mysql_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2476 }
2477
2478 return array(
2479 'string' => $server_info,
2480 'number' => preg_replace( '/([^\d.]+).*/', '', $server_info ),
2481 );
2482 }
2483
2484 public function help_tip($tip = ''){
2485 return '<span class="tutor-help-tip" data-tip="' . $tip . '"></span>';
2486 }
2487
2488 /**
2489 * @param int $course_id
2490 * @param int $user_id
2491 * @param int $offset
2492 * @param int $limit
2493 *
2494 * @return array|null|object
2495 *
2496 * Get top question
2497 *
2498 * @since v.1.0.0
2499 */
2500 public function get_top_question($course_id = 0, $user_id = 0, $offset = 0, $limit = 20){
2501 $course_id = $this->get_post_id($course_id);
2502 $user_id = $this->get_user_id($user_id);
2503
2504 global $wpdb;
2505
2506 $questions = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2507 {$wpdb->comments}.comment_post_ID,
2508 {$wpdb->comments}.comment_author,
2509 {$wpdb->comments}.comment_date,
2510 {$wpdb->comments}.comment_content,
2511 {$wpdb->comments}.user_id,
2512 {$wpdb->commentmeta}.meta_value as question_title,
2513 {$wpdb->users}.display_name
2514
2515 from {$wpdb->comments}
2516 INNER JOIN {$wpdb->commentmeta}
2517 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2518 INNER JOIN {$wpdb->users}
2519 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2520 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2521 AND {$wpdb->comments}.user_id = {$user_id}
2522 AND {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2523 AND meta_key = 'tutor_question_title' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2524 );
2525
2526 return $questions;
2527 }
2528
2529 /**
2530 * @param string $search_term
2531 *
2532 * @return int
2533 *
2534 * Get total number of Q&A questions
2535 *
2536 * @since v.1.0.0
2537 */
2538 public function get_total_qa_question($search_term = ''){
2539 global $wpdb;
2540
2541 if ($search_term){
2542 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2543 }
2544
2545 $count = $wpdb->get_var("SELECT COUNT({$wpdb->comments}.comment_ID) FROM {$wpdb->comments}
2546 INNER JOIN {$wpdb->commentmeta}
2547 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2548 WHERE comment_type = 'tutor_q_and_a' AND comment_parent = 0 {$search_term} ");
2549
2550 return (int) $count;
2551 }
2552
2553 /**
2554 * @param int $start
2555 * @param int $limit
2556 * @param string $search_term
2557 *
2558 * @return array|null|object
2559 *
2560 *
2561 * Get question and answer query
2562 *
2563 * @since v.1.0.0
2564 */
2565 public function get_qa_questions($start = 0, $limit = 10, $search_term = '') {
2566 global $wpdb;
2567
2568 if ($search_term){
2569 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2570 }
2571
2572 $query = $wpdb->get_results("SELECT
2573 {$wpdb->comments}.comment_ID,
2574 {$wpdb->comments}.comment_post_ID,
2575 {$wpdb->comments}.comment_author,
2576 {$wpdb->comments}.comment_date,
2577 {$wpdb->comments}.comment_content,
2578 {$wpdb->comments}.user_id,
2579 {$wpdb->commentmeta}.meta_value as question_title,
2580 {$wpdb->users}.display_name,
2581 {$wpdb->posts}.post_title,
2582
2583 (SELECT COUNT(answers_t.comment_ID) FROM {$wpdb->comments} answers_t
2584 WHERE answers_t.comment_parent = {$wpdb->comments}.comment_ID ) as answer_count
2585
2586 FROM {$wpdb->comments}
2587
2588 INNER JOIN {$wpdb->commentmeta}
2589 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2590
2591 INNER JOIN {$wpdb->posts}
2592 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2593
2594 INNER JOIN {$wpdb->users}
2595 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2596
2597 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_parent = 0 {$search_term}
2598 ORDER BY {$wpdb->comments}.comment_ID DESC
2599 LIMIT {$start},{$limit}; ");
2600
2601 return $query;
2602 }
2603
2604 /**
2605 * @param $question_id
2606 *
2607 * @return array|null|object|void
2608 *
2609 * Get question for Q&A
2610 *
2611 * @since v.1.0.0
2612 */
2613 public function get_qa_question($question_id){
2614 global $wpdb;
2615 $query = $wpdb->get_row("SELECT
2616 {$wpdb->comments}.comment_ID,
2617 {$wpdb->comments}.comment_post_ID,
2618 {$wpdb->comments}.comment_author,
2619 {$wpdb->comments}.comment_date,
2620 {$wpdb->comments}.comment_content,
2621 {$wpdb->comments}.user_id,
2622 {$wpdb->commentmeta}.meta_value as question_title,
2623 {$wpdb->users}.display_name,
2624 {$wpdb->posts}.post_title
2625
2626 FROM {$wpdb->comments}
2627 INNER JOIN {$wpdb->commentmeta}
2628 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2629
2630 INNER JOIN {$wpdb->posts}
2631 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2632
2633 INNER JOIN {$wpdb->users}
2634 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2635 WHERE comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_ID = {$question_id}");
2636
2637 return $query;
2638 }
2639
2640 /**
2641 * @param $question_id
2642 *
2643 * @return array|null|object
2644 *
2645 * Get question and asnwer by question
2646 */
2647 public function get_qa_answer_by_question($question_id){
2648 global $wpdb;
2649 $query = $wpdb->get_results("SELECT
2650 {$wpdb->comments}.comment_ID,
2651 {$wpdb->comments}.comment_post_ID,
2652 {$wpdb->comments}.comment_author,
2653 {$wpdb->comments}.comment_date,
2654 {$wpdb->comments}.comment_content,
2655 {$wpdb->comments}.comment_parent,
2656 {$wpdb->comments}.user_id,
2657 {$wpdb->users}.display_name
2658
2659 FROM {$wpdb->comments}
2660
2661 INNER JOIN {$wpdb->users}
2662 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2663 WHERE comment_type = 'tutor_q_and_a'
2664 AND {$wpdb->comments}.comment_parent = {$question_id} ORDER BY {$wpdb->comments}.comment_ID ASC ");
2665
2666 return $query;
2667 }
2668
2669 public function unanswered_question_count(){
2670 global $wpdb;
2671
2672 $count = $wpdb->get_var("select COUNT({$wpdb->comments}.comment_ID)
2673 from {$wpdb->comments}
2674 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2675 AND {$wpdb->comments}.comment_approved = 'waiting_for_answer'
2676 AND {$wpdb->comments}.comment_parent = 0;");
2677 return (int) $count;
2678 }
2679
2680 /**
2681 * @param int $course_id
2682 *
2683 * @return array|null|object
2684 *
2685 * Return all of announcements for a course
2686 *
2687 * @since v.1.0.0
2688 */
2689 public function get_announcements($course_id = 0){
2690 $course_id = $this->get_post_id($course_id);
2691 global $wpdb;
2692
2693 $query = $wpdb->get_results("select {$wpdb->posts}.ID, post_author, post_date, post_content, post_title, display_name
2694 from {$wpdb->posts}
2695 INNER JOIN {$wpdb->users} ON post_author = {$wpdb->users}.ID
2696 WHERE post_type = 'tutor_announcements'
2697 AND post_parent = {$course_id} ORDER BY {$wpdb->posts}.ID DESC;");
2698 return $query;
2699 }
2700
2701 /**
2702 * @param string $content
2703 *
2704 * @return mixed
2705 *
2706 * Announcement content
2707 *
2708 * @since v.1.0.0
2709 */
2710
2711 public function announcement_content($content = ''){
2712 $search = array('{user_display_name}');
2713
2714 $user_display_name = 'User';
2715 if (is_user_logged_in()){
2716 $user = wp_get_current_user();
2717 $user_display_name = $user->display_name;
2718 }
2719 $replace = array($user_display_name);
2720
2721 return str_replace($search, $replace, $content);
2722 }
2723
2724 /**
2725 * @param int $post_id
2726 * @param string $option_key
2727 * @param bool $default
2728 *
2729 * @return array|bool|mixed
2730 *
2731 * Get the quiz option from meta
2732 */
2733 public function get_quiz_option($post_id = 0, $option_key = '', $default = false){
2734 $post_id = $this->get_post_id($post_id);
2735 $get_option_meta = maybe_unserialize(get_post_meta($post_id, 'tutor_quiz_option', true));
2736
2737 if ( ! $option_key && ! empty($get_option_meta)) {
2738 return $get_option_meta;
2739 }
2740
2741 $value = $this->avalue_dot( $option_key, $get_option_meta );
2742 if ( $value ) {
2743 return $value;
2744 }
2745 return $default;
2746 }
2747
2748
2749 /**
2750 * @param int $quiz_id
2751 *
2752 * @return array|bool|null|object
2753 *
2754 * Get the questions by quiz ID
2755 */
2756 public function get_questions_by_quiz($quiz_id = 0){
2757 $quiz_id = $this->get_post_id($quiz_id);
2758 global $wpdb;
2759
2760 //$questions = $wpdb->get_results("SELECT ID, post_content, post_title, post_parent from {$wpdb->posts} WHERE post_type = 'tutor_question'
2761 // AND post_parent = {$quiz_id} ORDER BY menu_order ASC ");
2762
2763 $questions = $wpdb->get_results("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY question_order ASC ");
2764
2765 if (is_array($questions) && count($questions)){
2766 return $questions;
2767 }
2768 return false;
2769 }
2770
2771 /**
2772 * @param int $question_id
2773 *
2774 * @return array|bool|object|void|null
2775 *
2776 * Get Quiz question by question id
2777 */
2778 public function get_quiz_question_by_id($question_id = 0){
2779 global $wpdb;
2780
2781 if ($question_id){
2782 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} LIMIT 0,1 ;");
2783 return $question;
2784 }
2785
2786 return false;
2787 }
2788
2789 /**
2790 * @param null $type
2791 *
2792 * @return array|mixed
2793 *
2794 * Get all question types
2795 *
2796 * @since v.1.0.0
2797 */
2798
2799 public function get_question_types($type = null){
2800 $types = array(
2801 'true_false' => array('name' => __('True/False', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-yes-no"></i>'),
2802 'single_choice' => array('name' => __('Single Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-mark"></i>'),
2803 'multiple_choice' => array('name' => __('Multiple Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-multiple-choice"></i>'),
2804 'open_ended' => array('name' => __('Open Ended/Essay', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-open-ended"></i>'),
2805 'short_answer' => array('name' => __('Short Answer', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-short-ans"></i>'),
2806 'fill_in_the_blank' => array('name' => __('Fill In The Blank', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-fill-gaps"></i>'),
2807 'answer_sorting' => array('name' => __('Answer Sorting', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-answer-shorting"></i>'),
2808 'assessment' => array('name' => __('Assessment', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-assesment"></i>'),
2809 'matching' => array('name' => __('Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-matching"></i>'),
2810 'image_matching' => array('name' => __('Image Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-matching"></i>'),
2811 'image_answering' => array('name' => __('Image Answering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-ans"></i>'),
2812 'ordering' => array('name' => __('Ordering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-ordering"></i>'),
2813 );
2814
2815 if (isset($types[$type])){
2816 return $types[$type];
2817 }
2818 return $types;
2819 }
2820
2821 public function get_quiz_answer_options_by_question($question_id){
2822 global $wpdb;
2823
2824 $answer_options = $wpdb->get_results("select
2825 {$wpdb->comments}.comment_ID,
2826 {$wpdb->comments}.comment_post_ID,
2827 {$wpdb->comments}.comment_content
2828
2829 FROM {$wpdb->comments}
2830 WHERE {$wpdb->comments}.comment_post_ID = {$question_id}
2831 AND {$wpdb->comments}.comment_type = 'quiz_answer_option'
2832 ORDER BY {$wpdb->comments}.comment_karma ASC ;");
2833
2834 if (is_array($answer_options) && count($answer_options)){
2835 return $answer_options;
2836 }
2837 return false;
2838 }
2839
2840 /**
2841 * @param $quiz_id
2842 *
2843 * @return int
2844 *
2845 * Get the next question order ID
2846 *
2847 * @since v.1.0.0
2848 */
2849
2850 public function quiz_next_question_order_id($quiz_id){
2851 global $wpdb;
2852
2853 //$last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$quiz_id} AND post_type =
2854 // 'tutor_question';");
2855
2856 $last_order = (int) $wpdb->get_var("SELECT MAX(question_order) FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ;");
2857 return $last_order + 1;
2858 }
2859
2860 /**
2861 * @param $quiz_id
2862 *
2863 * @return int
2864 *
2865 * new design quiz question
2866 * @since v.1.0.0
2867 */
2868 public function quiz_next_question_id(){
2869 global $wpdb;
2870
2871 $last_order = (int) $wpdb->get_var("SELECT MAX(question_id) FROM {$wpdb->prefix}tutor_quiz_questions;");
2872 return $last_order + 1;
2873 }
2874
2875 public function get_quiz_id_by_question($question_id){
2876 global $wpdb;
2877
2878 $quiz_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$question_id} AND post_type = 'tutor_question' ;");
2879 return $quiz_id;
2880 }
2881
2882 /**
2883 * @param array $config
2884 *
2885 * @return array|bool|null|object
2886 *
2887 * It was used in previous quiz algorithm
2888 *
2889 * @deprecated
2890 *
2891 * @since v.1.0.0
2892 */
2893 public function get_unattached_quiz($config = array()){
2894 global $wpdb;
2895
2896 $default_attr = array(
2897 'search_term' => '',
2898 'start' => '0',
2899 'limit' => '10',
2900 'order' => 'DESC',
2901 'order_by' => 'ID',
2902 );
2903 $attr = array_merge($default_attr, $config);
2904 extract($attr);
2905
2906 $search_query = '';
2907 if (! empty($search_term)){
2908 $search_query = "AND post_title LIKE '%{$search_term}%'";
2909 }
2910
2911 $questions = $wpdb->get_results("SELECT ID, post_content, post_title, post_parent from {$wpdb->posts} WHERE post_type = 'tutor_quiz' AND post_status = 'publish' AND post_parent = 0 {$search_query} ORDER BY {$order_by} {$order} LIMIT {$start},{$limit} ");
2912
2913 if (is_array($questions) && count($questions)){
2914 return $questions;
2915 }
2916 return false;
2917 }
2918
2919 /**
2920 * @param int $post_id
2921 *
2922 * @return array|bool|null|object
2923 *
2924 * @since v.1.0.0
2925 */
2926 public function get_attached_quiz($post_id = 0){
2927 global $wpdb;
2928
2929 $post_id = $this->get_post_id($post_id);
2930
2931 $questions = $wpdb->get_results("SELECT ID, post_content, post_title, post_parent from {$wpdb->posts} WHERE post_type = 'tutor_quiz' AND post_status = 'publish' AND post_parent = {$post_id}");
2932
2933 if (is_array($questions) && count($questions)){
2934 return $questions;
2935 }
2936 return false;
2937 }
2938
2939 /**
2940 * @param $quiz_id
2941 *
2942 * @return array|bool|null|object|void
2943 *
2944 * Get course by quiz
2945 *
2946 * @since v.1.0.0
2947 */
2948
2949 public function get_course_by_quiz($quiz_id){
2950 global $wpdb;
2951
2952 $quiz_id = $this->get_post_id($quiz_id);
2953 $post = get_post($quiz_id);
2954
2955 if ($post) {
2956 $course_post_type = tutor()->course_post_type;
2957 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$post->post_parent} " );
2958
2959 if ($course) {
2960 //Checking if this topic
2961 if ( $course->post_type !== $course_post_type ) {
2962 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
2963 }
2964 //Checking if this lesson
2965 if ( $course->post_type !== $course_post_type ) {
2966 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
2967 }
2968
2969 return $course;
2970 }
2971 }
2972
2973 return false;
2974 }
2975
2976 /**
2977 * @param $quiz_id
2978 *
2979 * @return int
2980 *
2981 * @since v.1.0.0
2982 */
2983 public function total_questions_for_student_by_quiz($quiz_id){
2984 $quiz_id = $this->get_post_id($quiz_id);
2985 global $wpdb;
2986
2987 $total_question = (int) $wpdb->get_var("select count(ID) from {$wpdb->posts} where post_parent = {$quiz_id} AND post_type = 'tutor_question' ");
2988
2989 return $total_question;
2990 }
2991
2992 /**
2993 * @param int $quiz_id
2994 *
2995 * @return array|null|object|void
2996 *
2997 * Determine if there is any started quiz exists
2998 *
2999 * @since v.1.0.0
3000 */
3001
3002 public function is_started_quiz($quiz_id = 0){
3003 global $wpdb;
3004
3005 $quiz_id = $this->get_post_id($quiz_id);
3006 $user_id = get_current_user_id();
3007
3008 $is_started = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE user_id = {$user_id} AND quiz_id = {$quiz_id} AND attempt_status = 'attempt_started' ");
3009
3010 return $is_started;
3011 }
3012
3013 /**
3014 * @param $quiz_id
3015 *
3016 * Method for get the total amount of question for a quiz
3017 * Student will answer this amount of question, one quiz have many question
3018 * but student will answer a specific amount of questions
3019 *
3020 * @return int
3021 *
3022 * @since v.1.0.0
3023 */
3024
3025 public function max_questions_for_take_quiz($quiz_id){
3026 $quiz_id = $this->get_post_id($quiz_id);
3027 global $wpdb;
3028
3029 $max_questions = (int) $wpdb->get_var("select count(question_id) from {$wpdb->prefix}tutor_quiz_questions where quiz_id = {$quiz_id} ");
3030 $max_mentioned = (int) $this->get_quiz_option($quiz_id, 'max_questions_for_answer', 10);
3031
3032 if ($max_mentioned < $max_questions ){
3033 return $max_mentioned;
3034 }
3035
3036 return $max_questions;
3037 }
3038
3039 /**
3040 * @param int $attempt_id
3041 *
3042 * @return array|bool|null|object|void
3043 *
3044 * Get single quiz attempt
3045 *
3046 * @since v.1.0.0
3047 */
3048 public function get_attempt($attempt_id = 0){
3049 global $wpdb;
3050 if ( ! $attempt_id){
3051 return false;
3052 }
3053 $attempt = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE attempt_id = {$attempt_id} ");
3054 return $attempt;
3055 }
3056
3057 /**
3058 * @param $attempt_info
3059 *
3060 * @return mixed
3061 *
3062 * Get unserialize attempt info
3063 *
3064 * @since v.1.0.0
3065 */
3066
3067 public function quiz_attempt_info($attempt_info){
3068 return maybe_unserialize($attempt_info);
3069 }
3070
3071 /**
3072 * @param $quiz_attempt_id
3073 * @param array $attempt_info
3074 *
3075 * @return bool|int
3076 *
3077 * Update attempt for various action
3078 *
3079 * @since v.1.0.0
3080 */
3081 public function quiz_update_attempt_info($quiz_attempt_id, $attempt_info = array()){
3082 $answers = tutor_utils()->avalue_dot('answers', $attempt_info);
3083 $total_marks = array_sum(wp_list_pluck($answers, 'question_mark'));
3084 $earned_marks = tutor_utils()->avalue_dot('marks_earned', $attempt_info);
3085 $earned_mark_percent = $earned_marks > 0 ? ( number_format(($earned_marks * 100) / $total_marks)) : 0;
3086 update_comment_meta($quiz_attempt_id, 'earned_mark_percent', $earned_mark_percent);
3087
3088 return update_comment_meta($quiz_attempt_id,'quiz_attempt_info', $attempt_info);
3089 }
3090
3091 /**
3092 * @param int $quiz_id
3093 *
3094 * @return array|null|object
3095 *
3096 * Get random question by quiz id
3097 *
3098 * @since v.1.0.0
3099 */
3100
3101 public function get_random_question_by_quiz($quiz_id = 0){
3102 global $wpdb;
3103
3104 $quiz_id = $this->get_post_id($quiz_id);
3105 $is_attempt = $this->is_started_quiz($quiz_id);
3106
3107 $tempSql = " AND question_type = 'matching' ";
3108 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} {$tempSql} ORDER BY RAND() LIMIT 0,1 ");
3109
3110 return $questions;
3111 }
3112
3113 /**
3114 * @param int $quiz_id
3115 *
3116 * @return array|null|object
3117 *
3118 * Get random questions by quiz
3119 */
3120 public function get_random_questions_by_quiz($quiz_id = 0){
3121 global $wpdb;
3122
3123 $quiz_id = $this->get_post_id($quiz_id);
3124 $attempt = $this->is_started_quiz($quiz_id);
3125 if ( ! $attempt){
3126 return false;
3127 }
3128
3129 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY RAND() LIMIT {$attempt->total_questions} ");
3130
3131 return $questions;
3132 }
3133
3134 /**
3135 * @param $question_id
3136 * @param bool $rand
3137 *
3138 * @return array|bool|null|object
3139 *
3140 * Get answers list by quiz question
3141 *
3142 * @since v.1.0.0
3143 */
3144 public function get_answers_by_quiz_question($question_id, $rand = false){
3145 global $wpdb;
3146
3147
3148 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} ;");
3149 if ( ! $question){
3150 return false;
3151 }
3152
3153 $order = " answer_order ASC ";
3154 if ($question->question_type === 'ordering'){
3155 $order = " RAND() ";
3156 }
3157
3158 if ($rand){
3159 $order = " RAND() ";
3160 }
3161
3162 $answers = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question_id} AND belongs_question_type =
3163 '{$question->question_type}' order by {$order} ");
3164 return $answers;
3165 }
3166
3167 /**
3168 * @param int $quiz_id
3169 * @param int $user_id
3170 *
3171 * @return array|bool|null|object
3172 *
3173 * Get all of the attempts by an user of a quiz
3174 *
3175 * @since v.1.0.0
3176 */
3177
3178 public function quiz_attempts($quiz_id = 0, $user_id = 0){
3179 global $wpdb;
3180
3181 $quiz_id = $this->get_post_id($quiz_id);
3182 $user_id = $this->get_user_id($user_id);
3183
3184 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE quiz_id = {$quiz_id} AND user_id = {$user_id} ");
3185
3186 if (is_array($attempts) && count($attempts)){
3187 return $attempts;
3188 }
3189
3190 return false;
3191 }
3192
3193 /**
3194 * @param string $search_term
3195 *
3196 * @return int
3197 *
3198 * Total number of quiz attempts
3199 *
3200 * @since v.1.0.0
3201 */
3202
3203 public function get_total_quiz_attempts($search_term = ''){
3204 global $wpdb;
3205
3206 if ($search_term){
3207 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3208 }
3209
3210 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3211 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3212 INNER JOIN {$wpdb->posts} quiz
3213 ON quiz_attempts.quiz_id = quiz.ID
3214 INNER JOIN {$wpdb->users}
3215 ON quiz_attempts.user_id = {$wpdb->users}.ID
3216 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3217 return (int) $count;
3218 }
3219
3220 /**
3221 * @param int $start
3222 * @param int $limit
3223 * @param string $search_term
3224 *
3225 * @return array|null|object
3226 *
3227 *
3228 * Get the all quiz attempts
3229 *
3230 * @since v.1.0.0
3231 */
3232 public function get_quiz_attempts($start = 0, $limit = 10, $search_term = '') {
3233 global $wpdb;
3234
3235 if ($search_term){
3236 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3237 }
3238
3239 $query = $wpdb->get_results("SELECT *
3240 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3241 INNER JOIN {$wpdb->posts} quiz
3242 ON quiz_attempts.quiz_id = quiz.ID
3243 INNER JOIN {$wpdb->users}
3244 ON quiz_attempts.user_id = {$wpdb->users}.ID
3245 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3246 ORDER BY quiz_attempts.attempt_id DESC
3247 LIMIT {$start},{$limit}; ");
3248 return $query;
3249 }
3250
3251 public function get_quiz_attempts_by_course_ids($start = 0, $limit = 10, $course_ids = array(), $search_term = '') {
3252 global $wpdb;
3253
3254 if ($search_term){
3255 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3256 }
3257
3258 $course_ids_in = implode($course_ids, ',');
3259 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3260 $search_term = $sql.$search_term;
3261
3262 $query = $wpdb->get_results("SELECT *
3263 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3264 INNER JOIN {$wpdb->posts} quiz
3265 ON quiz_attempts.quiz_id = quiz.ID
3266 INNER JOIN {$wpdb->users}
3267 ON quiz_attempts.user_id = {$wpdb->users}.ID
3268 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3269 ORDER BY quiz_attempts.attempt_id DESC
3270 LIMIT {$start},{$limit}; ");
3271 return $query;
3272 }
3273
3274 public function get_total_quiz_attempts_by_course_ids($course_ids = array(), $search_term = ''){
3275 global $wpdb;
3276
3277 if ($search_term){
3278 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3279 }
3280
3281 $course_ids_in = implode($course_ids, ',');
3282 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3283 $search_term = $sql.$search_term;
3284
3285 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3286 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3287 INNER JOIN {$wpdb->posts} quiz
3288 ON quiz_attempts.quiz_id = quiz.ID
3289 INNER JOIN {$wpdb->users}
3290 ON quiz_attempts.user_id = {$wpdb->users}.ID
3291 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3292 return (int) $count;
3293 }
3294
3295 /**
3296 * @param $attempt_id
3297 *
3298 * @return array|null|object
3299 *
3300 * Get quiz answers by attempt id
3301 *
3302 * @since v.1.0.0
3303 */
3304 public function get_quiz_answers_by_attempt_id($attempt_id){
3305 global $wpdb;
3306
3307 $results = $wpdb->get_results("SELECT answers.*, question.question_title, question.question_type
3308 FROM {$wpdb->prefix}tutor_quiz_attempt_answers answers
3309 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answers.question_id = question.question_id
3310 WHERE answers.quiz_attempt_id = {$attempt_id} ");
3311
3312 return $results;
3313 }
3314
3315 /**
3316 * @param $answer_id
3317 *
3318 * @return array|null|object
3319 *
3320 * Get single answer by answer_id
3321 *
3322 * @since v.1.0.0
3323 */
3324 public function get_answer_by_id($answer_id){
3325 global $wpdb;
3326
3327 if (is_array($answer_id)){
3328 $in_ids = implode(",", $answer_id);
3329 $sql = "answer.answer_id IN({$in_ids})";
3330 }else{
3331 $sql = "answer.answer_id = {$answer_id}";
3332 }
3333
3334 $answer = $wpdb->get_results("SELECT answer.*, question.question_title, question.question_type
3335 FROM {$wpdb->prefix}tutor_quiz_question_answers answer
3336 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answer.belongs_question_id = question.question_id
3337 WHERE 1=1 AND {$sql} ");
3338
3339 return $answer;
3340 }
3341
3342 /**
3343 * @param $ids
3344 *
3345 * @return array|bool|null|object
3346 *
3347 * Get quiz answers by ids
3348 *
3349 * @since v.1.0.0
3350 */
3351
3352 public function get_quiz_answers_by_ids($ids){
3353 $ids = (array) $ids;
3354
3355 if (!count($ids)){
3356 return false;
3357 }
3358
3359 $in_ids = implode(",", $ids);
3360
3361 global $wpdb;
3362 $query = $wpdb->get_results("SELECT
3363 comment_ID,
3364 comment_content
3365 FROM {$wpdb->comments}
3366 WHERE comment_type = 'quiz_answer_option' AND comment_ID IN({$in_ids}) ");
3367
3368 if (is_array($query) && count($query)){
3369 return $query;
3370 }
3371
3372 return false;
3373 }
3374
3375 /**
3376 * @param null $level
3377 *
3378 * @return mixed
3379 *
3380 * Get the users / students / course levels
3381 *
3382 * @since v.1.0.0
3383 */
3384
3385 public function course_levels($level = null){
3386 $levels = apply_filters('tutor_course_level', array(
3387 'all_levels' => __('All Levels', 'tutor'),
3388 'beginner' => __('Beginner', 'tutor'),
3389 'intermediate' => __('Intermediate', 'tutor'),
3390 'expert' => __('Expert', 'tutor'),
3391 ));
3392
3393 if ($level){
3394 if (isset($levels[$level])){
3395 return $levels[$level];
3396 }else{
3397 return '';
3398 }
3399 }
3400
3401 return $levels;
3402 }
3403
3404 /**
3405 * @return mixed|void
3406 *
3407 * Get user permalink for dashboard
3408 *
3409 * @since v.1.0.0
3410 */
3411 public function user_profile_permalinks(){
3412 $permalinks = array(
3413 'enrolled_course' => __('Enrolled Course', 'tutor'),
3414 'courses_taken' => __('Courses Taken', 'tutor'),
3415 'reviews_wrote' => __('Reviews Written', 'tutor'),
3416 );
3417
3418 return apply_filters('tutor_public_profile/permalinks', $permalinks);
3419 }
3420
3421 /**
3422 * @return bool|false|string
3423 *
3424 * Student registration form
3425 *
3426 * @since v.1.0.0
3427 */
3428 public function student_register_url(){
3429 $student_register_page = (int) $this->get_option('student_register_page');
3430
3431 if ($student_register_page){
3432 return get_the_permalink($student_register_page);
3433 }
3434 return false;
3435 }
3436
3437 /**
3438 * @return false|string
3439 *
3440 * Get frontend dashboard URL
3441 */
3442 public function tutor_dashboard_url(){
3443 $page_id = (int) tutor_utils()->get_option('student_dashboard');
3444 $page_id = apply_filters('tutor_dashboard_url', $page_id);
3445 return get_the_permalink($page_id);
3446 }
3447
3448 /**
3449 * @param int $course_id
3450 * @param int $user_id
3451 *
3452 * @return bool
3453 *
3454 * is_wishlisted();
3455 *
3456 * @since v.1.0.0
3457 */
3458 public function is_wishlisted($course_id = 0, $user_id = 0){
3459 $course_id = $this->get_post_id($course_id);
3460 $user_id = $this->get_user_id($user_id);
3461 if ( ! $user_id){
3462 return false;
3463 }
3464
3465 global $wpdb;
3466 $if_added_to_list = (bool) $wpdb->get_row("select * from {$wpdb->usermeta} WHERE user_id = {$user_id} AND meta_key = '_tutor_course_wishlist' AND meta_value = {$course_id} ;");
3467
3468 return $if_added_to_list;
3469 }
3470
3471 /**
3472 * @param int $user_id
3473 *
3474 * @return array|null|object
3475 *
3476 * Get the wish lists by an user
3477 *
3478 * @since v.1.0.0
3479 */
3480 public function get_wishlist($user_id = 0){
3481 $user_id = $this->get_user_id($user_id);
3482 global $wpdb;
3483
3484 $query = "SELECT $wpdb->posts.*
3485 FROM $wpdb->posts
3486 LEFT JOIN $wpdb->usermeta ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
3487 WHERE $wpdb->usermeta.meta_key = '_tutor_course_wishlist'
3488 AND $wpdb->usermeta.user_id = {$user_id}
3489 ORDER BY $wpdb->usermeta.umeta_id DESC ";
3490 $pageposts = $wpdb->get_results($query, OBJECT);
3491 return $pageposts;
3492 }
3493
3494 /**
3495 * @param int $limit
3496 *
3497 * @return array|null|object
3498 *
3499 * Getting popular courses
3500 *
3501 * @since v.1.0.0
3502 */
3503 public function most_popular_courses($limit = 10){
3504 global $wpdb;
3505
3506 $courses = $wpdb->get_results("
3507 SELECT COUNT(enrolled.ID) as total_enrolled,
3508 enrolled.post_parent as course_id,
3509 course.*
3510 from {$wpdb->posts} enrolled
3511 INNER JOIN {$wpdb->posts} course ON enrolled.post_parent = course.ID
3512 WHERE enrolled.post_type = 'tutor_enrolled' AND enrolled.post_status = 'completed'
3513
3514 GROUP BY course_id
3515 ORDER BY total_enrolled DESC LIMIT 0,{$limit} ;");
3516
3517 return $courses;
3518 }
3519
3520 /**
3521 * @param int $limit
3522 *
3523 * @return array|bool|null|object
3524 *
3525 * Get most rated courses lists
3526 *
3527 * @since v.1.0.0
3528 */
3529 public function most_rated_courses($limit = 10){
3530 global $wpdb;
3531
3532 $result = $wpdb->get_results("
3533 SELECT COUNT(comment_ID) AS total_rating,
3534 comment_ID,
3535 comment_post_ID,
3536 course.*
3537 FROM {$wpdb->comments}
3538 INNER JOIN {$wpdb->posts} course ON comment_post_ID = course.ID
3539 WHERE {$wpdb->comments}.comment_type = 'tutor_course_rating' AND {$wpdb->comments}.comment_approved = 'approved'
3540 GROUP BY comment_post_ID ORDER BY total_rating DESC LIMIT 0,{$limit}
3541 ;");
3542
3543 if (is_array($result) && count($result)){
3544 return $result;
3545 }
3546 return false;
3547 }
3548
3549 /**
3550 * @param null $addon_field
3551 *
3552 * @return bool
3553 *
3554 * Get Addon config
3555 *
3556 * @since v.1.0.0
3557 */
3558 public function get_addon_config($addon_field = null){
3559 if ( ! $addon_field){
3560 return false;
3561 }
3562
3563 $addonsConfig = maybe_unserialize(get_option('tutor_addons_config'));
3564
3565 if (isset($addonsConfig[$addon_field])){
3566 return $addonsConfig[$addon_field];
3567 }
3568
3569 return false;
3570 }
3571
3572 /**
3573 * @return array|false|string
3574 *
3575 * Get the IP from visitor
3576 *
3577 * @since v.1.0.0
3578 */
3579 function get_ip() {
3580 $ipaddress = '';
3581 if (getenv('HTTP_CLIENT_IP'))
3582 $ipaddress = getenv('HTTP_CLIENT_IP');
3583 else if(getenv('HTTP_X_FORWARDED_FOR'))
3584 $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
3585 else if(getenv('HTTP_X_FORWARDED'))
3586 $ipaddress = getenv('HTTP_X_FORWARDED');
3587 else if(getenv('HTTP_FORWARDED_FOR'))
3588 $ipaddress = getenv('HTTP_FORWARDED_FOR');
3589 else if(getenv('HTTP_FORWARDED'))
3590 $ipaddress = getenv('HTTP_FORWARDED');
3591 else if(getenv('REMOTE_ADDR'))
3592 $ipaddress = getenv('REMOTE_ADDR');
3593 else
3594 $ipaddress = 'UNKNOWN';
3595 return $ipaddress;
3596 }
3597
3598 }