PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.2.13
Tutor LMS – eLearning and online course solution v1.2.13
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
4103 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
1694 do_action('tutor_mark_lesson_complete_before', $post_id, $user_id);
1695 update_user_meta($user_id, '_tutor_completed_lesson_id_'.$post_id, time());
1696 do_action('tutor_mark_lesson_complete_after', $post_id, $user_id);
1697
1698 }
1699
1700 /**
1701 * Saving enroll information to posts table
1702 * post_author = enrolled_student_id (wp_users id)
1703 * post_parent = enrolled course id
1704 *
1705 * @type: call when need
1706 * @return bool;
1707 *
1708 * @since v.1.0.0
1709 */
1710 public function do_enroll($course_id = 0, $order_id = 0){
1711 if ( ! $course_id){
1712 return false;
1713 }
1714
1715 do_action('tutor_before_enroll', $course_id);
1716 $user_id = get_current_user_id();
1717 $title = __('Course Enrolled', 'tutor')." &ndash; ".date_i18n(get_option('date_format')) .' @ '.date_i18n(get_option('time_format') ) ;
1718
1719 $enrolment_status = 'completed';
1720
1721 if ($this->is_course_purchasable($course_id)) {
1722 /**
1723 * We need to verify this enrollment, we will change the status later after payment confirmation
1724 */
1725 $enrolment_status = 'pending';
1726 }
1727
1728 $enroll_data = apply_filters('tutor_enroll_data',
1729 array(
1730 'post_type' => 'tutor_enrolled',
1731 'post_title' => $title,
1732 'post_status' => $enrolment_status,
1733 'post_author' => $user_id,
1734 'post_parent' => $course_id,
1735 )
1736 );
1737
1738 // Insert the post into the database
1739 $isEnrolled = wp_insert_post( $enroll_data );
1740 if ($isEnrolled) {
1741 do_action('tutor_after_enroll', $course_id, $isEnrolled);
1742
1743 //Mark Current User as Students with user meta data
1744 update_user_meta( $user_id, '_is_tutor_student', time() );
1745
1746 if ($order_id) {
1747 //Mark order for course and user
1748 $product_id = $this->get_course_product_id($course_id);
1749 update_post_meta( $isEnrolled, '_tutor_enrolled_by_order_id', $order_id );
1750 update_post_meta( $isEnrolled, '_tutor_enrolled_by_product_id', $product_id );
1751 update_post_meta( $order_id, '_is_tutor_order_for_course', time() );
1752 update_post_meta( $order_id, '_tutor_order_for_course_id_'.$course_id, $isEnrolled );
1753 }
1754 return true;
1755 }
1756
1757 return false;
1758 }
1759
1760 /**
1761 * @param $order_id
1762 *
1763 * Complete course enrollment and do some task
1764 *
1765 * @since v.1.0.0
1766 */
1767 public function complete_course_enroll($order_id){
1768 if ( ! tutor_utils()->is_tutor_order($order_id)){
1769 return;
1770 }
1771
1772 global $wpdb;
1773
1774 $enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id($order_id);
1775 if ($enrolled_ids_with_course){
1776 $enrolled_ids = wp_list_pluck($enrolled_ids_with_course, 'enrolled_id');
1777
1778 if (is_array($enrolled_ids) && count($enrolled_ids)){
1779 foreach ($enrolled_ids as $enrolled_id){
1780 $wpdb->update( $wpdb->posts, array( 'post_status' => 'completed' ), array( 'ID' => $enrolled_id ) );
1781 }
1782 }
1783 }
1784 }
1785
1786 /**
1787 * @param $order_id
1788 *
1789 * @return array|bool
1790 *
1791 * @since v.1.0.0
1792 */
1793 public function get_course_enrolled_ids_by_order_id($order_id){
1794 global $wpdb;
1795 //Getting all of courses ids within this order
1796
1797 $courses_ids = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE post_id = {$order_id} AND meta_key LIKE '_tutor_order_for_course_id_%' ");
1798
1799 if (is_array($courses_ids) && count($courses_ids)){
1800 $course_enrolled_by_order = array();
1801 foreach ($courses_ids as $courses_id){
1802 $course_id = str_replace('_tutor_order_for_course_id_', '',$courses_id->meta_key);
1803 //array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id))
1804 $course_enrolled_by_order[] = array('course_id' => $course_id, 'enrolled_id' => $courses_id->meta_value, 'order_id' => $courses_id->post_id );
1805 }
1806 return $course_enrolled_by_order;
1807 }
1808 return false;
1809 }
1810
1811 /**
1812 * Get wc product in efficient query
1813 *
1814 * @since v.1.0.0
1815 */
1816
1817 /**
1818 * @return array|null|object
1819 *
1820 * WooCommerce specific utils
1821 */
1822 public function get_wc_products_db(){
1823 global $wpdb;
1824 $query = $wpdb->get_results("SELECT ID, post_title from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'product' ");
1825
1826 return $query;
1827 }
1828
1829 /**
1830 * @return array|null|object
1831 *
1832 * Get EDD Products
1833 */
1834 public function get_edd_products(){
1835 global $wpdb;
1836 $query = $wpdb->get_results("SELECT ID, post_title from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'download' ");
1837
1838 return $query;
1839 }
1840
1841 /**
1842 * @param int $course_id
1843 *
1844 * @return int
1845 *
1846 * Get course productID
1847 *
1848 * @since v.1.0.0
1849 */
1850 public function get_course_product_id($course_id = 0){
1851 $course_id = $this->get_post_id($course_id);
1852 return (int) get_post_meta($course_id, '_tutor_course_product_id', true);
1853 }
1854
1855 /**
1856 * @param int $product_id
1857 *
1858 * @return array|null|object|void
1859 *
1860 * Get Product belongs with course
1861 *
1862 * @since v.1.0.0
1863 */
1864
1865 public function product_belongs_with_course($product_id = 0){
1866 global $wpdb;
1867
1868 $query = $wpdb->get_row("select * from {$wpdb->postmeta} WHERE meta_key='_tutor_course_product_id' AND meta_value = {$product_id} limit 1 ");
1869 return $query;
1870 }
1871
1872 /**
1873 * #End WooCommerce specific utils
1874 *
1875 * @since v.1.0.0
1876 */
1877
1878 public function get_enrolled_statuses(){
1879 return apply_filters(
1880 'tutor_get_enrolled_statuses',
1881 array (
1882 'pending',
1883 'processing',
1884 'on-hold',
1885 'completed',
1886 'cancelled',
1887 'refunded',
1888 'failed',
1889 )
1890 );
1891 }
1892
1893 /**
1894 * @param $order_id
1895 *
1896 * @return mixed
1897 *
1898 * determine is this a tutor order
1899 *
1900 * @since v.1.0.0
1901 */
1902 public function is_tutor_order($order_id){
1903 return get_post_meta($order_id, '_is_tutor_order_for_course', true);
1904 }
1905
1906 /**
1907 * @return mixed
1908 *
1909 * @deprecated
1910 */
1911 public function tutor_student_dashboard_pages(){
1912 _deprecated_function(__METHOD__, '1.1.2', 'tutor_dashboard_pages');
1913 return $this->tutor_dashboard_pages();
1914 }
1915
1916 /**
1917 * @return mixed
1918 *
1919 * Tutor Dashboard Pages
1920 *
1921 * @since v.1.0.0
1922 */
1923
1924 public function tutor_dashboard_pages(){
1925 $nav_items = array(
1926
1927 'index' => __('Dashboard', 'tutor'),
1928 'my-profile' => __('My Profile', 'tutor'),
1929 'enrolled-courses' => __('Enrolled Courses', 'tutor'),
1930 'my-courses' => __('My Courses', 'tutor'),
1931 'wishlist' => __('Wishlist', 'tutor'),
1932 'my-reviews' => __('My Reviews', 'tutor'),
1933 'quiz-attempts' => __('Quiz Attempts', 'tutor'),
1934 'earning' => __('Earning', 'tutor'),
1935 'withdraw' => __('Withdraw', 'tutor'),
1936 //'purchase-history' => __('Purchase History', 'tutor'),
1937 //'messages' => __('Messages', 'tutor'),
1938 //'settings' => __('Settings', 'tutor'),
1939 'logout' => __('Logout', 'tutor'),
1940 );
1941
1942 return apply_filters('tutor_dashboard/student/pages', $nav_items);
1943 }
1944
1945 /**
1946 * @param string $page_key
1947 * @param int $page_id
1948 *
1949 * @return string
1950 *
1951 * Get tutor dashboard page single URL
1952 *
1953 * @since v.1.0.0
1954 */
1955 public function get_tutor_dashboard_page_permalink($page_key = '', $page_id = 0){
1956 if ($page_key === 'index'){
1957 $page_key = '';
1958 }
1959 $page_id = $this->get_post_id($page_id);
1960 return trailingslashit(get_permalink($page_id)).$page_key;
1961 }
1962
1963 /**
1964 * @param string $input
1965 *
1966 * @return array|bool|mixed|string
1967 *
1968 * Get old input
1969 *
1970 * @since v.1.0.0
1971 */
1972 public function input_old($input = ''){
1973 $value = $this->avalue_dot($input, $_REQUEST);
1974 if ($value){
1975 return $value;
1976 }
1977 return '';
1978 }
1979
1980 /**
1981 * @param int $user_id
1982 *
1983 * @return mixed
1984 *
1985 * Determine if is instructor or not
1986 *
1987 * @since v.1.0.0
1988 */
1989 public function is_instructor($user_id = 0){
1990 $user_id = $this->get_user_id($user_id);
1991 return get_user_meta($user_id, '_is_tutor_instructor', true);
1992 }
1993
1994 /**
1995 * @param int $user_id
1996 * @param bool $status_name
1997 *
1998 * @return bool|mixed
1999 *
2000 * Instructor status
2001 *
2002 * @since v.1.0.0
2003 */
2004 public function instructor_status($user_id = 0, $status_name = true){
2005 $user_id = $this->get_user_id($user_id);
2006
2007 $instructor_status = apply_filters('tutor_instructor_statuses', array(
2008 'pending' => __('Pending', 'tutor'),
2009 'approved' => __('Approved', 'tutor'),
2010 'blocked' => __('Blocked', 'tutor'),
2011 ));
2012
2013 $status = get_user_meta($user_id, '_tutor_instructor_status', true);
2014
2015 if (isset($instructor_status[$status])){
2016 if ( ! $status_name){
2017 return $status;
2018 }
2019 return $instructor_status[$status];
2020 }
2021 return false;
2022 }
2023
2024 /**
2025 * @param string $search_term
2026 *
2027 * @return int
2028 *
2029 * Get total number of instructors
2030 *
2031 * @since v.1.0.0
2032 */
2033
2034 public function get_total_instructors($search_term = ''){
2035 $meta_key = '_is_tutor_instructor';
2036
2037 global $wpdb;
2038
2039 if ($search_term){
2040 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2041 }
2042
2043 $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 ");
2044
2045 return (int) $count;
2046 }
2047
2048 /**
2049 * @param int $start
2050 * @param int $limit
2051 * @param string $search_term
2052 *
2053 * @return array|null|object
2054 *
2055 * Get all instructors
2056 *
2057 * @since v.1.0.0
2058 */
2059 public function get_instructors($start = 0, $limit = 10, $search_term = ''){
2060 $meta_key = '_is_tutor_instructor';
2061 global $wpdb;
2062
2063 if ($search_term){
2064 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2065 }
2066
2067 $instructors = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
2068 INNER JOIN {$wpdb->usermeta}
2069 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
2070 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
2071 ORDER BY {$wpdb->usermeta}.meta_value DESC
2072 LIMIT {$start}, {$limit} ");
2073
2074 return $instructors;
2075 }
2076
2077 /**
2078 * @param int $course_id
2079 *
2080 * @return array|bool|null|object
2081 *
2082 * Get all instructors by course
2083 *
2084 * @since v.1.0.0
2085 */
2086 public function get_instructors_by_course($course_id = 0){
2087 global $wpdb;
2088 $course_id = $this->get_post_id($course_id);
2089
2090 $instructors = $wpdb->get_results("select ID, display_name,
2091 get_course.meta_value as taught_course_id,
2092 tutor_job_title.meta_value as tutor_profile_job_title,
2093 tutor_bio.meta_value as tutor_profile_bio,
2094 tutor_photo.meta_value as tutor_profile_photo
2095 from {$wpdb->users}
2096 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}
2097 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2098 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2099 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2100 ");
2101
2102 if (is_array($instructors) && count($instructors)){
2103 return $instructors;
2104 }
2105
2106 return false;
2107 }
2108
2109 /**
2110 * @param $instructor_id
2111 *
2112 * Get total Students by instructor
2113 * 1 enrollment = 1 student, so total enrolled for a equivalent total students (Tricks)
2114 *
2115 * @return int
2116 *
2117 * @since v.1.0.0
2118 */
2119
2120 public function get_total_students_by_instructor($instructor_id){
2121 global $wpdb;
2122
2123 $course_post_type = tutor()->course_post_type;
2124 $count = $wpdb->get_var("SELECT COUNT(courses.ID) from {$wpdb->posts} courses
2125
2126 INNER JOIN {$wpdb->posts} enrolled ON courses.ID = enrolled.post_parent AND enrolled.post_type = 'tutor_enrolled'
2127 WHERE courses.post_status = 'publish'
2128 AND courses.post_type = '{$course_post_type}'
2129 AND courses.post_author = {$instructor_id} ; ");
2130 return (int) $count;
2131 }
2132
2133 /**
2134 * @param float $input
2135 *
2136 * @return float|string
2137 *
2138 * Get rating format from value
2139 *
2140 * @since v.1.0.0
2141 */
2142 public function get_rating_value($input = 0.00){
2143
2144 if ( $input > 0){
2145 $input = number_format($input, 2);
2146 $int_value = (int) $input;
2147 $fraction = $input - $int_value;
2148
2149 if ($fraction == 0){
2150 $fraction = 0.00;
2151 }elseif($fraction > 0.5){
2152 $fraction = 1;
2153 }else{
2154 $fraction = 0.5;
2155 }
2156
2157 return number_format( ($int_value + $fraction), 2);
2158 }
2159 return 0.00;
2160 }
2161
2162 /**
2163 * @param float $current_rating
2164 * @param bool $echo
2165 *
2166 * @return string
2167 *
2168 * Generate star rating based in given rating value
2169 *
2170 * @since v.1.0.0
2171 */
2172 public function star_rating_generator($current_rating = 0.00, $echo = true){
2173 $output = '<div class="tutor-star-rating-group">';
2174
2175 for ($i = 1; $i <=5 ; $i++){
2176 $intRating = (int) $current_rating;
2177
2178 if ($intRating >= $i){
2179 $output.= '<i class="tutor-icon-star-full" data-rating-value="'.$i.'"></i>';
2180 } else{
2181 if ( ($current_rating - $i) == -0.5){
2182 $output.= '<i class="tutor-icon-star-half" data-rating-value="'.$i.'"></i>';
2183 }else{
2184 $output.= '<i class="tutor-icon-star-line" data-rating-value="'.$i.'"></i>';
2185 }
2186 }
2187 }
2188
2189 $output .= "<div class='tutor-rating-gen-input'><input type='hidden' name='tutor_rating_gen_input' value='{$current_rating}' /> </div>";
2190
2191 $output .= "</div>";
2192
2193 if ($echo){
2194 echo $output;
2195 }
2196 return $output;
2197 }
2198
2199 /**
2200 * @param null $name
2201 *
2202 * @return string
2203 *
2204 * Generate text to avatar
2205 *
2206 * @since v.1.0.0
2207 */
2208 public function get_tutor_avatar($user_id = null, $size = 'thumbnail'){
2209 global $wpdb;
2210
2211 if ( ! $user_id){
2212 return '';
2213 }
2214
2215 $user = $this->get_tutor_user($user_id);
2216 if ($user->tutor_profile_photo){
2217 return '<img src="'.wp_get_attachment_image_url($user->tutor_profile_photo, $size).'" class="tutor-image-avatar" alt="" /> ';
2218 }
2219
2220 $name = $user->display_name;
2221 $arr = explode(' ', trim($name));
2222
2223 if (count($arr) > 1){
2224 $first_char = substr($arr[0], 0, 1) ;
2225 $second_char = substr($arr[1], 0, 1) ;
2226 }else{
2227 $first_char = substr($arr[0], 0, 1) ;
2228 $second_char = substr($arr[0], 1, 1) ;
2229 }
2230
2231 $initial_avatar = strtoupper($first_char.$second_char);
2232
2233 $bg_color = '#'.substr(md5($initial_avatar), 0, 6);
2234 $initial_avatar = "<span class='tutor-text-avatar' style='background-color: {$bg_color}; color: #fff8e5'>{$initial_avatar}</span>";
2235
2236 return $initial_avatar;
2237 }
2238
2239 /**
2240 * @param $user_id
2241 *
2242 * @return array|null|object|void
2243 *
2244 * Get tutor user
2245 *
2246 * @since v.1.0.0
2247 */
2248
2249 public function get_tutor_user($user_id){
2250 global $wpdb;
2251
2252 $user = $wpdb->get_row("select ID, display_name,
2253 tutor_job_title.meta_value as tutor_profile_job_title,
2254 tutor_bio.meta_value as tutor_profile_bio,
2255 tutor_photo.meta_value as tutor_profile_photo
2256
2257 from {$wpdb->users}
2258 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2259 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2260 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2261
2262 WHERE ID = {$user_id} ");
2263 return $user;
2264 }
2265
2266 /**
2267 * @param int $course_id
2268 * @param int $offset
2269 * @param int $limit
2270 *
2271 * @return array|null|object
2272 *
2273 * get course reviews
2274 *
2275 * @since v.1.0.0
2276 */
2277 public function get_course_reviews($course_id = 0, $offset = 0, $limit = 150){
2278 $course_id = $this->get_post_id($course_id);
2279 global $wpdb;
2280
2281 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2282 {$wpdb->comments}.comment_post_ID,
2283 {$wpdb->comments}.comment_author,
2284 {$wpdb->comments}.comment_author_email,
2285 {$wpdb->comments}.comment_date,
2286 {$wpdb->comments}.comment_content,
2287 {$wpdb->comments}.user_id,
2288 {$wpdb->commentmeta}.meta_value as rating,
2289 {$wpdb->users}.display_name
2290
2291 from {$wpdb->comments}
2292 INNER JOIN {$wpdb->commentmeta}
2293 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2294 INNER JOIN {$wpdb->users}
2295 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2296 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2297 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2298 );
2299
2300 return $reviews;
2301 }
2302
2303 /**
2304 * @param int $course_id
2305 *
2306 * @return object
2307 *
2308 * Get course rating
2309 *
2310 * @since v.1.0.0
2311 */
2312 public function get_course_rating($course_id = 0){
2313 $course_id = $this->get_post_id($course_id);
2314
2315 $ratings = array(
2316 'rating_count' => 0,
2317 'rating_sum' => 0,
2318 'rating_avg' => 0.00,
2319 'count_by_value' => array(5 => 0, 4 => 0, 3 => 0, 2 => 0, 1 => 0)
2320 );
2321
2322 global $wpdb;
2323
2324 $rating = $wpdb->get_row("select COUNT(meta_value) as rating_count, SUM(meta_value) as rating_sum
2325 from {$wpdb->comments}
2326 INNER JOIN {$wpdb->commentmeta}
2327 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2328 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2329 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2330 AND meta_key = 'tutor_rating' ;"
2331 );
2332
2333 if ($rating->rating_count){
2334 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2335
2336 /**
2337 * Get individual Rating by integer
2338 */
2339 $five_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2340 from {$wpdb->comments}
2341 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2342 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2343 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2344 AND meta_key = 'tutor_rating' AND meta_value = 5 ;"
2345 );
2346 $four_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2347 from {$wpdb->comments}
2348 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2349 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2350 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2351 AND meta_key = 'tutor_rating' AND meta_value = 4 ;"
2352 );
2353 $three_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2354 from {$wpdb->comments}
2355 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2356 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2357 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2358 AND meta_key = 'tutor_rating' AND meta_value = 3 ;"
2359 );
2360 $two_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2361 from {$wpdb->comments}
2362 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2363 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2364 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2365 AND meta_key = 'tutor_rating' AND meta_value = 2 ;"
2366 );
2367 $one_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2368 from {$wpdb->comments}
2369 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2370 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2371 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2372 AND meta_key = 'tutor_rating' AND meta_value = 1 ;"
2373 );
2374
2375 $ratings = array(
2376 'rating_count' => $rating->rating_count,
2377 'rating_sum' => $rating->rating_sum,
2378 'rating_avg' => $avg_rating,
2379 'count_by_value' => array(5 => $five_stars_count, 4 => $four_stars_count, 3 => $three_stars_count, 2 => $two_stars_count, 1 => $one_stars_count)
2380 );
2381
2382 }
2383
2384 return (object) $ratings;
2385 }
2386
2387 /**
2388 * @param int $user_id
2389 * @param int $offset
2390 * @param int $limit
2391 *
2392 * @return array|null|object
2393 *
2394 * Get reviews by a user
2395 *
2396 * @since v.1.0.0
2397 */
2398 public function get_reviews_by_user($user_id = 0, $offset = 0, $limit = 150){
2399 $user_id = $this->get_user_id($user_id);
2400 global $wpdb;
2401
2402 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2403 {$wpdb->comments}.comment_post_ID,
2404 {$wpdb->comments}.comment_author,
2405 {$wpdb->comments}.comment_author_email,
2406 {$wpdb->comments}.comment_date,
2407 {$wpdb->comments}.comment_content,
2408 {$wpdb->comments}.user_id,
2409 {$wpdb->commentmeta}.meta_value as rating,
2410 {$wpdb->users}.display_name
2411
2412 from {$wpdb->comments}
2413 INNER JOIN {$wpdb->commentmeta}
2414 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2415 INNER JOIN {$wpdb->users}
2416 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2417 WHERE {$wpdb->comments}.user_id = {$user_id}
2418 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2419 );
2420
2421 return $reviews;
2422 }
2423
2424 /**
2425 * @param $instructor_id
2426 *
2427 * @return object
2428 *
2429 * Get instructors rating
2430 *
2431 * @since v.1.0.0
2432 */
2433 public function get_instructor_ratings($instructor_id){
2434 global $wpdb;
2435
2436 $ratings = array(
2437 'rating_count' => 0,
2438 'rating_sum' => 0,
2439 'rating_avg' => 0.00,
2440 );
2441
2442 $rating = $wpdb->get_row("SELECT COUNT(rating.meta_value) as rating_count, SUM(rating.meta_value) as rating_sum
2443 FROM {$wpdb->usermeta} courses
2444 INNER JOIN {$wpdb->comments} reviews ON courses.meta_value = reviews.comment_post_ID AND reviews.comment_type = 'tutor_course_rating'
2445 INNER JOIN {$wpdb->commentmeta} rating ON reviews.comment_ID = rating.comment_id AND rating.meta_key = 'tutor_rating'
2446 WHERE courses.user_id = {$instructor_id} AND courses.meta_key = '_tutor_instructor_course_id'");
2447
2448 if ($rating->rating_count){
2449 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2450
2451 $ratings = array(
2452 'rating_count' => $rating->rating_count,
2453 'rating_sum' => $rating->rating_sum,
2454 'rating_avg' => $avg_rating,
2455 );
2456 }
2457
2458 return (object) $ratings;
2459 }
2460
2461 /**
2462 * @param int $course_id
2463 * @param int $user_id
2464 *
2465 * @return object
2466 *
2467 * Get course rating by user
2468 *
2469 * @since v.1.0.0
2470 */
2471 public function get_course_rating_by_user($course_id = 0, $user_id = 0){
2472 $course_id = $this->get_post_id($course_id);
2473 $user_id = $this->get_user_id($user_id);
2474
2475 $ratings = array(
2476 'rating' => 0,
2477 'review' => '',
2478 );
2479
2480 global $wpdb;
2481
2482 $rating = $wpdb->get_row("select meta_value as rating, comment_content as review from {$wpdb->comments}
2483 INNER JOIN {$wpdb->commentmeta}
2484 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2485 WHERE {$wpdb->comments}.comment_post_ID = {$course_id} AND user_id = {$user_id}
2486 AND meta_key = 'tutor_rating' ;"
2487 );
2488
2489 if ($rating){
2490 $rating_format = number_format($rating->rating, 2);
2491
2492 $ratings = array(
2493 'rating' => $rating_format,
2494 'review' => $rating->review,
2495 );
2496 }
2497 return (object) $ratings;
2498 }
2499
2500 /**
2501 * @param int $user_id
2502 *
2503 * @return null|string
2504 *
2505 * @since v.1.0.0
2506 */
2507 public function count_reviews_wrote_by_user($user_id = 0){
2508 global $wpdb;
2509 $user_id = $this->get_user_id($user_id);
2510
2511 $count_reviews = $wpdb->get_var("SELECT COUNT(comment_ID) from {$wpdb->comments} WHERE user_id = {$user_id} AND comment_type = 'tutor_course_rating' ");
2512 return $count_reviews;
2513 }
2514
2515 /**
2516 * @param $size
2517 *
2518 * @return bool|int|string
2519 *
2520 * This function transforms the php.ini notation for numbers (like '2M') to an integer.
2521 *
2522 * @since v.1.0.0
2523 */
2524
2525 function let_to_num( $size ) {
2526 $l = substr( $size, -1 );
2527 $ret = substr( $size, 0, -1 );
2528 $byte = 1024;
2529
2530 switch ( strtoupper( $l ) ) {
2531 case 'P':
2532 $ret *= 1024;
2533 // No break.
2534 case 'T':
2535 $ret *= 1024;
2536 // No break.
2537 case 'G':
2538 $ret *= 1024;
2539 // No break.
2540 case 'M':
2541 $ret *= 1024;
2542 // No break.
2543 case 'K':
2544 $ret *= 1024;
2545 // No break.
2546 }
2547 return $ret;
2548 }
2549
2550 /**
2551 * @return array
2552 *
2553 * Get Database version
2554 *
2555 * @since v.1.0.0
2556 */
2557 function get_db_version() {
2558 global $wpdb;
2559
2560 if ( empty( $wpdb->is_mysql ) ) {
2561 return array(
2562 'string' => '',
2563 'number' => '',
2564 );
2565 }
2566
2567 if ( $wpdb->use_mysqli ) {
2568 $server_info = mysqli_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2569 } else {
2570 $server_info = mysql_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2571 }
2572
2573 return array(
2574 'string' => $server_info,
2575 'number' => preg_replace( '/([^\d.]+).*/', '', $server_info ),
2576 );
2577 }
2578
2579 public function help_tip($tip = ''){
2580 return '<span class="tutor-help-tip" data-tip="' . $tip . '"></span>';
2581 }
2582
2583 /**
2584 * @param int $course_id
2585 * @param int $user_id
2586 * @param int $offset
2587 * @param int $limit
2588 *
2589 * @return array|null|object
2590 *
2591 * Get top question
2592 *
2593 * @since v.1.0.0
2594 */
2595 public function get_top_question($course_id = 0, $user_id = 0, $offset = 0, $limit = 20){
2596 $course_id = $this->get_post_id($course_id);
2597 $user_id = $this->get_user_id($user_id);
2598
2599 global $wpdb;
2600
2601 $questions = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2602 {$wpdb->comments}.comment_post_ID,
2603 {$wpdb->comments}.comment_author,
2604 {$wpdb->comments}.comment_date,
2605 {$wpdb->comments}.comment_content,
2606 {$wpdb->comments}.user_id,
2607 {$wpdb->commentmeta}.meta_value as question_title,
2608 {$wpdb->users}.display_name
2609
2610 from {$wpdb->comments}
2611 INNER JOIN {$wpdb->commentmeta}
2612 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2613 INNER JOIN {$wpdb->users}
2614 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2615 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2616 AND {$wpdb->comments}.user_id = {$user_id}
2617 AND {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2618 AND meta_key = 'tutor_question_title' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2619 );
2620
2621 return $questions;
2622 }
2623
2624 /**
2625 * @param string $search_term
2626 *
2627 * @return int
2628 *
2629 * Get total number of Q&A questions
2630 *
2631 * @since v.1.0.0
2632 */
2633 public function get_total_qa_question($search_term = ''){
2634 global $wpdb;
2635
2636 if ($search_term){
2637 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2638 }
2639
2640 $user_id = get_current_user_id();
2641 $course_type = tutor()->course_post_type;
2642
2643 $in_question_id_query = '';
2644 /**
2645 * Get only assinged courses questions if current user is a
2646 */
2647 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2648 $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' " );
2649 $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} " );
2650 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2651
2652 if ( $this->count( $my_course_ids ) ) {
2653 $implode_ids = implode( ',', $my_course_ids );
2654 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2655 }
2656 }
2657
2658 $count = $wpdb->get_var("SELECT COUNT({$wpdb->comments}.comment_ID) FROM {$wpdb->comments}
2659 INNER JOIN {$wpdb->commentmeta}
2660 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2661 WHERE comment_type = 'tutor_q_and_a' AND comment_parent = 0 {$in_question_id_query} {$search_term} ");
2662
2663 return (int) $count;
2664 }
2665
2666 /**
2667 * @param int $start
2668 * @param int $limit
2669 * @param string $search_term
2670 *
2671 * @return array|null|object
2672 *
2673 *
2674 * Get question and answer query
2675 *
2676 * @since v.1.0.0
2677 */
2678 public function get_qa_questions($start = 0, $limit = 10, $search_term = '') {
2679 global $wpdb;
2680
2681 if ($search_term){
2682 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2683 }
2684
2685 $user_id = get_current_user_id();
2686 $course_type = tutor()->course_post_type;
2687
2688 $in_question_id_query = '';
2689 /**
2690 * Get only assinged courses questions if current user is a
2691 */
2692 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2693 $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' " );
2694 $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} " );
2695 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2696
2697 if ( $this->count( $my_course_ids ) ) {
2698 $implode_ids = implode( ',', $my_course_ids );
2699 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2700 }
2701 }
2702
2703 $query = $wpdb->get_results("SELECT
2704 {$wpdb->comments}.comment_ID,
2705 {$wpdb->comments}.comment_post_ID,
2706 {$wpdb->comments}.comment_author,
2707 {$wpdb->comments}.comment_date,
2708 {$wpdb->comments}.comment_content,
2709 {$wpdb->comments}.user_id,
2710 {$wpdb->commentmeta}.meta_value as question_title,
2711 {$wpdb->users}.display_name,
2712 {$wpdb->posts}.post_title,
2713
2714 (SELECT COUNT(answers_t.comment_ID) FROM {$wpdb->comments} answers_t
2715 WHERE answers_t.comment_parent = {$wpdb->comments}.comment_ID ) as answer_count
2716
2717 FROM {$wpdb->comments}
2718
2719 INNER JOIN {$wpdb->commentmeta}
2720 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2721
2722 INNER JOIN {$wpdb->posts}
2723 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2724
2725 INNER JOIN {$wpdb->users}
2726 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2727
2728 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_parent = 0 {$search_term}
2729 {$in_question_id_query}
2730 ORDER BY {$wpdb->comments}.comment_ID DESC
2731 LIMIT {$start},{$limit}; ");
2732
2733 return $query;
2734 }
2735
2736 /**
2737 * @param $question_id
2738 *
2739 * @return array|null|object|void
2740 *
2741 * Get question for Q&A
2742 *
2743 * @since v.1.0.0
2744 */
2745 public function get_qa_question($question_id){
2746 global $wpdb;
2747 $query = $wpdb->get_row("SELECT
2748 {$wpdb->comments}.comment_ID,
2749 {$wpdb->comments}.comment_post_ID,
2750 {$wpdb->comments}.comment_author,
2751 {$wpdb->comments}.comment_date,
2752 {$wpdb->comments}.comment_content,
2753 {$wpdb->comments}.user_id,
2754 {$wpdb->commentmeta}.meta_value as question_title,
2755 {$wpdb->users}.display_name,
2756 {$wpdb->posts}.post_title
2757
2758 FROM {$wpdb->comments}
2759 INNER JOIN {$wpdb->commentmeta}
2760 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2761
2762 INNER JOIN {$wpdb->posts}
2763 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2764
2765 INNER JOIN {$wpdb->users}
2766 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2767 WHERE comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_ID = {$question_id}");
2768
2769 return $query;
2770 }
2771
2772 /**
2773 * @param $question_id
2774 *
2775 * @return array|null|object
2776 *
2777 * Get question and asnwer by question
2778 */
2779 public function get_qa_answer_by_question($question_id){
2780 global $wpdb;
2781 $query = $wpdb->get_results("SELECT
2782 {$wpdb->comments}.comment_ID,
2783 {$wpdb->comments}.comment_post_ID,
2784 {$wpdb->comments}.comment_author,
2785 {$wpdb->comments}.comment_date,
2786 {$wpdb->comments}.comment_content,
2787 {$wpdb->comments}.comment_parent,
2788 {$wpdb->comments}.user_id,
2789 {$wpdb->users}.display_name
2790
2791 FROM {$wpdb->comments}
2792
2793 INNER JOIN {$wpdb->users}
2794 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2795 WHERE comment_type = 'tutor_q_and_a'
2796 AND {$wpdb->comments}.comment_parent = {$question_id} ORDER BY {$wpdb->comments}.comment_ID ASC ");
2797
2798 return $query;
2799 }
2800
2801 public function unanswered_question_count(){
2802 global $wpdb;
2803
2804 $count = $wpdb->get_var("select COUNT({$wpdb->comments}.comment_ID)
2805 from {$wpdb->comments}
2806 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2807 AND {$wpdb->comments}.comment_approved = 'waiting_for_answer'
2808 AND {$wpdb->comments}.comment_parent = 0;");
2809 return (int) $count;
2810 }
2811
2812 /**
2813 * @param int $course_id
2814 *
2815 * @return array|null|object
2816 *
2817 * Return all of announcements for a course
2818 *
2819 * @since v.1.0.0
2820 */
2821 public function get_announcements($course_id = 0){
2822 $course_id = $this->get_post_id($course_id);
2823 global $wpdb;
2824
2825 $query = $wpdb->get_results("select {$wpdb->posts}.ID, post_author, post_date, post_content, post_title, display_name
2826 from {$wpdb->posts}
2827 INNER JOIN {$wpdb->users} ON post_author = {$wpdb->users}.ID
2828 WHERE post_type = 'tutor_announcements'
2829 AND post_parent = {$course_id} ORDER BY {$wpdb->posts}.ID DESC;");
2830 return $query;
2831 }
2832
2833 /**
2834 * @param string $content
2835 *
2836 * @return mixed
2837 *
2838 * Announcement content
2839 *
2840 * @since v.1.0.0
2841 */
2842
2843 public function announcement_content($content = ''){
2844 $search = array('{user_display_name}');
2845
2846 $user_display_name = 'User';
2847 if (is_user_logged_in()){
2848 $user = wp_get_current_user();
2849 $user_display_name = $user->display_name;
2850 }
2851 $replace = array($user_display_name);
2852
2853 return str_replace($search, $replace, $content);
2854 }
2855
2856 /**
2857 * @param int $post_id
2858 * @param string $option_key
2859 * @param bool $default
2860 *
2861 * @return array|bool|mixed
2862 *
2863 * Get the quiz option from meta
2864 */
2865 public function get_quiz_option($post_id = 0, $option_key = '', $default = false){
2866 $post_id = $this->get_post_id($post_id);
2867 $get_option_meta = maybe_unserialize(get_post_meta($post_id, 'tutor_quiz_option', true));
2868
2869 if ( ! $option_key && ! empty($get_option_meta)) {
2870 return $get_option_meta;
2871 }
2872
2873 $value = $this->avalue_dot( $option_key, $get_option_meta );
2874 if ( $value ) {
2875 return $value;
2876 }
2877 return $default;
2878 }
2879
2880
2881 /**
2882 * @param int $quiz_id
2883 *
2884 * @return array|bool|null|object
2885 *
2886 * Get the questions by quiz ID
2887 */
2888 public function get_questions_by_quiz($quiz_id = 0){
2889 $quiz_id = $this->get_post_id($quiz_id);
2890 global $wpdb;
2891
2892 //$questions = $wpdb->get_results("SELECT ID, post_content, post_title, post_parent from {$wpdb->posts} WHERE post_type = 'tutor_question'
2893 // AND post_parent = {$quiz_id} ORDER BY menu_order ASC ");
2894
2895 $questions = $wpdb->get_results("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY question_order ASC ");
2896
2897 if (is_array($questions) && count($questions)){
2898 return $questions;
2899 }
2900 return false;
2901 }
2902
2903 /**
2904 * @param int $question_id
2905 *
2906 * @return array|bool|object|void|null
2907 *
2908 * Get Quiz question by question id
2909 */
2910 public function get_quiz_question_by_id($question_id = 0){
2911 global $wpdb;
2912
2913 if ($question_id){
2914 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} LIMIT 0,1 ;");
2915 return $question;
2916 }
2917
2918 return false;
2919 }
2920
2921 /**
2922 * @param null $type
2923 *
2924 * @return array|mixed
2925 *
2926 * Get all question types
2927 *
2928 * @since v.1.0.0
2929 */
2930
2931 public function get_question_types($type = null){
2932 $types = array(
2933 'true_false' => array('name' => __('True/False', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-yes-no"></i>', 'is_pro' => false),
2934 'single_choice' => array('name' => __('Single Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-mark"></i>', 'is_pro' => false),
2935 'multiple_choice' => array('name' => __('Multiple Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-multiple-choice"></i>', 'is_pro' => false),
2936 'open_ended' => array('name' => __('Open Ended/Essay', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-open-ended"></i>', 'is_pro' => false),
2937 '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),
2938 'short_answer' => array('name' => __('Short Answer', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-short-ans"></i>', 'is_pro' => true),
2939 'matching' => array('name' => __('Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-matching"></i>', 'is_pro' => true),
2940 'image_matching' => array('name' => __('Image Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-matching"></i>', 'is_pro' => true),
2941 'image_answering' => array('name' => __('Image Answering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-ans"></i>', 'is_pro' => true),
2942 'ordering' => array('name' => __('Ordering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-ordering"></i>', 'is_pro' => true),
2943 );
2944
2945 if (isset($types[$type])){
2946 return $types[$type];
2947 }
2948 return $types;
2949 }
2950
2951 public function get_quiz_answer_options_by_question($question_id){
2952 global $wpdb;
2953
2954 $answer_options = $wpdb->get_results("select
2955 {$wpdb->comments}.comment_ID,
2956 {$wpdb->comments}.comment_post_ID,
2957 {$wpdb->comments}.comment_content
2958
2959 FROM {$wpdb->comments}
2960 WHERE {$wpdb->comments}.comment_post_ID = {$question_id}
2961 AND {$wpdb->comments}.comment_type = 'quiz_answer_option'
2962 ORDER BY {$wpdb->comments}.comment_karma ASC ;");
2963
2964 if (is_array($answer_options) && count($answer_options)){
2965 return $answer_options;
2966 }
2967 return false;
2968 }
2969
2970 /**
2971 * @param $quiz_id
2972 *
2973 * @return int
2974 *
2975 * Get the next question order ID
2976 *
2977 * @since v.1.0.0
2978 */
2979
2980 public function quiz_next_question_order_id($quiz_id){
2981 global $wpdb;
2982
2983 //$last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$quiz_id} AND post_type =
2984 // 'tutor_question';");
2985
2986 $last_order = (int) $wpdb->get_var("SELECT MAX(question_order) FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ;");
2987 return $last_order + 1;
2988 }
2989
2990 /**
2991 * @param $quiz_id
2992 *
2993 * @return int
2994 *
2995 * new design quiz question
2996 * @since v.1.0.0
2997 */
2998 public function quiz_next_question_id(){
2999 global $wpdb;
3000
3001 $last_order = (int) $wpdb->get_var("SELECT MAX(question_id) FROM {$wpdb->prefix}tutor_quiz_questions;");
3002 return $last_order + 1;
3003 }
3004
3005 public function get_quiz_id_by_question($question_id){
3006 global $wpdb;
3007
3008 $quiz_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$question_id} AND post_type = 'tutor_question' ;");
3009 return $quiz_id;
3010 }
3011
3012 /**
3013 * @param array $config
3014 *
3015 * @return array|bool|null|object
3016 *
3017 * It was used in previous quiz algorithm
3018 *
3019 * @deprecated
3020 *
3021 * @since v.1.0.0
3022 */
3023 public function get_unattached_quiz($config = array()){
3024 global $wpdb;
3025
3026 $default_attr = array(
3027 'search_term' => '',
3028 'start' => '0',
3029 'limit' => '10',
3030 'order' => 'DESC',
3031 'order_by' => 'ID',
3032 );
3033 $attr = array_merge($default_attr, $config);
3034 extract($attr);
3035
3036 $search_query = '';
3037 if (! empty($search_term)){
3038 $search_query = "AND post_title LIKE '%{$search_term}%'";
3039 }
3040
3041 $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} ");
3042
3043 if (is_array($questions) && count($questions)){
3044 return $questions;
3045 }
3046 return false;
3047 }
3048
3049 /**
3050 * @param int $post_id
3051 *
3052 * @return array|bool|null|object
3053 *
3054 * @since v.1.0.0
3055 */
3056 public function get_attached_quiz($post_id = 0){
3057 global $wpdb;
3058
3059 $post_id = $this->get_post_id($post_id);
3060
3061 $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}");
3062
3063 if (is_array($questions) && count($questions)){
3064 return $questions;
3065 }
3066 return false;
3067 }
3068
3069 /**
3070 * @param $quiz_id
3071 *
3072 * @return array|bool|null|object|void
3073 *
3074 * Get course by quiz
3075 *
3076 * @since v.1.0.0
3077 */
3078
3079 public function get_course_by_quiz($quiz_id){
3080 global $wpdb;
3081
3082 $quiz_id = $this->get_post_id($quiz_id);
3083 $post = get_post($quiz_id);
3084
3085 if ($post) {
3086 $course_post_type = tutor()->course_post_type;
3087 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$post->post_parent} " );
3088
3089 if ($course) {
3090 //Checking if this topic
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 //Checking if this lesson
3095 if ( $course->post_type !== $course_post_type ) {
3096 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
3097 }
3098
3099 return $course;
3100 }
3101 }
3102
3103 return false;
3104 }
3105
3106 /**
3107 * @param $quiz_id
3108 *
3109 * @return int
3110 *
3111 * @since v.1.0.0
3112 */
3113 public function total_questions_for_student_by_quiz($quiz_id){
3114 $quiz_id = $this->get_post_id($quiz_id);
3115 global $wpdb;
3116
3117 $total_question = (int) $wpdb->get_var("select count(ID) from {$wpdb->posts} where post_parent = {$quiz_id} AND post_type = 'tutor_question' ");
3118
3119 return $total_question;
3120 }
3121
3122 /**
3123 * @param int $quiz_id
3124 *
3125 * @return array|null|object|void
3126 *
3127 * Determine if there is any started quiz exists
3128 *
3129 * @since v.1.0.0
3130 */
3131
3132 public function is_started_quiz($quiz_id = 0){
3133 global $wpdb;
3134
3135 $quiz_id = $this->get_post_id($quiz_id);
3136 $user_id = get_current_user_id();
3137
3138 $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' ");
3139
3140 return $is_started;
3141 }
3142
3143 /**
3144 * @param $quiz_id
3145 *
3146 * Method for get the total amount of question for a quiz
3147 * Student will answer this amount of question, one quiz have many question
3148 * but student will answer a specific amount of questions
3149 *
3150 * @return int
3151 *
3152 * @since v.1.0.0
3153 */
3154
3155 public function max_questions_for_take_quiz($quiz_id){
3156 $quiz_id = $this->get_post_id($quiz_id);
3157 global $wpdb;
3158
3159 $max_questions = (int) $wpdb->get_var("select count(question_id) from {$wpdb->prefix}tutor_quiz_questions where quiz_id = {$quiz_id} ");
3160 $max_mentioned = (int) $this->get_quiz_option($quiz_id, 'max_questions_for_answer', 10);
3161
3162 if ($max_mentioned < $max_questions ){
3163 return $max_mentioned;
3164 }
3165
3166 return $max_questions;
3167 }
3168
3169 /**
3170 * @param int $attempt_id
3171 *
3172 * @return array|bool|null|object|void
3173 *
3174 * Get single quiz attempt
3175 *
3176 * @since v.1.0.0
3177 */
3178 public function get_attempt($attempt_id = 0){
3179 global $wpdb;
3180 if ( ! $attempt_id){
3181 return false;
3182 }
3183 $attempt = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE attempt_id = {$attempt_id} ");
3184 return $attempt;
3185 }
3186
3187 /**
3188 * @param $attempt_info
3189 *
3190 * @return mixed
3191 *
3192 * Get unserialize attempt info
3193 *
3194 * @since v.1.0.0
3195 */
3196
3197 public function quiz_attempt_info($attempt_info){
3198 return maybe_unserialize($attempt_info);
3199 }
3200
3201 /**
3202 * @param $quiz_attempt_id
3203 * @param array $attempt_info
3204 *
3205 * @return bool|int
3206 *
3207 * Update attempt for various action
3208 *
3209 * @since v.1.0.0
3210 */
3211 public function quiz_update_attempt_info($quiz_attempt_id, $attempt_info = array()){
3212 $answers = tutor_utils()->avalue_dot('answers', $attempt_info);
3213 $total_marks = array_sum(wp_list_pluck($answers, 'question_mark'));
3214 $earned_marks = tutor_utils()->avalue_dot('marks_earned', $attempt_info);
3215 $earned_mark_percent = $earned_marks > 0 ? ( number_format(($earned_marks * 100) / $total_marks)) : 0;
3216 update_comment_meta($quiz_attempt_id, 'earned_mark_percent', $earned_mark_percent);
3217
3218 return update_comment_meta($quiz_attempt_id,'quiz_attempt_info', $attempt_info);
3219 }
3220
3221 /**
3222 * @param int $quiz_id
3223 *
3224 * @return array|null|object
3225 *
3226 * Get random question by quiz id
3227 *
3228 * @since v.1.0.0
3229 */
3230
3231 public function get_random_question_by_quiz($quiz_id = 0){
3232 global $wpdb;
3233
3234 $quiz_id = $this->get_post_id($quiz_id);
3235 $is_attempt = $this->is_started_quiz($quiz_id);
3236
3237 $tempSql = " AND question_type = 'matching' ";
3238 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} {$tempSql} ORDER BY RAND() LIMIT 0,1 ");
3239
3240 return $questions;
3241 }
3242
3243 /**
3244 * @param int $quiz_id
3245 *
3246 * @return array|null|object
3247 *
3248 * Get random questions by quiz
3249 */
3250 public function get_random_questions_by_quiz($quiz_id = 0){
3251 global $wpdb;
3252
3253 $quiz_id = $this->get_post_id($quiz_id);
3254 $attempt = $this->is_started_quiz($quiz_id);
3255 if ( ! $attempt){
3256 return false;
3257 }
3258
3259 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY RAND() LIMIT {$attempt->total_questions} ");
3260
3261 return $questions;
3262 }
3263
3264 /**
3265 * @param $question_id
3266 * @param bool $rand
3267 *
3268 * @return array|bool|null|object
3269 *
3270 * Get answers list by quiz question
3271 *
3272 * @since v.1.0.0
3273 */
3274 public function get_answers_by_quiz_question($question_id, $rand = false){
3275 global $wpdb;
3276
3277
3278 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} ;");
3279 if ( ! $question){
3280 return false;
3281 }
3282
3283 $order = " answer_order ASC ";
3284 if ($question->question_type === 'ordering'){
3285 $order = " RAND() ";
3286 }
3287
3288 if ($rand){
3289 $order = " RAND() ";
3290 }
3291
3292 $answers = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question_id} AND belongs_question_type =
3293 '{$question->question_type}' order by {$order} ");
3294 return $answers;
3295 }
3296
3297 /**
3298 * @param int $quiz_id
3299 * @param int $user_id
3300 *
3301 * @return array|bool|null|object
3302 *
3303 * Get all of the attempts by an user of a quiz
3304 *
3305 * @since v.1.0.0
3306 */
3307
3308 public function quiz_attempts($quiz_id = 0, $user_id = 0){
3309 global $wpdb;
3310
3311 $quiz_id = $this->get_post_id($quiz_id);
3312 $user_id = $this->get_user_id($user_id);
3313
3314 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE quiz_id = {$quiz_id} AND user_id = {$user_id} ");
3315
3316 if (is_array($attempts) && count($attempts)){
3317 return $attempts;
3318 }
3319
3320 return false;
3321 }
3322
3323
3324 public function get_all_quiz_attempts_by_user($user_id = 0){
3325 global $wpdb;
3326
3327 $user_id = $this->get_user_id($user_id);
3328
3329 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE user_id = {$user_id} ");
3330
3331 if (is_array($attempts) && count($attempts)){
3332 return $attempts;
3333 }
3334
3335 return false;
3336 }
3337
3338 /**
3339 * @param string $search_term
3340 *
3341 * @return int
3342 *
3343 * Total number of quiz attempts
3344 *
3345 * @since v.1.0.0
3346 */
3347
3348 public function get_total_quiz_attempts($search_term = ''){
3349 global $wpdb;
3350
3351 if ($search_term){
3352 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3353 }
3354
3355 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3356 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3357 INNER JOIN {$wpdb->posts} quiz
3358 ON quiz_attempts.quiz_id = quiz.ID
3359 INNER JOIN {$wpdb->users}
3360 ON quiz_attempts.user_id = {$wpdb->users}.ID
3361 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3362 return (int) $count;
3363 }
3364
3365 /**
3366 * @param int $start
3367 * @param int $limit
3368 * @param string $search_term
3369 *
3370 * @return array|null|object
3371 *
3372 *
3373 * Get the all quiz attempts
3374 *
3375 * @since v.1.0.0
3376 */
3377 public function get_quiz_attempts($start = 0, $limit = 10, $search_term = '') {
3378 global $wpdb;
3379
3380 if ($search_term){
3381 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3382 }
3383
3384 $query = $wpdb->get_results("SELECT *
3385 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3386 INNER JOIN {$wpdb->posts} quiz
3387 ON quiz_attempts.quiz_id = quiz.ID
3388 INNER JOIN {$wpdb->users}
3389 ON quiz_attempts.user_id = {$wpdb->users}.ID
3390 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3391 ORDER BY quiz_attempts.attempt_id DESC
3392 LIMIT {$start},{$limit}; ");
3393 return $query;
3394 }
3395
3396 public function get_quiz_attempts_by_course_ids($start = 0, $limit = 10, $course_ids = array(), $search_term = '') {
3397 global $wpdb;
3398
3399 if ($search_term){
3400 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3401 }
3402
3403 $course_ids_in = implode($course_ids, ',');
3404 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3405 $search_term = $sql.$search_term;
3406
3407 $query = $wpdb->get_results("SELECT *
3408 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3409 INNER JOIN {$wpdb->posts} quiz
3410 ON quiz_attempts.quiz_id = quiz.ID
3411 INNER JOIN {$wpdb->users}
3412 ON quiz_attempts.user_id = {$wpdb->users}.ID
3413 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3414 ORDER BY quiz_attempts.attempt_id DESC
3415 LIMIT {$start},{$limit}; ");
3416 return $query;
3417 }
3418
3419 public function get_total_quiz_attempts_by_course_ids($course_ids = array(), $search_term = ''){
3420 global $wpdb;
3421
3422 if ($search_term){
3423 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3424 }
3425
3426 $course_ids_in = implode($course_ids, ',');
3427 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3428 $search_term = $sql.$search_term;
3429
3430 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3431 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3432 INNER JOIN {$wpdb->posts} quiz
3433 ON quiz_attempts.quiz_id = quiz.ID
3434 INNER JOIN {$wpdb->users}
3435 ON quiz_attempts.user_id = {$wpdb->users}.ID
3436 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3437 return (int) $count;
3438 }
3439
3440 /**
3441 * @param $attempt_id
3442 *
3443 * @return array|null|object
3444 *
3445 * Get quiz answers by attempt id
3446 *
3447 * @since v.1.0.0
3448 */
3449 public function get_quiz_answers_by_attempt_id($attempt_id){
3450 global $wpdb;
3451
3452 $results = $wpdb->get_results("SELECT answers.*, question.question_title, question.question_type
3453 FROM {$wpdb->prefix}tutor_quiz_attempt_answers answers
3454 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answers.question_id = question.question_id
3455 WHERE answers.quiz_attempt_id = {$attempt_id} ");
3456
3457 return $results;
3458 }
3459
3460 /**
3461 * @param $answer_id
3462 *
3463 * @return array|null|object
3464 *
3465 * Get single answer by answer_id
3466 *
3467 * @since v.1.0.0
3468 */
3469 public function get_answer_by_id($answer_id){
3470 global $wpdb;
3471
3472 if (is_array($answer_id)){
3473 $in_ids = implode(",", $answer_id);
3474 $sql = "answer.answer_id IN({$in_ids})";
3475 }else{
3476 $sql = "answer.answer_id = {$answer_id}";
3477 }
3478
3479 $answer = $wpdb->get_results("SELECT answer.*, question.question_title, question.question_type
3480 FROM {$wpdb->prefix}tutor_quiz_question_answers answer
3481 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answer.belongs_question_id = question.question_id
3482 WHERE 1=1 AND {$sql} ");
3483
3484 return $answer;
3485 }
3486
3487 /**
3488 * @param $ids
3489 *
3490 * @return array|bool|null|object
3491 *
3492 * Get quiz answers by ids
3493 *
3494 * @since v.1.0.0
3495 */
3496
3497 public function get_quiz_answers_by_ids($ids){
3498 $ids = (array) $ids;
3499
3500 if (!count($ids)){
3501 return false;
3502 }
3503
3504 $in_ids = implode(",", $ids);
3505
3506 global $wpdb;
3507 $query = $wpdb->get_results("SELECT
3508 comment_ID,
3509 comment_content
3510 FROM {$wpdb->comments}
3511 WHERE comment_type = 'quiz_answer_option' AND comment_ID IN({$in_ids}) ");
3512
3513 if (is_array($query) && count($query)){
3514 return $query;
3515 }
3516
3517 return false;
3518 }
3519
3520 /**
3521 * @param null $level
3522 *
3523 * @return mixed
3524 *
3525 * Get the users / students / course levels
3526 *
3527 * @since v.1.0.0
3528 */
3529
3530 public function course_levels($level = null){
3531 $levels = apply_filters('tutor_course_level', array(
3532 'all_levels' => __('All Levels', 'tutor'),
3533 'beginner' => __('Beginner', 'tutor'),
3534 'intermediate' => __('Intermediate', 'tutor'),
3535 'expert' => __('Expert', 'tutor'),
3536 ));
3537
3538 if ($level){
3539 if (isset($levels[$level])){
3540 return $levels[$level];
3541 }else{
3542 return '';
3543 }
3544 }
3545
3546 return $levels;
3547 }
3548
3549 /**
3550 * @return mixed|void
3551 *
3552 * Get user permalink for dashboard
3553 *
3554 * @since v.1.0.0
3555 */
3556 public function user_profile_permalinks(){
3557 $permalinks = array(
3558 'courses_taken' => __('Courses Taken', 'tutor'),
3559 );
3560
3561 $show_enrolled_course = tutor_utils()->get_option('show_courses_completed_by_student');
3562 $enable_show_reviews_wrote = tutor_utils()->get_option('students_own_review_show_at_profile');
3563
3564 if ($show_enrolled_course){
3565 $permalinks['enrolled_course'] = __('Enrolled Course', 'tutor');
3566 }
3567 if ($enable_show_reviews_wrote){
3568 $permalinks['reviews_wrote'] = __('Reviews Written', 'tutor');
3569 }
3570
3571
3572 return apply_filters('tutor_public_profile/permalinks', $permalinks);
3573 }
3574
3575 /**
3576 * @return bool|false|string
3577 *
3578 * Student registration form
3579 *
3580 * @since v.1.0.0
3581 */
3582 public function student_register_url(){
3583 $student_register_page = (int) $this->get_option('student_register_page');
3584
3585 if ($student_register_page){
3586 return get_the_permalink($student_register_page);
3587 }
3588 return false;
3589 }
3590
3591 /**
3592 * @return false|string
3593 *
3594 * Get frontend dashboard URL
3595 */
3596 public function tutor_dashboard_url(){
3597 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3598 $page_id = apply_filters('tutor_dashboard_url', $page_id);
3599 return get_the_permalink($page_id);
3600 }
3601
3602 /**
3603 * @param int $course_id
3604 * @param int $user_id
3605 *
3606 * @return bool
3607 *
3608 * is_wishlisted();
3609 *
3610 * @since v.1.0.0
3611 */
3612 public function is_wishlisted($course_id = 0, $user_id = 0){
3613 $course_id = $this->get_post_id($course_id);
3614 $user_id = $this->get_user_id($user_id);
3615 if ( ! $user_id){
3616 return false;
3617 }
3618
3619 global $wpdb;
3620 $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} ;");
3621
3622 return $if_added_to_list;
3623 }
3624
3625 /**
3626 * @param int $user_id
3627 *
3628 * @return array|null|object
3629 *
3630 * Get the wish lists by an user
3631 *
3632 * @since v.1.0.0
3633 */
3634 public function get_wishlist($user_id = 0){
3635 $user_id = $this->get_user_id($user_id);
3636 global $wpdb;
3637
3638 $query = "SELECT $wpdb->posts.*
3639 FROM $wpdb->posts
3640 LEFT JOIN $wpdb->usermeta ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
3641 WHERE $wpdb->usermeta.meta_key = '_tutor_course_wishlist'
3642 AND $wpdb->usermeta.user_id = {$user_id}
3643 ORDER BY $wpdb->usermeta.umeta_id DESC ";
3644 $pageposts = $wpdb->get_results($query, OBJECT);
3645 return $pageposts;
3646 }
3647
3648 /**
3649 * @param int $limit
3650 *
3651 * @return array|null|object
3652 *
3653 * Getting popular courses
3654 *
3655 * @since v.1.0.0
3656 */
3657 public function most_popular_courses($limit = 10){
3658 global $wpdb;
3659
3660 $courses = $wpdb->get_results("
3661 SELECT COUNT(enrolled.ID) as total_enrolled,
3662 enrolled.post_parent as course_id,
3663 course.*
3664 from {$wpdb->posts} enrolled
3665 INNER JOIN {$wpdb->posts} course ON enrolled.post_parent = course.ID
3666 WHERE enrolled.post_type = 'tutor_enrolled' AND enrolled.post_status = 'completed'
3667
3668 GROUP BY course_id
3669 ORDER BY total_enrolled DESC LIMIT 0,{$limit} ;");
3670
3671 return $courses;
3672 }
3673
3674 /**
3675 * @param int $limit
3676 *
3677 * @return array|bool|null|object
3678 *
3679 * Get most rated courses lists
3680 *
3681 * @since v.1.0.0
3682 */
3683 public function most_rated_courses($limit = 10){
3684 global $wpdb;
3685
3686 $result = $wpdb->get_results("
3687 SELECT COUNT(comment_ID) AS total_rating,
3688 comment_ID,
3689 comment_post_ID,
3690 course.*
3691 FROM {$wpdb->comments}
3692 INNER JOIN {$wpdb->posts} course ON comment_post_ID = course.ID
3693 WHERE {$wpdb->comments}.comment_type = 'tutor_course_rating' AND {$wpdb->comments}.comment_approved = 'approved'
3694 GROUP BY comment_post_ID ORDER BY total_rating DESC LIMIT 0,{$limit}
3695 ;");
3696
3697 if (is_array($result) && count($result)){
3698 return $result;
3699 }
3700 return false;
3701 }
3702
3703 /**
3704 * @param null $addon_field
3705 *
3706 * @return bool
3707 *
3708 * Get Addon config
3709 *
3710 * @since v.1.0.0
3711 */
3712 public function get_addon_config($addon_field = null){
3713 if ( ! $addon_field){
3714 return false;
3715 }
3716
3717 $addonsConfig = maybe_unserialize(get_option('tutor_addons_config'));
3718
3719 if (isset($addonsConfig[$addon_field])){
3720 return $addonsConfig[$addon_field];
3721 }
3722
3723 return false;
3724 }
3725
3726 /**
3727 * @return array|false|string
3728 *
3729 * Get the IP from visitor
3730 *
3731 * @since v.1.0.0
3732 */
3733 function get_ip() {
3734 $ipaddress = '';
3735 if (getenv('HTTP_CLIENT_IP'))
3736 $ipaddress = getenv('HTTP_CLIENT_IP');
3737 else if(getenv('HTTP_X_FORWARDED_FOR'))
3738 $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
3739 else if(getenv('HTTP_X_FORWARDED'))
3740 $ipaddress = getenv('HTTP_X_FORWARDED');
3741 else if(getenv('HTTP_FORWARDED_FOR'))
3742 $ipaddress = getenv('HTTP_FORWARDED_FOR');
3743 else if(getenv('HTTP_FORWARDED'))
3744 $ipaddress = getenv('HTTP_FORWARDED');
3745 else if(getenv('REMOTE_ADDR'))
3746 $ipaddress = getenv('REMOTE_ADDR');
3747 else
3748 $ipaddress = 'UNKNOWN';
3749 return $ipaddress;
3750 }
3751
3752 /**
3753 * @return mixed|void
3754 *
3755 * Get the social icons
3756 *
3757 * @since v.1.0.4
3758 */
3759
3760 public function tutor_social_share_icons(){
3761 $icons = array(
3762 'facebook' => array('share_class' => 's_facebook', 'icon_html' => '<i class="tutor-icon-facebook"></i>' ),
3763 'twitter' => array('share_class' => 's_twitter', 'icon_html' => '<i class="tutor-icon-twitter"></i>' ),
3764 'linkedin' => array('share_class' => 's_linkedin', 'icon_html' => '<i class="tutor-icon-linkdin"></i>' ),
3765 'tumblr' => array('share_class' => 's_tumblr', 'icon_html' => '<i class="tutor-icon-tumblr"></i>' ),
3766 );
3767
3768 return apply_filters('tutor_social_share_icons', $icons);
3769 }
3770
3771 /**
3772 * @param array $array
3773 *
3774 * @return bool
3775 *
3776 * count method with check is_array
3777 *
3778 * @since v.1.0.4
3779 */
3780 public function count($array = array()){
3781 return is_array($array) && count($array);
3782 }
3783
3784 /**
3785 * @return array
3786 *
3787 * get all screen ids
3788 *
3789 * @since v.1.1.2
3790 */
3791 public function tutor_get_screen_ids(){
3792 $screen_ids = array(
3793 "edit-course",
3794 "course",
3795 "edit-course-category",
3796 "edit-course-tag",
3797 "tutor-lms_page_tutor-students",
3798 "tutor-lms_page_tutor-instructors",
3799 "tutor-lms_page_question_answer",
3800 "tutor-lms_page_tutor_quiz_attempts",
3801 "tutor-lms_page_tutor-addons",
3802 "tutor-lms_page_tutor-status",
3803 "tutor-lms_page_tutor_report",
3804 "tutor-lms_page_tutor_settings",
3805 "tutor-lms_page_tutor_emails",
3806 );
3807
3808 return apply_filters('tutor_get_screen_ids', $screen_ids);
3809 }
3810
3811
3812 /**
3813 * @return mixed
3814 *
3815 * get earning transaction completed status
3816 *
3817 * @since v.1.1.2
3818 */
3819 public function get_earnings_completed_statuses(){
3820 return apply_filters(
3821 'tutor_get_earnings_completed_statuses',
3822 array (
3823 'wc-completed',
3824 'completed',
3825 'complete',
3826 )
3827 );
3828 }
3829
3830 /**
3831 * @param int $user_id
3832 * @param array $date_filter
3833 *
3834 * @return array|null|object
3835 *
3836 * Get all time earning sum for an instructor with all commission
3837 *
3838 * @since v.1.1.2
3839 */
3840
3841 public function get_earning_sum($user_id = 0, $date_filter = array()){
3842 global $wpdb;
3843
3844 $user_id = $this->get_user_id($user_id);
3845 $date_query = '';
3846 if ($this->count($date_filter)){
3847 extract($date_filter);
3848
3849 if ( ! empty($dataFor)){
3850 if ($dataFor === 'yearly'){
3851 if (empty($year)){
3852 $year = date('Y');
3853 }
3854 $date_query = "AND YEAR(created_at) = {$year} ";
3855 }
3856 }else{
3857 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
3858 }
3859 }
3860
3861 $complete_status = tutor_utils()->get_earnings_completed_statuses();
3862 $complete_status = "'".implode("','", $complete_status)."'";
3863
3864 $earning_sum = $wpdb->get_row("SELECT SUM(course_price_total) as course_price_total,
3865 SUM(course_price_grand_total) as course_price_grand_total,
3866 SUM(instructor_amount) as instructor_amount,
3867 (SELECT SUM(amount) FROM {$wpdb->prefix}tutor_withdraws WHERE user_id = {$user_id} AND status != 'rejected' ) as
3868 withdraws_amount,
3869 (SUM(instructor_amount) - (SELECT withdraws_amount) ) as balance,
3870 SUM(admin_amount) as admin_amount,
3871 SUM(deduct_fees_amount) as deduct_fees_amount
3872 FROM {$wpdb->prefix}tutor_earnings
3873 WHERE user_id = {$user_id} AND order_status IN({$complete_status}) {$date_query} ");
3874
3875 if ( ! $earning_sum->course_price_total){
3876 $earning_sum = (object) array(
3877 'course_price_total' => 0,
3878 'course_price_grand_total' => 0,
3879 'instructor_amount' => 0,
3880 'withdraws_amount' => 0,
3881 'balance' => 0,
3882 'admin_amount' => 0,
3883 'deduct_fees_amount' => 0,
3884 );
3885 }
3886
3887 return $earning_sum;
3888 }
3889
3890 /**
3891 * @param int $user_id
3892 * @param array $date_filter
3893 *
3894 * @return array|null|object
3895 *
3896 * Get earning statements
3897 *
3898 * @since v.1.1.2
3899 */
3900 public function get_earning_statements($user_id = 0, $filter_data = array()){
3901 global $wpdb;
3902
3903 $user_sql = "";
3904 if ($user_id){
3905 $user_sql = " AND user_id='{$user_id}' ";
3906 }
3907
3908 $date_query = '';
3909 $query_by_status = '';
3910 $pagination_query = '';
3911
3912 /**
3913 * Query by Date Filter
3914 */
3915 if ($this->count($filter_data)){
3916 extract($filter_data);
3917
3918 if ( ! empty($dataFor)){
3919 if ($dataFor === 'yearly'){
3920 if (empty($year)){
3921 $year = date('Y');
3922 }
3923 $date_query = "AND YEAR(created_at) = {$year} ";
3924 }
3925 }else{
3926 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
3927 }
3928
3929 /**
3930 * Query by order status related to this earning transaction
3931 */
3932 if ( ! empty($statuses)) {
3933 if ( $this->count( $statuses ) ) {
3934 $status = "'" . implode( "','", $statuses ) . "'";
3935 $query_by_status = "AND order_status IN({$status})";
3936 } elseif ( $statuses === 'completed' ) {
3937
3938 $get_earnings_completed_statuses = $this->get_earnings_completed_statuses();
3939 if ( $this->count( $get_earnings_completed_statuses ) ) {
3940 $status = "'" . implode( "','", $get_earnings_completed_statuses ) . "'";
3941 $query_by_status = "AND order_status IN({$status})";
3942 }
3943 }
3944 }
3945
3946 if ( ! empty($per_page)){
3947 $offset = (int) ! empty($offset) ? $offset : 0;
3948
3949 $pagination_query = " LIMIT {$offset}, {$per_page} ";
3950
3951 }
3952
3953
3954 }
3955
3956 $query = $wpdb->get_results("SELECT earning_tbl.*, course.post_title as course_title
3957 FROM {$wpdb->prefix}tutor_earnings earning_tbl
3958 LEFT JOIN {$wpdb->posts} course ON earning_tbl.course_id = course.ID
3959 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC {$pagination_query} ");
3960
3961
3962 $query_count = (int) $wpdb->get_var("SELECT COUNT(earning_tbl.earning_id)
3963 FROM {$wpdb->prefix}tutor_earnings earning_tbl
3964 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC ");
3965
3966 return (object) array(
3967 'count' => $query_count,
3968 'results' => $query,
3969 );
3970 }
3971
3972 /**
3973 * @param int $price
3974 *
3975 * @return int|string
3976 *
3977 * Get the price format
3978 *
3979 * @since v.1.1.2
3980 */
3981
3982 public function tutor_price($price = 0){
3983 if (function_exists('wc_price')){
3984 return wc_price($price);
3985 }elseif (function_exists('edd_currency_filter')){
3986 return edd_currency_filter(edd_format_amount($price));
3987 }else{
3988 return number_format_i18n($price);
3989 }
3990 }
3991
3992 /**
3993 * @param int $user_id
3994 *
3995 * @return bool|mixed
3996 *
3997 * Get withdraw method for a specific
3998 */
3999 public function get_user_withdraw_method($user_id = 0){
4000 $user_id = $this->get_user_id($user_id);
4001
4002 $account = get_user_meta($user_id, '_tutor_withdraw_method_data', true);
4003 if ($account){
4004 return maybe_unserialize($account);
4005 }
4006
4007 return false;
4008 }
4009
4010 /**
4011 * @param int $user_id
4012 * @param array $filter
4013 *
4014 * get withdrawal history
4015 *
4016 * @return object
4017 */
4018 public function get_withdrawals_history($user_id = 0, $filter = array()){
4019 global $wpdb;
4020
4021 $filter = (array) $filter;
4022 extract($filter);
4023
4024 $query_by_status_sql = "";
4025 $query_by_user_sql = "";
4026 $query_by_pagination = "";
4027
4028 if ( ! empty($status)){
4029 $status = (array) $status;
4030 $status = "'".implode("','", $status)."'";
4031
4032 $query_by_status_sql = " AND status IN({$status}) ";
4033 }
4034
4035 if ( ! empty($per_page)){
4036 if ( empty($start))
4037 $start = 0;
4038
4039 $query_by_pagination = " LIMIT {$start}, {$per_page} ";
4040 }
4041
4042 if ($user_id){
4043 $query_by_user_sql = " AND user_id = {$user_id} ";
4044 }
4045
4046
4047 $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} ");
4048
4049 $results = $wpdb->get_results("SELECT withdraw_tbl.*,
4050 user_tbl.display_name as user_name,
4051 user_tbl.user_email
4052 FROM {$wpdb->prefix}tutor_withdraws withdraw_tbl
4053 INNER JOIN {$wpdb->users} user_tbl ON withdraw_tbl.user_id = user_tbl.ID
4054 WHERE 1=1
4055 {$query_by_user_sql}
4056 {$query_by_status_sql} ORDER BY
4057 created_at DESC {$query_by_pagination} ");
4058
4059 $withdraw_history = array(
4060 'count' => 0,
4061 'results' => null,
4062 );
4063
4064 if ($count){
4065 $withdraw_history['count'] = $count;
4066 }
4067
4068 if (tutor_utils()->count($results)){
4069 $withdraw_history['results'] = $results;
4070 }
4071 return (object) $withdraw_history;
4072
4073 }
4074
4075 public function add_instructor_role($instructor_id = 0){
4076 if ( ! $instructor_id){
4077 return;
4078 }
4079 do_action('tutor_before_approved_instructor', $instructor_id);
4080
4081 update_user_meta($instructor_id, '_tutor_instructor_status', 'approved');
4082 update_user_meta($instructor_id, '_tutor_instructor_approved', time());
4083
4084 $instructor = new \WP_User($instructor_id);
4085 $instructor->add_role(tutor()->instructor_role);
4086
4087 do_action('tutor_after_approved_instructor', $instructor_id);
4088 }
4089
4090 public function remove_instructor_role($instructor_id = 0){
4091 if ( ! $instructor_id){
4092 return;
4093 }
4094
4095 do_action('tutor_before_blocked_instructor', $instructor_id);
4096 update_user_meta($instructor_id, '_tutor_instructor_status', 'blocked');
4097
4098 $instructor = new \WP_User($instructor_id);
4099 $instructor->remove_role(tutor()->instructor_role);
4100 do_action('tutor_after_blocked_instructor', $instructor_id);
4101 }
4102
4103 }