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