PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.2.0
Tutor LMS – eLearning and online course solution v1.2.0
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / 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.php 7 years ago TutorEDD.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 Withdraw.php 7 years ago Withdraw_Requests_List.php 7 years ago WooCommerce.php 7 years ago
Utils.php
4055 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 = 0, $post_status = 'publish'){
452 global $wpdb;
453
454 $instructor_id = $this->get_user_id($instructor_id);
455 $course_post_type = tutor()->course_post_type;
456
457 $where_post_status = "AND $wpdb->posts.post_status = 'publish' ";
458 if ($post_status === 'any'){
459 $where_post_status = "";
460 }
461
462 $querystr = "
463 SELECT $wpdb->posts.*
464 FROM $wpdb->posts
465 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
466
467 WHERE 1 = 1 {$where_post_status}
468 AND $wpdb->posts.post_type = '{$course_post_type}'
469 AND $wpdb->posts.post_date < NOW()
470 ORDER BY $wpdb->posts.post_date DESC";
471
472 $pageposts = $wpdb->get_results($querystr, OBJECT);
473 return $pageposts;
474 }
475
476 /**
477 * @return mixed
478 *
479 * Get archive page course count
480 *
481 * @since v.1.0.0
482 */
483 public function get_archive_page_course_count(){
484 global $wp_query;
485 return $wp_query->post_count;
486 }
487
488 /**
489 * @return null|string
490 *
491 * Get course count
492 *
493 * @since v.1.0.0
494 */
495 public function get_course_count(){
496 global $wpdb;
497
498 $course_post_type = tutor()->course_post_type;
499 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = '{$course_post_type}'; ");
500 return $count;
501 }
502
503 /**
504 * @return null|string
505 *
506 * Get lesson count
507 *
508 * @since v.1.0.0
509 */
510 public function get_lesson_count(){
511 global $wpdb;
512
513 $lesson_post_type = tutor()->lesson_post_type;
514 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = '{$lesson_post_type}'; ");
515 return $count;
516 }
517
518 /**
519 * @param int $course_id
520 * @param int $limit
521 *
522 * @return \WP_Query
523 *
524 * Get lesson
525 *
526 * @since v.1.0.0
527 */
528 public function get_lesson($course_id = 0, $limit = 10){
529 $course_id = $this->get_post_id($course_id);
530
531 $lesson_post_type = tutor()->lesson_post_type;
532 $args = array(
533 'post_status' => 'publish',
534 'post_type' => $lesson_post_type,
535 'posts_per_page' => $limit,
536 'meta_query' => array(
537 array(
538 'key' => '_tutor_course_id_for_lesson',
539 'value' => $course_id,
540 'compare' => '=',
541 ),
542 ),
543 );
544 $query = new \WP_Query($args);
545
546 return $query;
547 }
548
549 /**
550 * @param int $course_id
551 *
552 * @return int
553 *
554 * Get total lesson count by a course
555 *
556 * @since v.1.0.0
557 */
558 public function get_lesson_count_by_course($course_id = 0){
559 $course_id = $this->get_post_id($course_id);
560 global $wpdb;
561
562 $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} ");
563
564 return (int) $count_lesson;
565 }
566
567 /**
568 * @param int $course_id
569 * @param int $user_id
570 *
571 * @return int
572 *
573 * Get completed lesson total number by a course
574 *
575 * @since v.1.0.0
576 */
577 public function get_completed_lesson_count_by_course($course_id = 0, $user_id = 0){
578 $course_id = $this->get_post_id($course_id);
579 $user_id = $this->get_user_id($user_id);
580 global $wpdb;
581
582 $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} ");
583
584 $count = 0;
585 if (is_array($completed_lesson_ids) && count($completed_lesson_ids)){
586 $completed_lesson_meta_ids = array();
587 foreach ($completed_lesson_ids as $lesson_id){
588 $completed_lesson_meta_ids[] = '_tutor_completed_lesson_id_'.$lesson_id;
589 }
590 $in_ids = implode("','", $completed_lesson_meta_ids);
591
592 $count = (int) $wpdb->get_var("select count(umeta_id) from {$wpdb->usermeta} WHERE user_id = '{$user_id}' AND meta_key in('{$in_ids}') ");
593 }
594
595 return $count;
596 }
597
598 /**
599 * @param int $course_id
600 * @param int $user_id
601 *
602 * @return float|int
603 *
604 * @since v.1.0.0
605 */
606 public function get_course_completed_percent($course_id = 0, $user_id = 0){
607 $course_id = $this->get_post_id($course_id);
608 $user_id = $this->get_user_id($user_id);
609
610 $total_lesson = $this->get_lesson_count_by_course($course_id);
611 $completed_lesson = $this->get_completed_lesson_count_by_course($course_id, $user_id);
612
613 if ($total_lesson > 0 && $completed_lesson > 0){
614 return number_format(($completed_lesson * 100) / $total_lesson);
615 }
616
617 return 0;
618 }
619
620 /**
621 * @param int $course_id
622 *
623 * @return \WP_Query
624 *
625 * Get all topics by given course ID
626 *
627 * @since v.1.0.0
628 */
629 public function get_topics($course_id = 0){
630 $course_id = $this->get_post_id($course_id);
631
632 $args = array(
633 'post_type' => 'topics',
634 'post_parent' => $course_id,
635 'orderby' => 'menu_order',
636 'order' => 'ASC',
637 'posts_per_page' => -1,
638 );
639
640 $query = new \WP_Query($args);
641 return $query;
642 }
643
644 /**
645 * @param $course_ID
646 *
647 * @return int
648 *
649 * Get next topic order id
650 *
651 * @since v.1.0.0
652 */
653 public function get_next_topic_order_id($course_ID){
654 global $wpdb;
655
656 $last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$course_ID} AND post_type = 'topics';");
657 return $last_order + 1;
658 }
659
660 /**
661 * @param $topic_ID
662 *
663 * @return int
664 *
665 * Get next course content order id
666 *
667 * @since v.1.0.0
668 */
669 public function get_next_course_content_order_id($topic_ID){
670 global $wpdb;
671
672 $last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$topic_ID};");
673 return $last_order + 1;
674 }
675
676 /**
677 * @param int $topics_id
678 * @param int $limit
679 *
680 * @return \WP_Query
681 *
682 * Get lesson by topic
683 *
684 * @since v.1.0.0
685 */
686 public function get_lessons_by_topic($topics_id = 0, $limit = 10){
687 $topics_id = $this->get_post_id($topics_id);
688
689 $lesson_post_type = tutor()->lesson_post_type;
690 $args = array(
691 'post_type' => $lesson_post_type,
692 'post_parent' => $topics_id,
693 'posts_per_page' => $limit,
694 'orderby' => 'menu_order',
695 'order' => 'ASC',
696 );
697
698 $query = new \WP_Query($args);
699
700 return $query;
701 }
702
703 /**
704 * @param int $topics_id
705 * @param int $limit
706 *
707 * @return \WP_Query
708 *
709 * Get course content by topic
710 *
711 * @since v.1.0.0
712 */
713 public function get_course_contents_by_topic($topics_id = 0, $limit = 10){
714 $topics_id = $this->get_post_id($topics_id);
715
716 $lesson_post_type = tutor()->lesson_post_type;
717 $args = array(
718 'post_type' => array($lesson_post_type, 'tutor_quiz'),
719 'post_parent' => $topics_id,
720 'posts_per_page' => $limit,
721 'orderby' => 'menu_order',
722 'order' => 'ASC',
723 );
724
725 $query = new \WP_Query($args);
726
727 return $query;
728 }
729
730 /**
731 * @param string $request_method
732 *
733 * Check actions nonce
734 *
735 * @since v.1.0.0
736 */
737 public function checking_nonce($request_method = 'post'){
738 if ($request_method === 'post'){
739 if (!isset($_POST[tutor()->nonce]) || !wp_verify_nonce($_POST[tutor()->nonce], tutor()->nonce_action)) {
740 exit();
741 }
742 }else{
743 if (!isset($_GET[tutor()->nonce]) || !wp_verify_nonce($_GET[tutor()->nonce], tutor()->nonce_action)) {
744 exit();
745 }
746 }
747 }
748
749 /**
750 * @param int $course_id
751 *
752 * @return bool
753 *
754 * @since v.1.0.0
755 */
756 public function is_course_purchasable($course_id = 0){
757 return apply_filters('is_course_purchasable', false, $course_id);
758 }
759
760 /**
761 * @param int $course_id
762 *
763 * @return null|string
764 *
765 * get course price in digits format if any
766 *
767 * @since v.1.0.0
768 */
769
770 public function get_course_price($course_id = 0){
771 $course_id = $this->get_post_id($course_id);
772
773 $price = null;
774
775 if ($this->is_course_purchasable()) {
776 if ($this->has_wc()){
777 $product_id = tutor_utils()->get_course_product_id($course_id);
778 $product = wc_get_product( $product_id );
779
780 if ( $product ) {
781 $price = $product->get_price();
782 }
783 }else{
784 $price = apply_filters('get_tutor_course_price', null, $course_id);
785 }
786
787 }
788
789 return $price;
790 }
791
792 /**
793 * @param int $course_id
794 *
795 * @return array|bool|null|object
796 *
797 * Check if current user has been enrolled or not
798 *
799 * @since v.1.0.0
800 */
801
802 public function is_enrolled($course_id = 0, $user_id = 0){
803 $course_id = $this->get_post_id($course_id);
804 $user_id = $this->get_user_id($user_id);
805
806 if (is_user_logged_in()) {
807 global $wpdb;
808
809 $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'; " );
810
811 if ( $getEnrolledInfo ) {
812 return $getEnrolledInfo;
813 }
814 }
815 return false;
816 }
817
818 /**
819 * @param int $course_id
820 * @param int $user_id
821 *
822 * @return array|bool|null|object|void
823 *
824 * Has any enrolled for a user in a course
825 *
826 * @since v.1.0.0
827 */
828 public function has_any_enrolled($course_id = 0, $user_id = 0){
829 $course_id = $this->get_post_id($course_id);
830 $user_id = $this->get_user_id($user_id);
831
832 if (is_user_logged_in()) {
833 global $wpdb;
834
835 $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}; " );
836
837 if ( $getEnrolledInfo ) {
838 return $getEnrolledInfo;
839 }
840 }
841 return false;
842 }
843
844 /**
845 * @param int $lesson_id
846 * @param int $user_id
847 *
848 * @return array|bool|null|object
849 *
850 * Get the course Enrolled confirmation by lesson ID
851 *
852 * @since v.1.0.0
853 */
854
855 public function is_course_enrolled_by_lesson($lesson_id = 0, $user_id = 0){
856 $lesson_id = $this->get_post_id($lesson_id);
857 $user_id = $this->get_user_id($user_id);
858
859 return $this->is_enrolled($this->get_course_id_by_lesson($lesson_id));
860 }
861
862 /**
863 * @param int $lesson_id
864 *
865 * @return bool|mixed
866 *
867 * Get the course ID by Lesson
868 *
869 * @since v.1.0.0
870 */
871 public function get_course_id_by_lesson($lesson_id = 0){
872 $lesson_id = $this->get_post_id($lesson_id);
873 return get_post_meta($lesson_id, '_tutor_course_id_for_lesson', true);
874 }
875
876 /**
877 * @param int $course_id
878 *
879 * @return bool|false|string
880 *
881 * Get first lesson of a course
882 *
883 * @since v.1.0.0
884 */
885 public function get_course_first_lesson($course_id = 0){
886 $course_id = $this->get_post_id($course_id);
887 global $wpdb;
888
889 $lesson_id = $wpdb->get_var("
890 SELECT post_id as lesson_id
891 FROM $wpdb->postmeta
892 INNER JOIN {$wpdb->posts} ON post_id = {$wpdb->posts}.ID
893 WHERE meta_key = '_tutor_course_id_for_lesson' AND meta_value = {$course_id}
894
895 ORDER BY menu_order ASC LIMIT 1
896 ");
897
898 /*
899 $lesson_id = $wpdb->get_var(" select main_posts.ID from {$wpdb->posts} main_posts
900 WHERE post_parent =
901 (SELECT sub_posts.ID FROM {$wpdb->posts} sub_posts
902 WHERE post_type = 'topics' AND
903 sub_posts.post_parent = {$course_id} ORDER BY sub_posts.menu_order ASC LIMIT 1 )
904 ORDER BY main_posts.menu_order ASC LIMIT 1 ;");
905 */
906
907 if ($lesson_id){
908 return get_permalink($lesson_id);
909 }
910 return false;
911 }
912
913 /**
914 *
915 * Get course sub pages in course dashboard
916 *
917 * @since v.1.0.0
918 */
919 public function course_sub_pages(){
920 $nav_items = array(
921 'overview' => __('Overview', 'tutor'),
922 );
923
924 $enable_q_and_a_on_course = tutor_utils()->get_option('enable_q_and_a_on_course');
925 if ($enable_q_and_a_on_course){
926 $nav_items['questions'] = __('Q&A', 'tutor');
927 }
928 $nav_items['announcements'] = __('Announcements', 'tutor');
929
930 return apply_filters('tutor_course/single/enrolled/nav_items', $nav_items);
931 }
932
933 /**
934 * @param int $post_id
935 *
936 * @return bool|array
937 *
938 * @since v.1.0.0
939 */
940 public function get_video($post_id = 0){
941 $post_id = $this->get_post_id($post_id);
942 $attachments = get_post_meta($post_id, '_video', true);
943 if ($attachments) {
944 $attachments = maybe_unserialize($attachments);
945 }
946 return $attachments;
947 }
948
949 /**
950 * @param int $post_id
951 * @param array $video_data
952 *
953 * @return bool
954 *
955 * Update the video Info
956 */
957 public function update_video($post_id = 0, $video_data = array()){
958 $post_id = $this->get_post_id($post_id);
959
960 if (is_array($video_data) && count($video_data)){
961 update_post_meta($post_id, '_video', $video_data);
962 }
963 }
964
965 /**
966 * @param int $post_id
967 *
968 * @return bool|mixed
969 *
970 * @since v.1.0.0
971 */
972 public function get_attachments($post_id = 0){
973 $post_id = $this->get_post_id($post_id);
974 $attachments_arr = array();
975 $attachments = maybe_unserialize(get_post_meta($post_id, '_tutor_attachments', true));
976
977 $font_icons = apply_filters('tutor_file_types_icon', array(
978 'archive',
979 'audio',
980 'code',
981 'default',
982 'document',
983 'interactive',
984 'spreadsheet',
985 'text',
986 'video',
987 'image',
988 ));
989
990 if ( is_array($attachments) && count($attachments)) {
991 foreach ( $attachments as $attachment ) {
992 $url = wp_get_attachment_url( $attachment );
993 $file_type = wp_check_filetype( $url );
994 $ext = $file_type['ext'];
995 $title = get_the_title($attachment);
996
997 $file_path = get_attached_file( $attachment );
998 $size_bytes = file_exists($file_path) ? filesize( $file_path ) : 0;
999 $size = size_format( $size_bytes, 2 );
1000 $type = wp_ext2type( $ext );
1001
1002 $icon = 'default';
1003 if ( $type && in_array( $type, $font_icons ) ) {
1004 $icon = $type;
1005 }
1006
1007 $data = array(
1008 'post_id' => $post_id,
1009 'id' => $attachment,
1010 'url' => $url,
1011 'name' => $title . '.' . $ext,
1012 'title' => $title,
1013 'ext' => $ext,
1014 'size' => $size,
1015 'size_bytes' => $size_bytes,
1016 'icon' => $icon,
1017 );
1018
1019 $attachments_arr[] = (object) apply_filters( 'tutor/posts/attachments', $data );
1020 }
1021 }
1022
1023 return $attachments_arr;
1024 }
1025
1026
1027 /**
1028 * @param $seconds
1029 *
1030 * @return string
1031 *
1032 * return seconds to formatted playtime
1033 *
1034 * @since v.1.0.0
1035 */
1036 public function playtime_string($seconds) {
1037 $sign = (($seconds < 0) ? '-' : '');
1038 $seconds = round(abs($seconds));
1039 $H = (int) floor( $seconds / 3600);
1040 $M = (int) floor(($seconds - (3600 * $H) ) / 60);
1041 $S = (int) round( $seconds - (3600 * $H) - (60 * $M) );
1042 return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
1043 }
1044
1045 /**
1046 * @param $seconds
1047 *
1048 * @return array
1049 *
1050 * Get the playtime in array
1051 *
1052 * @since v.1.0.0
1053 */
1054 public function playtime_array($seconds){
1055 $run_time_format = array(
1056 'hours' => '00',
1057 'minutes' => '00',
1058 'seconds' => '00',
1059 );
1060
1061 if ($seconds <= 0 ){
1062 return $run_time_format;
1063 }
1064
1065 $playTimeString = $this->playtime_string($seconds);
1066 $timeInArray = explode(':', $playTimeString);
1067
1068 $run_time_size = count($timeInArray);
1069 if ($run_time_size === 3){
1070 $run_time_format['hours'] = $timeInArray[0];
1071 $run_time_format['minutes'] = $timeInArray[1];
1072 $run_time_format['seconds'] = $timeInArray[2];
1073 }elseif($run_time_size === 2){
1074 $run_time_format['minutes'] = $timeInArray[0];
1075 $run_time_format['seconds'] = $timeInArray[1];
1076 }
1077
1078 return $run_time_format;
1079 }
1080
1081 /**
1082 * @param $seconds
1083 *
1084 * @return string
1085 *
1086 * Convert seconds to human readable time
1087 *
1088 * @since v.1.0.0
1089 */
1090 public function seconds_to_time_context($seconds) {
1091 $sign = (($seconds < 0) ? '-' : '');
1092 $seconds = round(abs($seconds));
1093 $H = (int) floor( $seconds / 3600);
1094 $M = (int) floor(($seconds - (3600 * $H) ) / 60);
1095 $S = (int) round( $seconds - (3600 * $H) - (60 * $M) );
1096
1097 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';
1098 }
1099
1100 /**
1101 * @param int $lesson_id
1102 *
1103 * @return bool|object
1104 *
1105 * @since v.1.0.0
1106 */
1107
1108 public function get_video_info($lesson_id = 0){
1109 $lesson_id = $this->get_post_id($lesson_id);
1110 $video = $this->get_video($lesson_id);
1111
1112 if ( ! $video){
1113 return false;
1114 }
1115
1116 $info = array(
1117 'playtime' => '00:00',
1118 );
1119
1120 $types = apply_filters('tutor_video_types', array("mp4"=>"video/mp4", "webm"=>"video/webm", "ogg"=>"video/ogg"));
1121
1122 $videoSource = $this->avalue_dot('source', $video);
1123 if ($videoSource === 'html5'){
1124 $sourceVideoID = $this->avalue_dot('source_video_id', $video);
1125 $video_info = get_post_meta($sourceVideoID, '_wp_attachment_metadata', true);
1126
1127 if ($video_info){
1128 $path = get_attached_file($sourceVideoID);
1129 $info['playtime'] = $video_info['length_formatted'];
1130 $info['path'] = $path;
1131 $info['url'] = wp_get_attachment_url($sourceVideoID);
1132 $info['ext'] = strtolower(pathinfo($path, PATHINFO_EXTENSION));
1133 $info['type'] = $types[$info['ext']];
1134 }
1135 }
1136
1137 if ($videoSource !== 'html5'){
1138 $video = maybe_unserialize(get_post_meta($lesson_id, '_video', true));
1139
1140 $runtimeHours = tutor_utils()->avalue_dot('runtime.hours', $video);
1141 $runtimeMinutes = tutor_utils()->avalue_dot('runtime.minutes', $video);
1142 $runtimeSeconds = tutor_utils()->avalue_dot('runtime.seconds', $video);
1143
1144 $runtimeHours = $runtimeHours ? $runtimeHours : '00';
1145 $runtimeMinutes = $runtimeMinutes ? $runtimeMinutes : '00';
1146 $runtimeSeconds = $runtimeSeconds ? $runtimeSeconds : '00';
1147
1148 $info['playtime'] = "$runtimeHours:$runtimeMinutes:$runtimeSeconds";
1149 }
1150
1151 $info = array_merge($info, $video);
1152
1153 return (object) $info;
1154 }
1155
1156 /**
1157 * @param int $post_id
1158 *
1159 * @return bool
1160 *
1161 * Ensure if attached video is self hosted or not
1162 *
1163 * @since v.1.0.0
1164 */
1165 public function is_html5_video($post_id = 0){
1166 $post_id = $this->get_post_id($post_id);
1167
1168 $video = $this->get_video($post_id);
1169 if ( ! $video){
1170 return false;
1171 }
1172 $videoSource = $this->avalue_dot('source', $video);
1173 return $videoSource === 'html5';
1174 }
1175
1176 /**
1177 *
1178 * return lesson type icon
1179 *
1180 * @param int $lesson_id
1181 * @param bool $html
1182 * @param bool $echo
1183 *
1184 * @return string
1185 *
1186 * @since v.1.0.0
1187 */
1188
1189 public function get_lesson_type_icon($lesson_id = 0, $html = false, $echo = false){
1190 $post_id = $this->get_post_id($lesson_id);
1191 $video = tutor_utils()->get_video_info($post_id);
1192
1193 $play_time = false;
1194 if ($video){
1195 $play_time = $video->playtime;
1196 }
1197
1198 $tutor_lesson_type_icon = $play_time ? 'youtube' : 'document';
1199
1200 if ($html){
1201 $tutor_lesson_type_icon = "<i class='tutor-icon-$tutor_lesson_type_icon'></i> ";
1202 }
1203
1204 if ($tutor_lesson_type_icon){
1205 echo $tutor_lesson_type_icon;
1206 }
1207
1208 return $tutor_lesson_type_icon;
1209 }
1210
1211 /**
1212 * @param int $lesson_id
1213 * @param int $user_id
1214 *
1215 * @return bool|mixed
1216 *
1217 * @since v.1.0.0
1218 */
1219
1220 public function is_completed_lesson($lesson_id = 0, $user_id = 0){
1221 $lesson_id = $this->get_post_id($lesson_id);
1222 $user_id = $this->get_user_id($user_id);
1223
1224 $is_completed = get_user_meta($user_id, '_tutor_completed_lesson_id_'.$lesson_id, true);
1225
1226 if ($is_completed){
1227 return $is_completed;
1228 }
1229
1230 return false;
1231 }
1232
1233 /**
1234 * @param int $course_id
1235 * @param int $user_id
1236 *
1237 * @return array|bool|null|object|void
1238 *
1239 * Determine if a course completed
1240 *
1241 * @since v.1.0.0
1242 */
1243
1244 public function is_completed_course($course_id = 0, $user_id = 0){
1245 if ( ! is_user_logged_in()){
1246 return false;
1247 }
1248
1249 global $wpdb;
1250 $course_id = $this->get_post_id($course_id);
1251 $user_id = $this->get_user_id($user_id);
1252
1253 $is_completed = $wpdb->get_row("SELECT comment_ID,
1254 comment_post_ID as course_id,
1255 comment_author as completed_user_id,
1256 comment_date as completion_date,
1257 comment_content as completed_hash
1258 from {$wpdb->comments}
1259 WHERE comment_agent = 'TutorLMSPlugin'
1260 AND comment_type = 'course_completed'
1261 AND comment_post_ID = {$course_id}
1262 AND user_id = {$user_id} ;");
1263
1264 if ($is_completed){
1265 return $is_completed;
1266 }
1267
1268 return false;
1269 }
1270
1271 /**
1272 * @param array $input
1273 *
1274 * @return array
1275 *
1276 * Sanitize input array
1277 *
1278 * @since v.1.0.0
1279 */
1280 public function sanitize_array($input = array()){
1281 $array = array();
1282
1283 if (is_array($input) && count($input)){
1284 foreach ($input as $key => $value){
1285 if (is_array($value)){
1286 $array[$key] = $this->sanitize_array($value);
1287 }else{
1288 $key = sanitize_text_field($key);
1289 $value = sanitize_text_field($value);
1290 $array[$key] = $value;
1291 }
1292 }
1293 }
1294
1295 return $array;
1296 }
1297
1298 /**
1299 * @param int $post_id
1300 *
1301 * @return array|bool
1302 *
1303 * Determine if has any video in single
1304 *
1305 * @since v.1.0.0
1306 */
1307
1308 public function has_video_in_single($post_id = 0){
1309 if (is_single()) {
1310 $post_id = $this->get_post_id($post_id);
1311
1312 $video = $this->get_video( $post_id );
1313 if ( $video ) {
1314 return $video;
1315 }
1316 }
1317 return false;
1318
1319 }
1320
1321 /**
1322 * @param int $start
1323 * @param int $limit
1324 * @param string $search_term
1325 * @param int $course_id
1326 *
1327 * @return array|null|object
1328 *
1329 *
1330 * Get the enrolled students for all courses.
1331 *
1332 * Pass course id in 4th parameter to get students course wise.
1333 *
1334 * @since v.1.0.0
1335 */
1336 public function get_students($start = 0, $limit = 10, $search_term = ''){
1337 $meta_key = '_is_tutor_student';
1338
1339 global $wpdb;
1340
1341 if ($search_term){
1342 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
1343 }
1344
1345 $students = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
1346 INNER JOIN {$wpdb->usermeta}
1347 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
1348 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
1349 ORDER BY {$wpdb->usermeta}.meta_value DESC
1350 LIMIT {$start}, {$limit} ");
1351
1352 return $students;
1353 }
1354
1355 /**
1356 * @return int
1357 *
1358 * @since v.1.0.0
1359 *
1360 * get the total students
1361 * pass course id to get course wise total students
1362 *
1363 * @since v.1.0.0
1364 */
1365 public function get_total_students($search_term = ''){
1366 $meta_key = '_is_tutor_student';
1367
1368 global $wpdb;
1369
1370 if ($search_term){
1371 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
1372 }
1373
1374 $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 ");
1375
1376 return (int) $count;
1377 }
1378
1379 /**
1380 * @param int $user_id
1381 *
1382 * @return array
1383 *
1384 * Get complete courses ids by user
1385 *
1386 * @since v.1.0.0
1387 */
1388 public function get_completed_courses_ids_by_user($user_id = 0){
1389 global $wpdb;
1390
1391 $user_id = $this->get_user_id($user_id);
1392
1393 $course_ids = (array) $wpdb->get_col("SELECT comment_post_ID as course_id
1394 from {$wpdb->comments}
1395 WHERE comment_agent = 'TutorLMSPlugin'
1396 AND comment_type = 'course_completed'
1397 AND user_id = {$user_id} ;");
1398
1399 return $course_ids;
1400 }
1401
1402 /**
1403 * @param int $user_id
1404 *
1405 * @return bool|\WP_Query
1406 *
1407 * Return courses by user_id
1408 *
1409 * @since v.1.0.0
1410 */
1411 public function get_courses_by_user($user_id = 0){
1412 $user_id = $this->get_user_id($user_id);
1413 $course_ids = $this->get_completed_courses_ids_by_user($user_id);
1414
1415 if (count($course_ids)){
1416 $course_post_type = tutor()->course_post_type;
1417 $course_args = array(
1418 'post_type' => $course_post_type,
1419 'post_status' => 'publish',
1420 'post__in' => $course_ids,
1421 );
1422
1423 return new \WP_Query($course_args);
1424 }
1425
1426 return false;
1427 }
1428
1429 /**
1430 * @param int $user_id
1431 *
1432 * @return bool|\WP_Query
1433 *
1434 * Get the active course by user
1435 *
1436 * @since v.1.0.0
1437 */
1438
1439 public function get_active_courses_by_user($user_id = 0){
1440 $user_id = $this->get_user_id($user_id);
1441
1442 $course_ids = $this->get_completed_courses_ids_by_user($user_id);
1443 $enrolled_course_ids = $this->get_enrolled_courses_ids_by_user($user_id);
1444 $active_courses = array_diff($enrolled_course_ids, $course_ids);
1445
1446 if (count($active_courses)){
1447 $course_post_type = tutor()->course_post_type;
1448 $course_args = array(
1449 'post_type' => $course_post_type,
1450 'post_status' => 'publish',
1451 'post__in' => $active_courses,
1452 );
1453
1454 return new \WP_Query($course_args);
1455 }
1456
1457 return false;
1458 }
1459
1460 /**
1461 * @param int $user_id
1462 *
1463 * @return array
1464 *
1465 * Get enrolled course ids by a user
1466 *
1467 * @since v.1.0.0
1468 */
1469
1470 public function get_enrolled_courses_ids_by_user($user_id = 0){
1471 global $wpdb;
1472 $user_id = $this->get_user_id($user_id);
1473 $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'; ");
1474
1475 return $course_ids;
1476 }
1477
1478 /**
1479 * @param int $course_id
1480 *
1481 * @return int
1482 *
1483 * Get the total enrolled users at course
1484 */
1485 public function count_enrolled_users_by_course($course_id = 0){
1486 global $wpdb;
1487 $course_id = $this->get_post_id($course_id);
1488
1489 $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'; ");
1490
1491 return (int) $course_ids;
1492 }
1493
1494 /**
1495 * @param int $user_id
1496 *
1497 * @return bool|\WP_Query
1498 *
1499 * Get the enrolled courses by user
1500 */
1501 public function get_enrolled_courses_by_user($user_id = 0){
1502 global $wpdb;
1503
1504 $user_id = $this->get_user_id($user_id);
1505 $course_ids = $this->get_enrolled_courses_ids_by_user($user_id);
1506
1507 if (count($course_ids)){
1508 $course_post_type = tutor()->course_post_type;
1509 $course_args = array(
1510 'post_type' => $course_post_type,
1511 'post_status' => 'publish',
1512 'post__in' => $course_ids,
1513 );
1514 return new \WP_Query($course_args);
1515 }
1516 return false;
1517 }
1518
1519
1520 /**
1521 * @param int $post_id
1522 *
1523 * @return string
1524 *
1525 * Get the video streaming URL by post/lesson/course ID
1526 */
1527 public function get_video_stream_url($post_id = 0){
1528 $post_id = $this->get_post_id($post_id);
1529 $post = get_post($post_id);
1530
1531 if ($post->post_type === tutor()->lesson_post_type ){
1532 $video_url = trailingslashit(home_url()).'video-url/'.$post->post_name;
1533 }else{
1534 $video_info = tutor_utils()->get_video_info($post_id);
1535 $video_url = $video_info->url;
1536 }
1537
1538 return $video_url;
1539 }
1540
1541 /**
1542 * @param int $lesson_id
1543 * @param int $user_id
1544 *
1545 * @return array|bool|mixed
1546 *
1547 * Get student lesson reading current info
1548 *
1549 * @since v.1.0.0
1550 */
1551 public function get_lesson_reading_info_full($lesson_id = 0, $user_id = 0){
1552 $lesson_id = $this->get_post_id($lesson_id);
1553 $user_id = $this->get_user_id($user_id);
1554
1555 $lesson_info = (array) maybe_unserialize(get_user_meta($user_id, '_lesson_reading_info', true));
1556 return $this->avalue_dot($lesson_id, $lesson_info);
1557 }
1558
1559 /**
1560 * @param int $post_id
1561 *
1562 * @return bool|false|int
1563 *
1564 * Get current post id or given post id
1565 *
1566 * @since v.1.0.0
1567 */
1568 public function get_post_id($post_id = 0){
1569 if ( ! $post_id){
1570 $post_id = get_the_ID();
1571 if ( ! $post_id){
1572 return false;
1573 }
1574 }
1575
1576 return $post_id;
1577 }
1578
1579 /**
1580 * @param int $user_id
1581 *
1582 * @return bool|int
1583 *
1584 * Get current user or given user ID
1585 *
1586 * @since v.1.0.0
1587 */
1588 public function get_user_id($user_id = 0){
1589 if ( ! $user_id){
1590 $user_id = get_current_user_id();
1591 if ( ! $user_id){
1592 return false;
1593 }
1594 }
1595
1596 return $user_id;
1597 }
1598
1599 /**
1600 * @param int $lesson_id
1601 * @param int $user_id
1602 * @param string $key
1603 *
1604 * @return array|bool|mixed
1605 *
1606 * Get lesson reading info by key
1607 *
1608 * @since v.1.0.0
1609 */
1610
1611 public function get_lesson_reading_info($lesson_id = 0, $user_id = 0, $key = ''){
1612 $lesson_id = $this->get_post_id($lesson_id);
1613 $user_id = $this->get_user_id($user_id);
1614
1615 $lesson_info = $this->get_lesson_reading_info_full($lesson_id, $user_id);
1616
1617 return $this->avalue_dot($key, $lesson_info);
1618 }
1619
1620 /**
1621 * @param int $lesson_id
1622 * @param int $user_id
1623 * @param array $data
1624 *
1625 * @return bool
1626 *
1627 * Update student lesson reading info
1628 *
1629 * @since v.1.0.0
1630 */
1631 public function update_lesson_reading_info($lesson_id = 0, $user_id = 0, $key = '', $value = ''){
1632 $lesson_id = $this->get_post_id($lesson_id);
1633 $user_id = $this->get_user_id($user_id);
1634
1635 if ($key && $value){
1636 $lesson_info = (array) maybe_unserialize(get_user_meta($user_id, '_lesson_reading_info', true));
1637 $lesson_info[$lesson_id][$key] = $value;
1638 update_user_meta($user_id, '_lesson_reading_info', $lesson_info);
1639 }
1640 }
1641
1642 /**
1643 * @param string $url
1644 *
1645 * @return bool
1646 *
1647 * Get the Youtube Video ID from URL
1648 *
1649 * @since v.1.0.0
1650 */
1651 public function get_youtube_video_id($url = ''){
1652 if (!$url){
1653 return false;
1654 }
1655 preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
1656
1657 if (isset($match[1])) {
1658 $youtube_id = $match[1];
1659 return $youtube_id;
1660 }
1661
1662 return false;
1663 }
1664
1665 /**
1666 * @param string $url
1667 *
1668 * @return bool
1669 *
1670 * Get the vimeo video id from URL
1671 *
1672 * @since v.1.0.0
1673 */
1674 public function get_vimeo_video_id($url = ''){
1675 if (preg_match('%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(?:[?]?.*)$%im', $url, $match)) {
1676 if (isset($match[3])){
1677 return $match[3];
1678 }
1679 }
1680 return false;
1681 }
1682
1683 /**
1684 * @param int $post_id
1685 *
1686 * Mark lesson complete
1687 *
1688 * @since v.1.0.0
1689 */
1690 public function mark_lesson_complete($post_id = 0, $user_id = 0){
1691 $post_id = $this->get_post_id($post_id);
1692 $user_id = $this->get_user_id($user_id);
1693 update_user_meta($user_id, '_tutor_completed_lesson_id_'.$post_id, time());
1694 }
1695
1696 /**
1697 * Saving enroll information to posts table
1698 * post_author = enrolled_student_id (wp_users id)
1699 * post_parent = enrolled course id
1700 *
1701 * @type: call when need
1702 * @return bool;
1703 *
1704 * @since v.1.0.0
1705 */
1706 public function do_enroll($course_id = 0, $order_id = 0){
1707 if ( ! $course_id){
1708 return false;
1709 }
1710
1711 do_action('tutor_before_enroll', $course_id);
1712 $user_id = get_current_user_id();
1713 $title = __('Course Enrolled', 'tutor')." &ndash; ".date_i18n(get_option('date_format')) .' @ '.date_i18n(get_option('time_format') ) ;
1714
1715 $enrolment_status = 'completed';
1716
1717 if ($this->is_course_purchasable($course_id)) {
1718 /**
1719 * We need to verify this enrollment, we will change the status later after payment confirmation
1720 */
1721 $enrolment_status = 'pending';
1722 }
1723
1724 $enroll_data = apply_filters('tutor_enroll_data',
1725 array(
1726 'post_type' => 'tutor_enrolled',
1727 'post_title' => $title,
1728 'post_status' => $enrolment_status,
1729 'post_author' => $user_id,
1730 'post_parent' => $course_id,
1731 )
1732 );
1733
1734 // Insert the post into the database
1735 $isEnrolled = wp_insert_post( $enroll_data );
1736 if ($isEnrolled) {
1737 do_action('tutor_after_enroll', $course_id, $isEnrolled);
1738
1739 //Mark Current User as Students with user meta data
1740 update_user_meta( $user_id, '_is_tutor_student', time() );
1741
1742 if ($order_id) {
1743 //Mark order for course and user
1744 $product_id = $this->get_course_product_id($course_id);
1745 update_post_meta( $isEnrolled, '_tutor_enrolled_by_order_id', $order_id );
1746 update_post_meta( $isEnrolled, '_tutor_enrolled_by_product_id', $product_id );
1747 update_post_meta( $order_id, '_is_tutor_order_for_course', time() );
1748 update_post_meta( $order_id, '_tutor_order_for_course_id_'.$course_id, $isEnrolled );
1749 }
1750 return true;
1751 }
1752
1753 return false;
1754 }
1755
1756 /**
1757 * @param $order_id
1758 *
1759 * Complete course enrollment and do some task
1760 *
1761 * @since v.1.0.0
1762 */
1763 public function complete_course_enroll($order_id){
1764 if ( ! tutor_utils()->is_tutor_order($order_id)){
1765 return;
1766 }
1767
1768 global $wpdb;
1769
1770 $enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id($order_id);
1771 if ($enrolled_ids_with_course){
1772 $enrolled_ids = wp_list_pluck($enrolled_ids_with_course, 'enrolled_id');
1773
1774 if (is_array($enrolled_ids) && count($enrolled_ids)){
1775 foreach ($enrolled_ids as $enrolled_id){
1776 $wpdb->update( $wpdb->posts, array( 'post_status' => 'completed' ), array( 'ID' => $enrolled_id ) );
1777 }
1778 }
1779 }
1780 }
1781
1782 /**
1783 * @param $order_id
1784 *
1785 * @return array|bool
1786 *
1787 * @since v.1.0.0
1788 */
1789 public function get_course_enrolled_ids_by_order_id($order_id){
1790 global $wpdb;
1791 //Getting all of courses ids within this order
1792
1793 $courses_ids = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE post_id = {$order_id} AND meta_key LIKE '_tutor_order_for_course_id_%' ");
1794
1795 if (is_array($courses_ids) && count($courses_ids)){
1796 $course_enrolled_by_order = array();
1797 foreach ($courses_ids as $courses_id){
1798 $course_id = str_replace('_tutor_order_for_course_id_', '',$courses_id->meta_key);
1799 //array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id))
1800 $course_enrolled_by_order[] = array('course_id' => $course_id, 'enrolled_id' => $courses_id->meta_value, 'order_id' => $courses_id->post_id );
1801 }
1802 return $course_enrolled_by_order;
1803 }
1804 return false;
1805 }
1806
1807 /**
1808 * Get wc product in efficient query
1809 *
1810 * @since v.1.0.0
1811 */
1812
1813 /**
1814 * @return array|null|object
1815 *
1816 * WooCommerce specific utils
1817 */
1818 public function get_wc_products_db(){
1819 global $wpdb;
1820 $query = $wpdb->get_results("SELECT ID, post_title from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'product' ");
1821
1822 return $query;
1823 }
1824
1825 /**
1826 * @return array|null|object
1827 *
1828 * Get EDD Products
1829 */
1830 public function get_edd_products(){
1831 global $wpdb;
1832 $query = $wpdb->get_results("SELECT ID, post_title from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'download' ");
1833
1834 return $query;
1835 }
1836
1837 /**
1838 * @param int $course_id
1839 *
1840 * @return int
1841 *
1842 * Get course productID
1843 *
1844 * @since v.1.0.0
1845 */
1846 public function get_course_product_id($course_id = 0){
1847 $course_id = $this->get_post_id($course_id);
1848 return (int) get_post_meta($course_id, '_tutor_course_product_id', true);
1849 }
1850
1851 /**
1852 * @param int $product_id
1853 *
1854 * @return array|null|object|void
1855 *
1856 * Get Product belongs with course
1857 *
1858 * @since v.1.0.0
1859 */
1860
1861 public function product_belongs_with_course($product_id = 0){
1862 global $wpdb;
1863
1864 $query = $wpdb->get_row("select * from {$wpdb->postmeta} WHERE meta_key='_tutor_course_product_id' AND meta_value = {$product_id} limit 1 ");
1865 return $query;
1866 }
1867
1868 /**
1869 * #End WooCommerce specific utils
1870 *
1871 * @since v.1.0.0
1872 */
1873
1874 public function get_enrolled_statuses(){
1875 return apply_filters(
1876 'tutor_get_enrolled_statuses',
1877 array (
1878 'pending',
1879 'processing',
1880 'on-hold',
1881 'completed',
1882 'cancelled',
1883 'refunded',
1884 'failed',
1885 )
1886 );
1887 }
1888
1889 /**
1890 * @param $order_id
1891 *
1892 * @return mixed
1893 *
1894 * determine is this a tutor order
1895 *
1896 * @since v.1.0.0
1897 */
1898 public function is_tutor_order($order_id){
1899 return get_post_meta($order_id, '_is_tutor_order_for_course', true);
1900 }
1901
1902 /**
1903 * @return mixed
1904 *
1905 * @deprecated
1906 */
1907 public function tutor_student_dashboard_pages(){
1908 _deprecated_function(__METHOD__, '1.1.2', 'tutor_dashboard_pages');
1909 return $this->tutor_dashboard_pages();
1910 }
1911
1912 /**
1913 * @return mixed
1914 *
1915 * Tutor Dashboard Pages
1916 *
1917 * @since v.1.0.0
1918 */
1919
1920 public function tutor_dashboard_pages(){
1921 $nav_items = array(
1922
1923 'index' => __('Dashboard', 'tutor'),
1924 'my-profile' => __('My Profile', 'tutor'),
1925 'enrolled-courses' => __('Enrolled Courses', 'tutor'),
1926 'my-courses' => __('My Courses', 'tutor'),
1927 'wishlist' => __('Wishlist', 'tutor'),
1928 'my-reviews' => __('My Reviews', 'tutor'),
1929 'quiz-attempts' => __('Quiz Attempts', 'tutor'),
1930 'earning' => __('Earning', 'tutor'),
1931 'withdraw' => __('Withdraw', 'tutor'),
1932 //'purchase-history' => __('Purchase History', 'tutor'),
1933 //'messages' => __('Messages', 'tutor'),
1934 //'settings' => __('Settings', 'tutor'),
1935 'logout' => __('Logout', 'tutor'),
1936 );
1937
1938 return apply_filters('tutor_dashboard/student/pages', $nav_items);
1939 }
1940
1941 /**
1942 * @param string $page_key
1943 * @param int $page_id
1944 *
1945 * @return string
1946 *
1947 * Get tutor dashboard page single URL
1948 *
1949 * @since v.1.0.0
1950 */
1951 public function get_tutor_dashboard_page_permalink($page_key = '', $page_id = 0){
1952 if ($page_key === 'index'){
1953 $page_key = '';
1954 }
1955 $page_id = $this->get_post_id($page_id);
1956 return trailingslashit(get_permalink($page_id)).$page_key;
1957 }
1958
1959 /**
1960 * @param string $input
1961 *
1962 * @return array|bool|mixed|string
1963 *
1964 * Get old input
1965 *
1966 * @since v.1.0.0
1967 */
1968 public function input_old($input = ''){
1969 $value = $this->avalue_dot($input, $_REQUEST);
1970 if ($value){
1971 return $value;
1972 }
1973 return '';
1974 }
1975
1976 /**
1977 * @param int $user_id
1978 *
1979 * @return mixed
1980 *
1981 * Determine if is instructor or not
1982 *
1983 * @since v.1.0.0
1984 */
1985 public function is_instructor($user_id = 0){
1986 $user_id = $this->get_user_id($user_id);
1987 return get_user_meta($user_id, '_is_tutor_instructor', true);
1988 }
1989
1990 /**
1991 * @param int $user_id
1992 * @param bool $status_name
1993 *
1994 * @return bool|mixed
1995 *
1996 * Instructor status
1997 *
1998 * @since v.1.0.0
1999 */
2000 public function instructor_status($user_id = 0, $status_name = true){
2001 $user_id = $this->get_user_id($user_id);
2002
2003 $instructor_status = apply_filters('tutor_instructor_statuses', array(
2004 'pending' => __('Pending', 'tutor'),
2005 'approved' => __('Approved', 'tutor'),
2006 'blocked' => __('Blocked', 'tutor'),
2007 ));
2008
2009 $status = get_user_meta($user_id, '_tutor_instructor_status', true);
2010
2011 if (isset($instructor_status[$status])){
2012 if ( ! $status_name){
2013 return $status;
2014 }
2015 return $instructor_status[$status];
2016 }
2017 return false;
2018 }
2019
2020 /**
2021 * @param string $search_term
2022 *
2023 * @return int
2024 *
2025 * Get total number of instructors
2026 *
2027 * @since v.1.0.0
2028 */
2029
2030 public function get_total_instructors($search_term = ''){
2031 $meta_key = '_is_tutor_instructor';
2032
2033 global $wpdb;
2034
2035 if ($search_term){
2036 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2037 }
2038
2039 $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 ");
2040
2041 return (int) $count;
2042 }
2043
2044 /**
2045 * @param int $start
2046 * @param int $limit
2047 * @param string $search_term
2048 *
2049 * @return array|null|object
2050 *
2051 * Get all instructors
2052 *
2053 * @since v.1.0.0
2054 */
2055 public function get_instructors($start = 0, $limit = 10, $search_term = ''){
2056 $meta_key = '_is_tutor_instructor';
2057 global $wpdb;
2058
2059 if ($search_term){
2060 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2061 }
2062
2063 $instructors = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
2064 INNER JOIN {$wpdb->usermeta}
2065 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
2066 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
2067 ORDER BY {$wpdb->usermeta}.meta_value DESC
2068 LIMIT {$start}, {$limit} ");
2069
2070 return $instructors;
2071 }
2072
2073 /**
2074 * @param int $course_id
2075 *
2076 * @return array|bool|null|object
2077 *
2078 * Get all instructors by course
2079 *
2080 * @since v.1.0.0
2081 */
2082 public function get_instructors_by_course($course_id = 0){
2083 global $wpdb;
2084 $course_id = $this->get_post_id($course_id);
2085
2086 $instructors = $wpdb->get_results("select ID, display_name,
2087 get_course.meta_value as taught_course_id,
2088 tutor_job_title.meta_value as tutor_profile_job_title,
2089 tutor_bio.meta_value as tutor_profile_bio,
2090 tutor_photo.meta_value as tutor_profile_photo
2091 from {$wpdb->users}
2092 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}
2093 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2094 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2095 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2096 ");
2097
2098 if (is_array($instructors) && count($instructors)){
2099 return $instructors;
2100 }
2101
2102 return false;
2103 }
2104
2105 /**
2106 * @param $instructor_id
2107 *
2108 * Get total Students by instructor
2109 * 1 enrollment = 1 student, so total enrolled for a equivalent total students (Tricks)
2110 *
2111 * @return int
2112 *
2113 * @since v.1.0.0
2114 */
2115
2116 public function get_total_students_by_instructor($instructor_id){
2117 global $wpdb;
2118
2119 $course_post_type = tutor()->course_post_type;
2120 $count = $wpdb->get_var("SELECT COUNT(courses.ID) from {$wpdb->posts} courses
2121
2122 INNER JOIN {$wpdb->posts} enrolled ON courses.ID = enrolled.post_parent AND enrolled.post_type = 'tutor_enrolled'
2123 WHERE courses.post_status = 'publish'
2124 AND courses.post_type = '{$course_post_type}'
2125 AND courses.post_author = {$instructor_id} ; ");
2126 return (int) $count;
2127 }
2128
2129 /**
2130 * @param float $input
2131 *
2132 * @return float|string
2133 *
2134 * Get rating format from value
2135 *
2136 * @since v.1.0.0
2137 */
2138 public function get_rating_value($input = 0.00){
2139
2140 if ( $input > 0){
2141 $input = number_format($input, 2);
2142 $int_value = (int) $input;
2143 $fraction = $input - $int_value;
2144
2145 if ($fraction == 0){
2146 $fraction = 0.00;
2147 }elseif($fraction > 0.5){
2148 $fraction = 1;
2149 }else{
2150 $fraction = 0.5;
2151 }
2152
2153 return number_format( ($int_value + $fraction), 2);
2154 }
2155 return 0.00;
2156 }
2157
2158 /**
2159 * @param float $current_rating
2160 * @param bool $echo
2161 *
2162 * @return string
2163 *
2164 * Generate star rating based in given rating value
2165 *
2166 * @since v.1.0.0
2167 */
2168 public function star_rating_generator($current_rating = 0.00, $echo = true){
2169 $output = '<div class="tutor-star-rating-group">';
2170
2171 for ($i = 1; $i <=5 ; $i++){
2172 $intRating = (int) $current_rating;
2173
2174 if ($intRating >= $i){
2175 $output.= '<i class="tutor-icon-star-full" data-rating-value="'.$i.'"></i>';
2176 } else{
2177 if ( ($current_rating - $i) == -0.5){
2178 $output.= '<i class="tutor-icon-star-half" data-rating-value="'.$i.'"></i>';
2179 }else{
2180 $output.= '<i class="tutor-icon-star-line" data-rating-value="'.$i.'"></i>';
2181 }
2182 }
2183 }
2184
2185 $output .= "<div class='tutor-rating-gen-input'><input type='hidden' name='tutor_rating_gen_input' value='{$current_rating}' /> </div>";
2186
2187 $output .= "</div>";
2188
2189 if ($echo){
2190 echo $output;
2191 }
2192 return $output;
2193 }
2194
2195 /**
2196 * @param null $name
2197 *
2198 * @return string
2199 *
2200 * Generate text to avatar
2201 *
2202 * @since v.1.0.0
2203 */
2204 public function get_tutor_avatar($user_id = null, $size = 'thumbnail'){
2205 global $wpdb;
2206
2207 if ( ! $user_id){
2208 return '';
2209 }
2210
2211 $user = $this->get_tutor_user($user_id);
2212 if ($user->tutor_profile_photo){
2213 return '<img src="'.wp_get_attachment_image_url($user->tutor_profile_photo, $size).'" class="tutor-image-avatar" alt="" /> ';
2214 }
2215
2216 $name = $user->display_name;
2217 $arr = explode(' ', trim($name));
2218
2219 if (count($arr) > 1){
2220 $first_char = substr($arr[0], 0, 1) ;
2221 $second_char = substr($arr[1], 0, 1) ;
2222 }else{
2223 $first_char = substr($arr[0], 0, 1) ;
2224 $second_char = substr($arr[0], 1, 1) ;
2225 }
2226
2227 $initial_avatar = strtoupper($first_char.$second_char);
2228
2229 $bg_color = '#'.substr(md5($initial_avatar), 0, 6);
2230 $initial_avatar = "<span class='tutor-text-avatar' style='background-color: {$bg_color}; color: #fff8e5'>{$initial_avatar}</span>";
2231
2232 return $initial_avatar;
2233 }
2234
2235 /**
2236 * @param $user_id
2237 *
2238 * @return array|null|object|void
2239 *
2240 * Get tutor user
2241 *
2242 * @since v.1.0.0
2243 */
2244
2245 public function get_tutor_user($user_id){
2246 global $wpdb;
2247
2248 $user = $wpdb->get_row("select ID, display_name,
2249 tutor_job_title.meta_value as tutor_profile_job_title,
2250 tutor_bio.meta_value as tutor_profile_bio,
2251 tutor_photo.meta_value as tutor_profile_photo
2252
2253 from {$wpdb->users}
2254 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2255 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2256 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2257
2258 WHERE ID = {$user_id} ");
2259 return $user;
2260 }
2261
2262 /**
2263 * @param int $course_id
2264 * @param int $offset
2265 * @param int $limit
2266 *
2267 * @return array|null|object
2268 *
2269 * get course reviews
2270 *
2271 * @since v.1.0.0
2272 */
2273 public function get_course_reviews($course_id = 0, $offset = 0, $limit = 150){
2274 $course_id = $this->get_post_id($course_id);
2275 global $wpdb;
2276
2277 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2278 {$wpdb->comments}.comment_post_ID,
2279 {$wpdb->comments}.comment_author,
2280 {$wpdb->comments}.comment_author_email,
2281 {$wpdb->comments}.comment_date,
2282 {$wpdb->comments}.comment_content,
2283 {$wpdb->comments}.user_id,
2284 {$wpdb->commentmeta}.meta_value as rating,
2285 {$wpdb->users}.display_name
2286
2287 from {$wpdb->comments}
2288 INNER JOIN {$wpdb->commentmeta}
2289 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2290 INNER JOIN {$wpdb->users}
2291 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2292 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2293 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2294 );
2295
2296 return $reviews;
2297 }
2298
2299 /**
2300 * @param int $course_id
2301 *
2302 * @return object
2303 *
2304 * Get course rating
2305 *
2306 * @since v.1.0.0
2307 */
2308 public function get_course_rating($course_id = 0){
2309 $course_id = $this->get_post_id($course_id);
2310
2311 $ratings = array(
2312 'rating_count' => 0,
2313 'rating_sum' => 0,
2314 'rating_avg' => 0.00,
2315 'count_by_value' => array(5 => 0, 4 => 0, 3 => 0, 2 => 0, 1 => 0)
2316 );
2317
2318 global $wpdb;
2319
2320 $rating = $wpdb->get_row("select COUNT(meta_value) as rating_count, SUM(meta_value) as rating_sum
2321 from {$wpdb->comments}
2322 INNER JOIN {$wpdb->commentmeta}
2323 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2324 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2325 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2326 AND meta_key = 'tutor_rating' ;"
2327 );
2328
2329 if ($rating->rating_count){
2330 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2331
2332 /**
2333 * Get individual Rating by integer
2334 */
2335 $five_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2336 from {$wpdb->comments}
2337 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2338 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2339 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2340 AND meta_key = 'tutor_rating' AND meta_value = 5 ;"
2341 );
2342 $four_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2343 from {$wpdb->comments}
2344 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2345 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2346 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2347 AND meta_key = 'tutor_rating' AND meta_value = 4 ;"
2348 );
2349 $three_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2350 from {$wpdb->comments}
2351 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2352 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2353 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2354 AND meta_key = 'tutor_rating' AND meta_value = 3 ;"
2355 );
2356 $two_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2357 from {$wpdb->comments}
2358 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2359 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2360 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2361 AND meta_key = 'tutor_rating' AND meta_value = 2 ;"
2362 );
2363 $one_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2364 from {$wpdb->comments}
2365 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2366 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2367 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2368 AND meta_key = 'tutor_rating' AND meta_value = 1 ;"
2369 );
2370
2371 $ratings = array(
2372 'rating_count' => $rating->rating_count,
2373 'rating_sum' => $rating->rating_sum,
2374 'rating_avg' => $avg_rating,
2375 'count_by_value' => array(5 => $five_stars_count, 4 => $four_stars_count, 3 => $three_stars_count, 2 => $two_stars_count, 1 => $one_stars_count)
2376 );
2377
2378 }
2379
2380 return (object) $ratings;
2381 }
2382
2383 /**
2384 * @param int $user_id
2385 * @param int $offset
2386 * @param int $limit
2387 *
2388 * @return array|null|object
2389 *
2390 * Get reviews by a user
2391 *
2392 * @since v.1.0.0
2393 */
2394 public function get_reviews_by_user($user_id = 0, $offset = 0, $limit = 150){
2395 $user_id = $this->get_user_id($user_id);
2396 global $wpdb;
2397
2398 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2399 {$wpdb->comments}.comment_post_ID,
2400 {$wpdb->comments}.comment_author,
2401 {$wpdb->comments}.comment_author_email,
2402 {$wpdb->comments}.comment_date,
2403 {$wpdb->comments}.comment_content,
2404 {$wpdb->comments}.user_id,
2405 {$wpdb->commentmeta}.meta_value as rating,
2406 {$wpdb->users}.display_name
2407
2408 from {$wpdb->comments}
2409 INNER JOIN {$wpdb->commentmeta}
2410 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2411 INNER JOIN {$wpdb->users}
2412 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2413 WHERE {$wpdb->comments}.user_id = {$user_id}
2414 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2415 );
2416
2417 return $reviews;
2418 }
2419
2420 /**
2421 * @param $instructor_id
2422 *
2423 * @return object
2424 *
2425 * Get instructors rating
2426 *
2427 * @since v.1.0.0
2428 */
2429 public function get_instructor_ratings($instructor_id){
2430 global $wpdb;
2431
2432 $ratings = array(
2433 'rating_count' => 0,
2434 'rating_sum' => 0,
2435 'rating_avg' => 0.00,
2436 );
2437
2438 $rating = $wpdb->get_row("SELECT COUNT(rating.meta_value) as rating_count, SUM(rating.meta_value) as rating_sum
2439 FROM {$wpdb->usermeta} courses
2440 INNER JOIN {$wpdb->comments} reviews ON courses.meta_value = reviews.comment_post_ID AND reviews.comment_type = 'tutor_course_rating'
2441 INNER JOIN {$wpdb->commentmeta} rating ON reviews.comment_ID = rating.comment_id AND rating.meta_key = 'tutor_rating'
2442 WHERE courses.user_id = {$instructor_id} AND courses.meta_key = '_tutor_instructor_course_id'");
2443
2444 if ($rating->rating_count){
2445 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2446
2447 $ratings = array(
2448 'rating_count' => $rating->rating_count,
2449 'rating_sum' => $rating->rating_sum,
2450 'rating_avg' => $avg_rating,
2451 );
2452 }
2453
2454 return (object) $ratings;
2455 }
2456
2457 /**
2458 * @param int $course_id
2459 * @param int $user_id
2460 *
2461 * @return object
2462 *
2463 * Get course rating by user
2464 *
2465 * @since v.1.0.0
2466 */
2467 public function get_course_rating_by_user($course_id = 0, $user_id = 0){
2468 $course_id = $this->get_post_id($course_id);
2469 $user_id = $this->get_user_id($user_id);
2470
2471 $ratings = array(
2472 'rating' => 0,
2473 'review' => '',
2474 );
2475
2476 global $wpdb;
2477
2478 $rating = $wpdb->get_row("select meta_value as rating, comment_content as review from {$wpdb->comments}
2479 INNER JOIN {$wpdb->commentmeta}
2480 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2481 WHERE {$wpdb->comments}.comment_post_ID = {$course_id} AND user_id = {$user_id}
2482 AND meta_key = 'tutor_rating' ;"
2483 );
2484
2485 if ($rating){
2486 $rating_format = number_format($rating->rating, 2);
2487
2488 $ratings = array(
2489 'rating' => $rating_format,
2490 'review' => $rating->review,
2491 );
2492 }
2493 return (object) $ratings;
2494 }
2495
2496 /**
2497 * @param int $user_id
2498 *
2499 * @return null|string
2500 *
2501 * @since v.1.0.0
2502 */
2503 public function count_reviews_wrote_by_user($user_id = 0){
2504 global $wpdb;
2505 $user_id = $this->get_user_id($user_id);
2506
2507 $count_reviews = $wpdb->get_var("SELECT COUNT(comment_ID) from {$wpdb->comments} WHERE user_id = {$user_id} AND comment_type = 'tutor_course_rating' ");
2508 return $count_reviews;
2509 }
2510
2511 /**
2512 * @param $size
2513 *
2514 * @return bool|int|string
2515 *
2516 * This function transforms the php.ini notation for numbers (like '2M') to an integer.
2517 *
2518 * @since v.1.0.0
2519 */
2520
2521 function let_to_num( $size ) {
2522 $l = substr( $size, -1 );
2523 $ret = substr( $size, 0, -1 );
2524 $byte = 1024;
2525
2526 switch ( strtoupper( $l ) ) {
2527 case 'P':
2528 $ret *= 1024;
2529 // No break.
2530 case 'T':
2531 $ret *= 1024;
2532 // No break.
2533 case 'G':
2534 $ret *= 1024;
2535 // No break.
2536 case 'M':
2537 $ret *= 1024;
2538 // No break.
2539 case 'K':
2540 $ret *= 1024;
2541 // No break.
2542 }
2543 return $ret;
2544 }
2545
2546 /**
2547 * @return array
2548 *
2549 * Get Database version
2550 *
2551 * @since v.1.0.0
2552 */
2553 function get_db_version() {
2554 global $wpdb;
2555
2556 if ( empty( $wpdb->is_mysql ) ) {
2557 return array(
2558 'string' => '',
2559 'number' => '',
2560 );
2561 }
2562
2563 if ( $wpdb->use_mysqli ) {
2564 $server_info = mysqli_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2565 } else {
2566 $server_info = mysql_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2567 }
2568
2569 return array(
2570 'string' => $server_info,
2571 'number' => preg_replace( '/([^\d.]+).*/', '', $server_info ),
2572 );
2573 }
2574
2575 public function help_tip($tip = ''){
2576 return '<span class="tutor-help-tip" data-tip="' . $tip . '"></span>';
2577 }
2578
2579 /**
2580 * @param int $course_id
2581 * @param int $user_id
2582 * @param int $offset
2583 * @param int $limit
2584 *
2585 * @return array|null|object
2586 *
2587 * Get top question
2588 *
2589 * @since v.1.0.0
2590 */
2591 public function get_top_question($course_id = 0, $user_id = 0, $offset = 0, $limit = 20){
2592 $course_id = $this->get_post_id($course_id);
2593 $user_id = $this->get_user_id($user_id);
2594
2595 global $wpdb;
2596
2597 $questions = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2598 {$wpdb->comments}.comment_post_ID,
2599 {$wpdb->comments}.comment_author,
2600 {$wpdb->comments}.comment_date,
2601 {$wpdb->comments}.comment_content,
2602 {$wpdb->comments}.user_id,
2603 {$wpdb->commentmeta}.meta_value as question_title,
2604 {$wpdb->users}.display_name
2605
2606 from {$wpdb->comments}
2607 INNER JOIN {$wpdb->commentmeta}
2608 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2609 INNER JOIN {$wpdb->users}
2610 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2611 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2612 AND {$wpdb->comments}.user_id = {$user_id}
2613 AND {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2614 AND meta_key = 'tutor_question_title' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2615 );
2616
2617 return $questions;
2618 }
2619
2620 /**
2621 * @param string $search_term
2622 *
2623 * @return int
2624 *
2625 * Get total number of Q&A questions
2626 *
2627 * @since v.1.0.0
2628 */
2629 public function get_total_qa_question($search_term = ''){
2630 global $wpdb;
2631
2632 if ($search_term){
2633 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2634 }
2635
2636 $user_id = get_current_user_id();
2637 $course_type = tutor()->course_post_type;
2638
2639 $in_question_id_query = '';
2640 /**
2641 * Get only assinged courses questions if current user is a
2642 */
2643 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2644 $get_course_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_author = {$user_id} AND post_type = '{$course_type}' AND post_status = 'publish' " );
2645 $get_assigned_courses_ids = $wpdb->get_col( "SELECT meta_value from {$wpdb->usermeta} WHERE meta_key = '_tutor_instructor_course_id' AND user_id = {$user_id} " );
2646 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2647
2648 if ( $this->count( $my_course_ids ) ) {
2649 $implode_ids = implode( ',', $my_course_ids );
2650 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2651 }
2652 }
2653
2654 $count = $wpdb->get_var("SELECT COUNT({$wpdb->comments}.comment_ID) FROM {$wpdb->comments}
2655 INNER JOIN {$wpdb->commentmeta}
2656 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2657 WHERE comment_type = 'tutor_q_and_a' AND comment_parent = 0 {$in_question_id_query} {$search_term} ");
2658
2659 return (int) $count;
2660 }
2661
2662 /**
2663 * @param int $start
2664 * @param int $limit
2665 * @param string $search_term
2666 *
2667 * @return array|null|object
2668 *
2669 *
2670 * Get question and answer query
2671 *
2672 * @since v.1.0.0
2673 */
2674 public function get_qa_questions($start = 0, $limit = 10, $search_term = '') {
2675 global $wpdb;
2676
2677 if ($search_term){
2678 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2679 }
2680
2681 $user_id = get_current_user_id();
2682 $course_type = tutor()->course_post_type;
2683
2684 $in_question_id_query = '';
2685 /**
2686 * Get only assinged courses questions if current user is a
2687 */
2688 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2689 $get_course_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_author = {$user_id} AND post_type = '{$course_type}' AND post_status = 'publish' " );
2690 $get_assigned_courses_ids = $wpdb->get_col( "SELECT meta_value from {$wpdb->usermeta} WHERE meta_key = '_tutor_instructor_course_id' AND user_id = {$user_id} " );
2691 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2692
2693 if ( $this->count( $my_course_ids ) ) {
2694 $implode_ids = implode( ',', $my_course_ids );
2695 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2696 }
2697 }
2698
2699 $query = $wpdb->get_results("SELECT
2700 {$wpdb->comments}.comment_ID,
2701 {$wpdb->comments}.comment_post_ID,
2702 {$wpdb->comments}.comment_author,
2703 {$wpdb->comments}.comment_date,
2704 {$wpdb->comments}.comment_content,
2705 {$wpdb->comments}.user_id,
2706 {$wpdb->commentmeta}.meta_value as question_title,
2707 {$wpdb->users}.display_name,
2708 {$wpdb->posts}.post_title,
2709
2710 (SELECT COUNT(answers_t.comment_ID) FROM {$wpdb->comments} answers_t
2711 WHERE answers_t.comment_parent = {$wpdb->comments}.comment_ID ) as answer_count
2712
2713 FROM {$wpdb->comments}
2714
2715 INNER JOIN {$wpdb->commentmeta}
2716 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2717
2718 INNER JOIN {$wpdb->posts}
2719 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2720
2721 INNER JOIN {$wpdb->users}
2722 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2723
2724 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_parent = 0 {$search_term}
2725 {$in_question_id_query}
2726 ORDER BY {$wpdb->comments}.comment_ID DESC
2727 LIMIT {$start},{$limit}; ");
2728
2729 return $query;
2730 }
2731
2732 /**
2733 * @param $question_id
2734 *
2735 * @return array|null|object|void
2736 *
2737 * Get question for Q&A
2738 *
2739 * @since v.1.0.0
2740 */
2741 public function get_qa_question($question_id){
2742 global $wpdb;
2743 $query = $wpdb->get_row("SELECT
2744 {$wpdb->comments}.comment_ID,
2745 {$wpdb->comments}.comment_post_ID,
2746 {$wpdb->comments}.comment_author,
2747 {$wpdb->comments}.comment_date,
2748 {$wpdb->comments}.comment_content,
2749 {$wpdb->comments}.user_id,
2750 {$wpdb->commentmeta}.meta_value as question_title,
2751 {$wpdb->users}.display_name,
2752 {$wpdb->posts}.post_title
2753
2754 FROM {$wpdb->comments}
2755 INNER JOIN {$wpdb->commentmeta}
2756 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2757
2758 INNER JOIN {$wpdb->posts}
2759 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2760
2761 INNER JOIN {$wpdb->users}
2762 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2763 WHERE comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_ID = {$question_id}");
2764
2765 return $query;
2766 }
2767
2768 /**
2769 * @param $question_id
2770 *
2771 * @return array|null|object
2772 *
2773 * Get question and asnwer by question
2774 */
2775 public function get_qa_answer_by_question($question_id){
2776 global $wpdb;
2777 $query = $wpdb->get_results("SELECT
2778 {$wpdb->comments}.comment_ID,
2779 {$wpdb->comments}.comment_post_ID,
2780 {$wpdb->comments}.comment_author,
2781 {$wpdb->comments}.comment_date,
2782 {$wpdb->comments}.comment_content,
2783 {$wpdb->comments}.comment_parent,
2784 {$wpdb->comments}.user_id,
2785 {$wpdb->users}.display_name
2786
2787 FROM {$wpdb->comments}
2788
2789 INNER JOIN {$wpdb->users}
2790 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2791 WHERE comment_type = 'tutor_q_and_a'
2792 AND {$wpdb->comments}.comment_parent = {$question_id} ORDER BY {$wpdb->comments}.comment_ID ASC ");
2793
2794 return $query;
2795 }
2796
2797 public function unanswered_question_count(){
2798 global $wpdb;
2799
2800 $count = $wpdb->get_var("select COUNT({$wpdb->comments}.comment_ID)
2801 from {$wpdb->comments}
2802 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2803 AND {$wpdb->comments}.comment_approved = 'waiting_for_answer'
2804 AND {$wpdb->comments}.comment_parent = 0;");
2805 return (int) $count;
2806 }
2807
2808 /**
2809 * @param int $course_id
2810 *
2811 * @return array|null|object
2812 *
2813 * Return all of announcements for a course
2814 *
2815 * @since v.1.0.0
2816 */
2817 public function get_announcements($course_id = 0){
2818 $course_id = $this->get_post_id($course_id);
2819 global $wpdb;
2820
2821 $query = $wpdb->get_results("select {$wpdb->posts}.ID, post_author, post_date, post_content, post_title, display_name
2822 from {$wpdb->posts}
2823 INNER JOIN {$wpdb->users} ON post_author = {$wpdb->users}.ID
2824 WHERE post_type = 'tutor_announcements'
2825 AND post_parent = {$course_id} ORDER BY {$wpdb->posts}.ID DESC;");
2826 return $query;
2827 }
2828
2829 /**
2830 * @param string $content
2831 *
2832 * @return mixed
2833 *
2834 * Announcement content
2835 *
2836 * @since v.1.0.0
2837 */
2838
2839 public function announcement_content($content = ''){
2840 $search = array('{user_display_name}');
2841
2842 $user_display_name = 'User';
2843 if (is_user_logged_in()){
2844 $user = wp_get_current_user();
2845 $user_display_name = $user->display_name;
2846 }
2847 $replace = array($user_display_name);
2848
2849 return str_replace($search, $replace, $content);
2850 }
2851
2852 /**
2853 * @param int $post_id
2854 * @param string $option_key
2855 * @param bool $default
2856 *
2857 * @return array|bool|mixed
2858 *
2859 * Get the quiz option from meta
2860 */
2861 public function get_quiz_option($post_id = 0, $option_key = '', $default = false){
2862 $post_id = $this->get_post_id($post_id);
2863 $get_option_meta = maybe_unserialize(get_post_meta($post_id, 'tutor_quiz_option', true));
2864
2865 if ( ! $option_key && ! empty($get_option_meta)) {
2866 return $get_option_meta;
2867 }
2868
2869 $value = $this->avalue_dot( $option_key, $get_option_meta );
2870 if ( $value ) {
2871 return $value;
2872 }
2873 return $default;
2874 }
2875
2876
2877 /**
2878 * @param int $quiz_id
2879 *
2880 * @return array|bool|null|object
2881 *
2882 * Get the questions by quiz ID
2883 */
2884 public function get_questions_by_quiz($quiz_id = 0){
2885 $quiz_id = $this->get_post_id($quiz_id);
2886 global $wpdb;
2887
2888 //$questions = $wpdb->get_results("SELECT ID, post_content, post_title, post_parent from {$wpdb->posts} WHERE post_type = 'tutor_question'
2889 // AND post_parent = {$quiz_id} ORDER BY menu_order ASC ");
2890
2891 $questions = $wpdb->get_results("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY question_order ASC ");
2892
2893 if (is_array($questions) && count($questions)){
2894 return $questions;
2895 }
2896 return false;
2897 }
2898
2899 /**
2900 * @param int $question_id
2901 *
2902 * @return array|bool|object|void|null
2903 *
2904 * Get Quiz question by question id
2905 */
2906 public function get_quiz_question_by_id($question_id = 0){
2907 global $wpdb;
2908
2909 if ($question_id){
2910 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} LIMIT 0,1 ;");
2911 return $question;
2912 }
2913
2914 return false;
2915 }
2916
2917 /**
2918 * @param null $type
2919 *
2920 * @return array|mixed
2921 *
2922 * Get all question types
2923 *
2924 * @since v.1.0.0
2925 */
2926
2927 public function get_question_types($type = null){
2928 $types = array(
2929 'true_false' => array('name' => __('True/False', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-yes-no"></i>', 'is_pro' => false),
2930 'single_choice' => array('name' => __('Single Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-mark"></i>', 'is_pro' => false),
2931 'multiple_choice' => array('name' => __('Multiple Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-multiple-choice"></i>', 'is_pro' => false),
2932 'open_ended' => array('name' => __('Open Ended/Essay', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-open-ended"></i>', 'is_pro' => false),
2933 'fill_in_the_blank' => array('name' => __('Fill In The Blank', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-fill-gaps"></i>', 'is_pro' => false),
2934 'short_answer' => array('name' => __('Short Answer', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-short-ans"></i>', 'is_pro' => true),
2935 'matching' => array('name' => __('Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-matching"></i>', 'is_pro' => true),
2936 'image_matching' => array('name' => __('Image Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-matching"></i>', 'is_pro' => true),
2937 'image_answering' => array('name' => __('Image Answering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-ans"></i>', 'is_pro' => true),
2938 'ordering' => array('name' => __('Ordering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-ordering"></i>', 'is_pro' => true),
2939 );
2940
2941 if (isset($types[$type])){
2942 return $types[$type];
2943 }
2944 return $types;
2945 }
2946
2947 public function get_quiz_answer_options_by_question($question_id){
2948 global $wpdb;
2949
2950 $answer_options = $wpdb->get_results("select
2951 {$wpdb->comments}.comment_ID,
2952 {$wpdb->comments}.comment_post_ID,
2953 {$wpdb->comments}.comment_content
2954
2955 FROM {$wpdb->comments}
2956 WHERE {$wpdb->comments}.comment_post_ID = {$question_id}
2957 AND {$wpdb->comments}.comment_type = 'quiz_answer_option'
2958 ORDER BY {$wpdb->comments}.comment_karma ASC ;");
2959
2960 if (is_array($answer_options) && count($answer_options)){
2961 return $answer_options;
2962 }
2963 return false;
2964 }
2965
2966 /**
2967 * @param $quiz_id
2968 *
2969 * @return int
2970 *
2971 * Get the next question order ID
2972 *
2973 * @since v.1.0.0
2974 */
2975
2976 public function quiz_next_question_order_id($quiz_id){
2977 global $wpdb;
2978
2979 //$last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$quiz_id} AND post_type =
2980 // 'tutor_question';");
2981
2982 $last_order = (int) $wpdb->get_var("SELECT MAX(question_order) FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ;");
2983 return $last_order + 1;
2984 }
2985
2986 /**
2987 * @param $quiz_id
2988 *
2989 * @return int
2990 *
2991 * new design quiz question
2992 * @since v.1.0.0
2993 */
2994 public function quiz_next_question_id(){
2995 global $wpdb;
2996
2997 $last_order = (int) $wpdb->get_var("SELECT MAX(question_id) FROM {$wpdb->prefix}tutor_quiz_questions;");
2998 return $last_order + 1;
2999 }
3000
3001 public function get_quiz_id_by_question($question_id){
3002 global $wpdb;
3003
3004 $quiz_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$question_id} AND post_type = 'tutor_question' ;");
3005 return $quiz_id;
3006 }
3007
3008 /**
3009 * @param array $config
3010 *
3011 * @return array|bool|null|object
3012 *
3013 * It was used in previous quiz algorithm
3014 *
3015 * @deprecated
3016 *
3017 * @since v.1.0.0
3018 */
3019 public function get_unattached_quiz($config = array()){
3020 global $wpdb;
3021
3022 $default_attr = array(
3023 'search_term' => '',
3024 'start' => '0',
3025 'limit' => '10',
3026 'order' => 'DESC',
3027 'order_by' => 'ID',
3028 );
3029 $attr = array_merge($default_attr, $config);
3030 extract($attr);
3031
3032 $search_query = '';
3033 if (! empty($search_term)){
3034 $search_query = "AND post_title LIKE '%{$search_term}%'";
3035 }
3036
3037 $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} ");
3038
3039 if (is_array($questions) && count($questions)){
3040 return $questions;
3041 }
3042 return false;
3043 }
3044
3045 /**
3046 * @param int $post_id
3047 *
3048 * @return array|bool|null|object
3049 *
3050 * @since v.1.0.0
3051 */
3052 public function get_attached_quiz($post_id = 0){
3053 global $wpdb;
3054
3055 $post_id = $this->get_post_id($post_id);
3056
3057 $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}");
3058
3059 if (is_array($questions) && count($questions)){
3060 return $questions;
3061 }
3062 return false;
3063 }
3064
3065 /**
3066 * @param $quiz_id
3067 *
3068 * @return array|bool|null|object|void
3069 *
3070 * Get course by quiz
3071 *
3072 * @since v.1.0.0
3073 */
3074
3075 public function get_course_by_quiz($quiz_id){
3076 global $wpdb;
3077
3078 $quiz_id = $this->get_post_id($quiz_id);
3079 $post = get_post($quiz_id);
3080
3081 if ($post) {
3082 $course_post_type = tutor()->course_post_type;
3083 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$post->post_parent} " );
3084
3085 if ($course) {
3086 //Checking if this topic
3087 if ( $course->post_type !== $course_post_type ) {
3088 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
3089 }
3090 //Checking if this lesson
3091 if ( $course->post_type !== $course_post_type ) {
3092 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
3093 }
3094
3095 return $course;
3096 }
3097 }
3098
3099 return false;
3100 }
3101
3102 /**
3103 * @param $quiz_id
3104 *
3105 * @return int
3106 *
3107 * @since v.1.0.0
3108 */
3109 public function total_questions_for_student_by_quiz($quiz_id){
3110 $quiz_id = $this->get_post_id($quiz_id);
3111 global $wpdb;
3112
3113 $total_question = (int) $wpdb->get_var("select count(ID) from {$wpdb->posts} where post_parent = {$quiz_id} AND post_type = 'tutor_question' ");
3114
3115 return $total_question;
3116 }
3117
3118 /**
3119 * @param int $quiz_id
3120 *
3121 * @return array|null|object|void
3122 *
3123 * Determine if there is any started quiz exists
3124 *
3125 * @since v.1.0.0
3126 */
3127
3128 public function is_started_quiz($quiz_id = 0){
3129 global $wpdb;
3130
3131 $quiz_id = $this->get_post_id($quiz_id);
3132 $user_id = get_current_user_id();
3133
3134 $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' ");
3135
3136 return $is_started;
3137 }
3138
3139 /**
3140 * @param $quiz_id
3141 *
3142 * Method for get the total amount of question for a quiz
3143 * Student will answer this amount of question, one quiz have many question
3144 * but student will answer a specific amount of questions
3145 *
3146 * @return int
3147 *
3148 * @since v.1.0.0
3149 */
3150
3151 public function max_questions_for_take_quiz($quiz_id){
3152 $quiz_id = $this->get_post_id($quiz_id);
3153 global $wpdb;
3154
3155 $max_questions = (int) $wpdb->get_var("select count(question_id) from {$wpdb->prefix}tutor_quiz_questions where quiz_id = {$quiz_id} ");
3156 $max_mentioned = (int) $this->get_quiz_option($quiz_id, 'max_questions_for_answer', 10);
3157
3158 if ($max_mentioned < $max_questions ){
3159 return $max_mentioned;
3160 }
3161
3162 return $max_questions;
3163 }
3164
3165 /**
3166 * @param int $attempt_id
3167 *
3168 * @return array|bool|null|object|void
3169 *
3170 * Get single quiz attempt
3171 *
3172 * @since v.1.0.0
3173 */
3174 public function get_attempt($attempt_id = 0){
3175 global $wpdb;
3176 if ( ! $attempt_id){
3177 return false;
3178 }
3179 $attempt = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE attempt_id = {$attempt_id} ");
3180 return $attempt;
3181 }
3182
3183 /**
3184 * @param $attempt_info
3185 *
3186 * @return mixed
3187 *
3188 * Get unserialize attempt info
3189 *
3190 * @since v.1.0.0
3191 */
3192
3193 public function quiz_attempt_info($attempt_info){
3194 return maybe_unserialize($attempt_info);
3195 }
3196
3197 /**
3198 * @param $quiz_attempt_id
3199 * @param array $attempt_info
3200 *
3201 * @return bool|int
3202 *
3203 * Update attempt for various action
3204 *
3205 * @since v.1.0.0
3206 */
3207 public function quiz_update_attempt_info($quiz_attempt_id, $attempt_info = array()){
3208 $answers = tutor_utils()->avalue_dot('answers', $attempt_info);
3209 $total_marks = array_sum(wp_list_pluck($answers, 'question_mark'));
3210 $earned_marks = tutor_utils()->avalue_dot('marks_earned', $attempt_info);
3211 $earned_mark_percent = $earned_marks > 0 ? ( number_format(($earned_marks * 100) / $total_marks)) : 0;
3212 update_comment_meta($quiz_attempt_id, 'earned_mark_percent', $earned_mark_percent);
3213
3214 return update_comment_meta($quiz_attempt_id,'quiz_attempt_info', $attempt_info);
3215 }
3216
3217 /**
3218 * @param int $quiz_id
3219 *
3220 * @return array|null|object
3221 *
3222 * Get random question by quiz id
3223 *
3224 * @since v.1.0.0
3225 */
3226
3227 public function get_random_question_by_quiz($quiz_id = 0){
3228 global $wpdb;
3229
3230 $quiz_id = $this->get_post_id($quiz_id);
3231 $is_attempt = $this->is_started_quiz($quiz_id);
3232
3233 $tempSql = " AND question_type = 'matching' ";
3234 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} {$tempSql} ORDER BY RAND() LIMIT 0,1 ");
3235
3236 return $questions;
3237 }
3238
3239 /**
3240 * @param int $quiz_id
3241 *
3242 * @return array|null|object
3243 *
3244 * Get random questions by quiz
3245 */
3246 public function get_random_questions_by_quiz($quiz_id = 0){
3247 global $wpdb;
3248
3249 $quiz_id = $this->get_post_id($quiz_id);
3250 $attempt = $this->is_started_quiz($quiz_id);
3251 if ( ! $attempt){
3252 return false;
3253 }
3254
3255 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY RAND() LIMIT {$attempt->total_questions} ");
3256
3257 return $questions;
3258 }
3259
3260 /**
3261 * @param $question_id
3262 * @param bool $rand
3263 *
3264 * @return array|bool|null|object
3265 *
3266 * Get answers list by quiz question
3267 *
3268 * @since v.1.0.0
3269 */
3270 public function get_answers_by_quiz_question($question_id, $rand = false){
3271 global $wpdb;
3272
3273
3274 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} ;");
3275 if ( ! $question){
3276 return false;
3277 }
3278
3279 $order = " answer_order ASC ";
3280 if ($question->question_type === 'ordering'){
3281 $order = " RAND() ";
3282 }
3283
3284 if ($rand){
3285 $order = " RAND() ";
3286 }
3287
3288 $answers = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question_id} AND belongs_question_type =
3289 '{$question->question_type}' order by {$order} ");
3290 return $answers;
3291 }
3292
3293 /**
3294 * @param int $quiz_id
3295 * @param int $user_id
3296 *
3297 * @return array|bool|null|object
3298 *
3299 * Get all of the attempts by an user of a quiz
3300 *
3301 * @since v.1.0.0
3302 */
3303
3304 public function quiz_attempts($quiz_id = 0, $user_id = 0){
3305 global $wpdb;
3306
3307 $quiz_id = $this->get_post_id($quiz_id);
3308 $user_id = $this->get_user_id($user_id);
3309
3310 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE quiz_id = {$quiz_id} AND user_id = {$user_id} ");
3311
3312 if (is_array($attempts) && count($attempts)){
3313 return $attempts;
3314 }
3315
3316 return false;
3317 }
3318
3319
3320 public function get_all_quiz_attempts_by_user($user_id = 0){
3321 global $wpdb;
3322
3323 $user_id = $this->get_user_id($user_id);
3324
3325 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE user_id = {$user_id} ");
3326
3327 if (is_array($attempts) && count($attempts)){
3328 return $attempts;
3329 }
3330
3331 return false;
3332 }
3333
3334 /**
3335 * @param string $search_term
3336 *
3337 * @return int
3338 *
3339 * Total number of quiz attempts
3340 *
3341 * @since v.1.0.0
3342 */
3343
3344 public function get_total_quiz_attempts($search_term = ''){
3345 global $wpdb;
3346
3347 if ($search_term){
3348 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3349 }
3350
3351 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3352 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3353 INNER JOIN {$wpdb->posts} quiz
3354 ON quiz_attempts.quiz_id = quiz.ID
3355 INNER JOIN {$wpdb->users}
3356 ON quiz_attempts.user_id = {$wpdb->users}.ID
3357 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3358 return (int) $count;
3359 }
3360
3361 /**
3362 * @param int $start
3363 * @param int $limit
3364 * @param string $search_term
3365 *
3366 * @return array|null|object
3367 *
3368 *
3369 * Get the all quiz attempts
3370 *
3371 * @since v.1.0.0
3372 */
3373 public function get_quiz_attempts($start = 0, $limit = 10, $search_term = '') {
3374 global $wpdb;
3375
3376 if ($search_term){
3377 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3378 }
3379
3380 $query = $wpdb->get_results("SELECT *
3381 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3382 INNER JOIN {$wpdb->posts} quiz
3383 ON quiz_attempts.quiz_id = quiz.ID
3384 INNER JOIN {$wpdb->users}
3385 ON quiz_attempts.user_id = {$wpdb->users}.ID
3386 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3387 ORDER BY quiz_attempts.attempt_id DESC
3388 LIMIT {$start},{$limit}; ");
3389 return $query;
3390 }
3391
3392 public function get_quiz_attempts_by_course_ids($start = 0, $limit = 10, $course_ids = array(), $search_term = '') {
3393 global $wpdb;
3394
3395 if ($search_term){
3396 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3397 }
3398
3399 $course_ids_in = implode($course_ids, ',');
3400 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3401 $search_term = $sql.$search_term;
3402
3403 $query = $wpdb->get_results("SELECT *
3404 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3405 INNER JOIN {$wpdb->posts} quiz
3406 ON quiz_attempts.quiz_id = quiz.ID
3407 INNER JOIN {$wpdb->users}
3408 ON quiz_attempts.user_id = {$wpdb->users}.ID
3409 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3410 ORDER BY quiz_attempts.attempt_id DESC
3411 LIMIT {$start},{$limit}; ");
3412 return $query;
3413 }
3414
3415 public function get_total_quiz_attempts_by_course_ids($course_ids = array(), $search_term = ''){
3416 global $wpdb;
3417
3418 if ($search_term){
3419 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3420 }
3421
3422 $course_ids_in = implode($course_ids, ',');
3423 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3424 $search_term = $sql.$search_term;
3425
3426 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3427 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3428 INNER JOIN {$wpdb->posts} quiz
3429 ON quiz_attempts.quiz_id = quiz.ID
3430 INNER JOIN {$wpdb->users}
3431 ON quiz_attempts.user_id = {$wpdb->users}.ID
3432 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3433 return (int) $count;
3434 }
3435
3436 /**
3437 * @param $attempt_id
3438 *
3439 * @return array|null|object
3440 *
3441 * Get quiz answers by attempt id
3442 *
3443 * @since v.1.0.0
3444 */
3445 public function get_quiz_answers_by_attempt_id($attempt_id){
3446 global $wpdb;
3447
3448 $results = $wpdb->get_results("SELECT answers.*, question.question_title, question.question_type
3449 FROM {$wpdb->prefix}tutor_quiz_attempt_answers answers
3450 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answers.question_id = question.question_id
3451 WHERE answers.quiz_attempt_id = {$attempt_id} ");
3452
3453 return $results;
3454 }
3455
3456 /**
3457 * @param $answer_id
3458 *
3459 * @return array|null|object
3460 *
3461 * Get single answer by answer_id
3462 *
3463 * @since v.1.0.0
3464 */
3465 public function get_answer_by_id($answer_id){
3466 global $wpdb;
3467
3468 if (is_array($answer_id)){
3469 $in_ids = implode(",", $answer_id);
3470 $sql = "answer.answer_id IN({$in_ids})";
3471 }else{
3472 $sql = "answer.answer_id = {$answer_id}";
3473 }
3474
3475 $answer = $wpdb->get_results("SELECT answer.*, question.question_title, question.question_type
3476 FROM {$wpdb->prefix}tutor_quiz_question_answers answer
3477 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answer.belongs_question_id = question.question_id
3478 WHERE 1=1 AND {$sql} ");
3479
3480 return $answer;
3481 }
3482
3483 /**
3484 * @param $ids
3485 *
3486 * @return array|bool|null|object
3487 *
3488 * Get quiz answers by ids
3489 *
3490 * @since v.1.0.0
3491 */
3492
3493 public function get_quiz_answers_by_ids($ids){
3494 $ids = (array) $ids;
3495
3496 if (!count($ids)){
3497 return false;
3498 }
3499
3500 $in_ids = implode(",", $ids);
3501
3502 global $wpdb;
3503 $query = $wpdb->get_results("SELECT
3504 comment_ID,
3505 comment_content
3506 FROM {$wpdb->comments}
3507 WHERE comment_type = 'quiz_answer_option' AND comment_ID IN({$in_ids}) ");
3508
3509 if (is_array($query) && count($query)){
3510 return $query;
3511 }
3512
3513 return false;
3514 }
3515
3516 /**
3517 * @param null $level
3518 *
3519 * @return mixed
3520 *
3521 * Get the users / students / course levels
3522 *
3523 * @since v.1.0.0
3524 */
3525
3526 public function course_levels($level = null){
3527 $levels = apply_filters('tutor_course_level', array(
3528 'all_levels' => __('All Levels', 'tutor'),
3529 'beginner' => __('Beginner', 'tutor'),
3530 'intermediate' => __('Intermediate', 'tutor'),
3531 'expert' => __('Expert', 'tutor'),
3532 ));
3533
3534 if ($level){
3535 if (isset($levels[$level])){
3536 return $levels[$level];
3537 }else{
3538 return '';
3539 }
3540 }
3541
3542 return $levels;
3543 }
3544
3545 /**
3546 * @return mixed|void
3547 *
3548 * Get user permalink for dashboard
3549 *
3550 * @since v.1.0.0
3551 */
3552 public function user_profile_permalinks(){
3553 $permalinks = array(
3554 'enrolled_course' => __('Enrolled Course', 'tutor'),
3555 'courses_taken' => __('Courses Taken', 'tutor'),
3556 'reviews_wrote' => __('Reviews Written', 'tutor'),
3557 );
3558
3559 return apply_filters('tutor_public_profile/permalinks', $permalinks);
3560 }
3561
3562 /**
3563 * @return bool|false|string
3564 *
3565 * Student registration form
3566 *
3567 * @since v.1.0.0
3568 */
3569 public function student_register_url(){
3570 $student_register_page = (int) $this->get_option('student_register_page');
3571
3572 if ($student_register_page){
3573 return get_the_permalink($student_register_page);
3574 }
3575 return false;
3576 }
3577
3578 /**
3579 * @return false|string
3580 *
3581 * Get frontend dashboard URL
3582 */
3583 public function tutor_dashboard_url(){
3584 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3585 $page_id = apply_filters('tutor_dashboard_url', $page_id);
3586 return get_the_permalink($page_id);
3587 }
3588
3589 /**
3590 * @param int $course_id
3591 * @param int $user_id
3592 *
3593 * @return bool
3594 *
3595 * is_wishlisted();
3596 *
3597 * @since v.1.0.0
3598 */
3599 public function is_wishlisted($course_id = 0, $user_id = 0){
3600 $course_id = $this->get_post_id($course_id);
3601 $user_id = $this->get_user_id($user_id);
3602 if ( ! $user_id){
3603 return false;
3604 }
3605
3606 global $wpdb;
3607 $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} ;");
3608
3609 return $if_added_to_list;
3610 }
3611
3612 /**
3613 * @param int $user_id
3614 *
3615 * @return array|null|object
3616 *
3617 * Get the wish lists by an user
3618 *
3619 * @since v.1.0.0
3620 */
3621 public function get_wishlist($user_id = 0){
3622 $user_id = $this->get_user_id($user_id);
3623 global $wpdb;
3624
3625 $query = "SELECT $wpdb->posts.*
3626 FROM $wpdb->posts
3627 LEFT JOIN $wpdb->usermeta ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
3628 WHERE $wpdb->usermeta.meta_key = '_tutor_course_wishlist'
3629 AND $wpdb->usermeta.user_id = {$user_id}
3630 ORDER BY $wpdb->usermeta.umeta_id DESC ";
3631 $pageposts = $wpdb->get_results($query, OBJECT);
3632 return $pageposts;
3633 }
3634
3635 /**
3636 * @param int $limit
3637 *
3638 * @return array|null|object
3639 *
3640 * Getting popular courses
3641 *
3642 * @since v.1.0.0
3643 */
3644 public function most_popular_courses($limit = 10){
3645 global $wpdb;
3646
3647 $courses = $wpdb->get_results("
3648 SELECT COUNT(enrolled.ID) as total_enrolled,
3649 enrolled.post_parent as course_id,
3650 course.*
3651 from {$wpdb->posts} enrolled
3652 INNER JOIN {$wpdb->posts} course ON enrolled.post_parent = course.ID
3653 WHERE enrolled.post_type = 'tutor_enrolled' AND enrolled.post_status = 'completed'
3654
3655 GROUP BY course_id
3656 ORDER BY total_enrolled DESC LIMIT 0,{$limit} ;");
3657
3658 return $courses;
3659 }
3660
3661 /**
3662 * @param int $limit
3663 *
3664 * @return array|bool|null|object
3665 *
3666 * Get most rated courses lists
3667 *
3668 * @since v.1.0.0
3669 */
3670 public function most_rated_courses($limit = 10){
3671 global $wpdb;
3672
3673 $result = $wpdb->get_results("
3674 SELECT COUNT(comment_ID) AS total_rating,
3675 comment_ID,
3676 comment_post_ID,
3677 course.*
3678 FROM {$wpdb->comments}
3679 INNER JOIN {$wpdb->posts} course ON comment_post_ID = course.ID
3680 WHERE {$wpdb->comments}.comment_type = 'tutor_course_rating' AND {$wpdb->comments}.comment_approved = 'approved'
3681 GROUP BY comment_post_ID ORDER BY total_rating DESC LIMIT 0,{$limit}
3682 ;");
3683
3684 if (is_array($result) && count($result)){
3685 return $result;
3686 }
3687 return false;
3688 }
3689
3690 /**
3691 * @param null $addon_field
3692 *
3693 * @return bool
3694 *
3695 * Get Addon config
3696 *
3697 * @since v.1.0.0
3698 */
3699 public function get_addon_config($addon_field = null){
3700 if ( ! $addon_field){
3701 return false;
3702 }
3703
3704 $addonsConfig = maybe_unserialize(get_option('tutor_addons_config'));
3705
3706 if (isset($addonsConfig[$addon_field])){
3707 return $addonsConfig[$addon_field];
3708 }
3709
3710 return false;
3711 }
3712
3713 /**
3714 * @return array|false|string
3715 *
3716 * Get the IP from visitor
3717 *
3718 * @since v.1.0.0
3719 */
3720 function get_ip() {
3721 $ipaddress = '';
3722 if (getenv('HTTP_CLIENT_IP'))
3723 $ipaddress = getenv('HTTP_CLIENT_IP');
3724 else if(getenv('HTTP_X_FORWARDED_FOR'))
3725 $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
3726 else if(getenv('HTTP_X_FORWARDED'))
3727 $ipaddress = getenv('HTTP_X_FORWARDED');
3728 else if(getenv('HTTP_FORWARDED_FOR'))
3729 $ipaddress = getenv('HTTP_FORWARDED_FOR');
3730 else if(getenv('HTTP_FORWARDED'))
3731 $ipaddress = getenv('HTTP_FORWARDED');
3732 else if(getenv('REMOTE_ADDR'))
3733 $ipaddress = getenv('REMOTE_ADDR');
3734 else
3735 $ipaddress = 'UNKNOWN';
3736 return $ipaddress;
3737 }
3738
3739 /**
3740 * @return mixed|void
3741 *
3742 * Get the social icons
3743 *
3744 * @since v.1.0.4
3745 */
3746
3747 public function tutor_social_share_icons(){
3748 $icons = array(
3749 'facebook' => array('share_class' => 's_facebook', 'icon_html' => '<i class="tutor-icon-facebook"></i>' ),
3750 'twitter' => array('share_class' => 's_twitter', 'icon_html' => '<i class="tutor-icon-twitter"></i>' ),
3751 'linkedin' => array('share_class' => 's_linkedin', 'icon_html' => '<i class="tutor-icon-linkdin"></i>' ),
3752 'tumblr' => array('share_class' => 's_tumblr', 'icon_html' => '<i class="tutor-icon-tumblr"></i>' ),
3753 );
3754
3755 return apply_filters('tutor_social_share_icons', $icons);
3756 }
3757
3758 /**
3759 * @param array $array
3760 *
3761 * @return bool
3762 *
3763 * count method with check is_array
3764 *
3765 * @since v.1.0.4
3766 */
3767 public function count($array = array()){
3768 return is_array($array) && count($array);
3769 }
3770
3771 /**
3772 * @return array
3773 *
3774 * get all screen ids
3775 *
3776 * @since v.1.1.2
3777 */
3778 public function tutor_get_screen_ids(){
3779 $screen_ids = array(
3780 "edit-course",
3781 "course",
3782 "edit-course-category",
3783 "edit-course-tag",
3784 "tutor-lms_page_tutor-students",
3785 "tutor-lms_page_tutor-instructors",
3786 "tutor-lms_page_question_answer",
3787 "tutor-lms_page_tutor_quiz_attempts",
3788 "tutor-lms_page_tutor-addons",
3789 "tutor-lms_page_tutor-status",
3790 "tutor-lms_page_tutor_report",
3791 "tutor-lms_page_tutor_settings",
3792 "tutor-lms_page_tutor_emails",
3793 );
3794
3795 return apply_filters('tutor_get_screen_ids', $screen_ids);
3796 }
3797
3798
3799 /**
3800 * @return mixed
3801 *
3802 * get earning transaction completed status
3803 *
3804 * @since v.1.1.2
3805 */
3806 public function get_earnings_completed_statuses(){
3807 return apply_filters(
3808 'tutor_get_earnings_completed_statuses',
3809 array (
3810 'wc-completed',
3811 'completed',
3812 'complete',
3813 )
3814 );
3815 }
3816
3817 /**
3818 * @param int $user_id
3819 * @param array $date_filter
3820 *
3821 * @return array|null|object
3822 *
3823 * Get all time earning sum for an instructor with all commission
3824 *
3825 * @since v.1.1.2
3826 */
3827
3828 public function get_earning_sum($user_id = 0, $date_filter = array()){
3829 global $wpdb;
3830
3831 $user_id = $this->get_user_id($user_id);
3832 $date_query = '';
3833 if ($this->count($date_filter)){
3834 extract($date_filter);
3835
3836 if ( ! empty($dataFor)){
3837 if ($dataFor === 'yearly'){
3838 if (empty($year)){
3839 $year = date('Y');
3840 }
3841 $date_query = "AND YEAR(created_at) = {$year} ";
3842 }
3843 }else{
3844 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
3845 }
3846 }
3847
3848 $complete_status = tutor_utils()->get_earnings_completed_statuses();
3849 $complete_status = "'".implode("','", $complete_status)."'";
3850
3851 $earning_sum = $wpdb->get_row("SELECT SUM(course_price_total) as course_price_total,
3852 SUM(course_price_grand_total) as course_price_grand_total,
3853 SUM(instructor_amount) as instructor_amount,
3854 (SELECT SUM(amount) FROM {$wpdb->prefix}tutor_withdraws WHERE user_id = {$user_id} AND status != 'rejected' ) as
3855 withdraws_amount,
3856 (SUM(instructor_amount) - (SELECT withdraws_amount) ) as balance,
3857 SUM(admin_amount) as admin_amount,
3858 SUM(deduct_fees_amount) as deduct_fees_amount
3859 FROM {$wpdb->prefix}tutor_earnings
3860 WHERE user_id = {$user_id} AND order_status IN({$complete_status}) {$date_query} ");
3861
3862 if ( ! $earning_sum->course_price_total){
3863 $earning_sum = (object) array(
3864 'course_price_total' => 0,
3865 'course_price_grand_total' => 0,
3866 'instructor_amount' => 0,
3867 'withdraws_amount' => 0,
3868 'balance' => 0,
3869 'admin_amount' => 0,
3870 'deduct_fees_amount' => 0,
3871 );
3872 }
3873
3874 return $earning_sum;
3875 }
3876
3877 /**
3878 * @param int $user_id
3879 * @param array $date_filter
3880 *
3881 * @return array|null|object
3882 *
3883 * Get earning statements
3884 *
3885 * @since v.1.1.2
3886 */
3887 public function get_earning_statements($user_id = 0, $filter_data = array()){
3888 global $wpdb;
3889
3890 $user_sql = "";
3891 if ($user_id){
3892 $user_sql = " AND user_id='{$user_id}' ";
3893 }
3894
3895 $date_query = '';
3896 $query_by_status = '';
3897 $pagination_query = '';
3898
3899 /**
3900 * Query by Date Filter
3901 */
3902 if ($this->count($filter_data)){
3903 extract($filter_data);
3904
3905 if ( ! empty($dataFor)){
3906 if ($dataFor === 'yearly'){
3907 if (empty($year)){
3908 $year = date('Y');
3909 }
3910 $date_query = "AND YEAR(created_at) = {$year} ";
3911 }
3912 }else{
3913 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
3914 }
3915
3916 /**
3917 * Query by order status related to this earning transaction
3918 */
3919 if ( ! empty($statuses)) {
3920 if ( $this->count( $statuses ) ) {
3921 $status = "'" . implode( "','", $statuses ) . "'";
3922 $query_by_status = "AND order_status IN({$status})";
3923 } elseif ( $statuses === 'completed' ) {
3924
3925 $get_earnings_completed_statuses = $this->get_earnings_completed_statuses();
3926 if ( $this->count( $get_earnings_completed_statuses ) ) {
3927 $status = "'" . implode( "','", $get_earnings_completed_statuses ) . "'";
3928 $query_by_status = "AND order_status IN({$status})";
3929 }
3930 }
3931 }
3932
3933 if ( ! empty($per_page)){
3934 $offset = (int) ! empty($offset) ? $offset : 0;
3935
3936 $pagination_query = " LIMIT {$offset}, {$per_page} ";
3937
3938 }
3939
3940
3941 }
3942
3943 $query = $wpdb->get_results("SELECT earning_tbl.*, course.post_title as course_title
3944 FROM {$wpdb->prefix}tutor_earnings earning_tbl
3945 LEFT JOIN {$wpdb->posts} course ON earning_tbl.course_id = course.ID
3946 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC {$pagination_query} ");
3947
3948
3949 $query_count = (int) $wpdb->get_var("SELECT COUNT(earning_tbl.earning_id)
3950 FROM {$wpdb->prefix}tutor_earnings earning_tbl
3951 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC ");
3952
3953 return (object) array(
3954 'count' => $query_count,
3955 'results' => $query,
3956 );
3957 }
3958
3959 /**
3960 * @param int $price
3961 *
3962 * @return int|string
3963 *
3964 * Get the price format
3965 *
3966 * @since v.1.1.2
3967 */
3968
3969 public function tutor_price($price = 0){
3970 if (function_exists('wc_price')){
3971 return wc_price($price);
3972 }elseif (function_exists('edd_currency_filter')){
3973 return edd_currency_filter(edd_format_amount($price));
3974 }else{
3975 return number_format_i18n($price);
3976 }
3977 }
3978
3979 /**
3980 * @param int $user_id
3981 *
3982 * @return bool|mixed
3983 *
3984 * Get withdraw method for a specific
3985 */
3986 public function get_user_withdraw_method($user_id = 0){
3987 $user_id = $this->get_user_id($user_id);
3988
3989 $account = get_user_meta($user_id, '_tutor_withdraw_method_data', true);
3990 if ($account){
3991 return maybe_unserialize($account);
3992 }
3993
3994 return false;
3995 }
3996
3997
3998 public function get_withdrawals_history($user_id = 0, $filter = array()){
3999 global $wpdb;
4000
4001 $filter = (array) $filter;
4002 extract($filter);
4003
4004 $query_by_status_sql = "";
4005 $query_by_user_sql = "";
4006 $query_by_pagination = "";
4007
4008 if ( ! empty($status)){
4009 $status = (array) $status;
4010 $status = "'".implode("','", $status)."'";
4011
4012 $query_by_status_sql = " AND status IN({$status}) ";
4013 }
4014
4015 if ( ! empty($per_page)){
4016 if ( empty($start))
4017 $start = 0;
4018
4019 $query_by_pagination = " LIMIT {$start}, {$per_page} ";
4020 }
4021
4022 if ($user_id){
4023 $query_by_user_sql = " AND user_id = {$user_id} ";
4024 }
4025
4026
4027 $count = (int) $wpdb->get_var("SELECT COUNT(withdraw_id) FROM {$wpdb->prefix}tutor_withdraws WHERE 1=1 {$query_by_user_sql} {$query_by_status_sql} ");
4028
4029 $results = $wpdb->get_results("SELECT withdraw_tbl.*,
4030 user_tbl.display_name as user_name,
4031 user_tbl.user_email
4032 FROM {$wpdb->prefix}tutor_withdraws withdraw_tbl
4033 INNER JOIN {$wpdb->users} user_tbl ON withdraw_tbl.user_id = user_tbl.ID
4034 WHERE 1=1
4035 {$query_by_user_sql}
4036 {$query_by_status_sql} ORDER BY
4037 created_at DESC {$query_by_pagination} ");
4038
4039 $withdraw_history = array(
4040 'count' => 0,
4041 'results' => null,
4042 );
4043
4044 if ($count){
4045 $withdraw_history['count'] = $count;
4046 }
4047
4048 if (tutor_utils()->count($results)){
4049 $withdraw_history['results'] = $results;
4050 }
4051 return (object) $withdraw_history;
4052
4053 }
4054
4055 }