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