PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.3.6
Tutor LMS – eLearning and online course solution v1.3.6
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 6 years ago Admin.php 6 years ago Ajax.php 6 years ago Assets.php 6 years ago Course.php 6 years ago Course_Widget.php 6 years ago Dashboard.php 6 years ago Gutenberg.php 6 years ago Instructor.php 6 years ago Instructors_List.php 6 years ago Lesson.php 6 years ago Options.php 6 years ago Post_types.php 6 years ago Q_and_A.php 6 years ago Question.php 6 years ago Question_Answers_List.php 6 years ago Quiz.php 6 years ago Quiz_Attempts_List.php 6 years ago Rewrite_Rules.php 6 years ago Shortcode.php 6 years ago Student.php 6 years ago Students_List.php 6 years ago Taxonomies.php 6 years ago Template.php 6 years ago Theme_Compatibility.php 6 years ago Tools.php 6 years ago Tutor.php 6 years ago TutorEDD.php 6 years ago Tutor_Base.php 6 years ago Tutor_List_Table.php 6 years ago Upgrader.php 6 years ago User.php 6 years ago Utils.php 6 years ago Video_Stream.php 6 years ago Withdraw.php 6 years ago Withdraw_Requests_List.php 6 years ago WooCommerce.php 6 years ago
Utils.php
4674 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 * @param null $key
97 * @param array $array
98 *
99 * @return array|bool|mixed
100 *
101 * alias of avalue_dot method of utils
102 *
103 * Get array value by key and recursive array value by dot notation key
104 *
105 * ex: tutor_utils()->array_get('key.child_key', $array);
106 *
107 * @since v.1.3.3
108 */
109 public function array_get($key = null, $array = array()){
110 return $this->avalue_dot($key, $array);
111 }
112
113 /**
114 * @return array
115 *
116 * Get all pages
117 *
118 * @since v.1.0.0
119 */
120 public function get_pages(){
121 $pages = array();
122 $wp_pages = get_pages();
123 if (is_array($wp_pages) && count($wp_pages)){
124 foreach ($wp_pages as $page){
125 $pages[$page->ID] = $page->post_title;
126 }
127 }
128 return $pages;
129 }
130
131 /**
132 * @return string
133 *
134 * Get course archive URL
135 *
136 * @since v.1.0.0
137 */
138 public function course_archive_page_url(){
139 $course_post_type = tutor()->course_post_type;
140 $course_page_url = trailingslashit(home_url()).$course_post_type;
141
142 $course_archive_page = $this->get_option('course_archive_page');
143 if ($course_archive_page && $course_archive_page !== '-1'){
144 $course_page_url = get_permalink($course_archive_page);
145 }
146 return trailingslashit($course_page_url);
147 }
148
149 /**
150 * @param int $student_id
151 *
152 * @return string
153 *
154 * Get student URL
155 *
156 * @since v.1.0.0
157 */
158
159 public function profile_url($student_id = 0){
160 $site_url = trailingslashit(home_url()).'profile/';
161 $user_name = '';
162
163 $student_id = $this->get_user_id($student_id);
164 if ($student_id){
165 global $wpdb;
166 $user = $wpdb->get_row("SELECT user_login from {$wpdb->users} WHERE ID = {$student_id} ");
167 if ($user){
168 $user_name = $user->user_login;
169 }
170 }else{
171 $user_name = 'user_name';
172 }
173
174 return $site_url.$user_name;
175 }
176
177 /**
178 * @param string $user_login
179 *
180 * @return array|null|object
181 *
182 * Get user by user login
183 *
184 * @since v.1.0.0
185 */
186 public function get_user_by_login($user_login = ''){
187 global $wpdb;
188 $user_login = sanitize_text_field($user_login);
189 $user = $wpdb->get_row("SELECT * from {$wpdb->users} WHERE user_login = '{$user_login}'");
190 return $user;
191 }
192
193 /**
194 * @return bool
195 *
196 * Check if WooCommerce Activated
197 *
198 * @since v.1.0.0
199 */
200
201 public function has_wc(){
202 $activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ));
203 //$depends = array('woocommerce/woocommerce.php', 'tutor-woocommerce/tutor-woocommerce.php');
204 $depends = array('woocommerce/woocommerce.php');
205 $has = count(array_intersect($depends, $activated_plugins)) == count($depends);
206
207 return $has;
208 }
209
210 /**
211 * @return bool
212 *
213 * determine if EDD plugin activated
214 *
215 * @since v.1.0.0
216 */
217 public function has_edd(){
218 $activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ));
219 //$depends = array('easy-digital-downloads/easy-digital-downloads.php', 'tutor-edd/tutor-edd.php');
220 $depends = array('easy-digital-downloads/easy-digital-downloads.php');
221 $has = count(array_intersect($depends, $activated_plugins)) == count($depends);
222
223 return $has;
224 }
225
226 /**
227 * @return bool
228 *
229 * Determine if PMPro is activated
230 *
231 * @since v.1.3.6
232 */
233 public function has_pmpro(){
234 $activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ));
235 $depends = array('paid-memberships-pro/paid-memberships-pro.php');
236 return count(array_intersect($depends, $activated_plugins)) == count($depends);
237 }
238
239 /**
240 * @return mixed
241 *
242 * @since v.1.0.0
243 */
244 public function languages(){
245 $language_codes = array(
246 'en' => 'English' ,
247 'aa' => 'Afar' ,
248 'ab' => 'Abkhazian' ,
249 'af' => 'Afrikaans' ,
250 'am' => 'Amharic' ,
251 'ar' => 'Arabic' ,
252 'as' => 'Assamese' ,
253 'ay' => 'Aymara' ,
254 'az' => 'Azerbaijani' ,
255 'ba' => 'Bashkir' ,
256 'be' => 'Byelorussian' ,
257 'bg' => 'Bulgarian' ,
258 'bh' => 'Bihari' ,
259 'bi' => 'Bislama' ,
260 'bn' => 'Bengali/Bangla' ,
261 'bo' => 'Tibetan' ,
262 'br' => 'Breton' ,
263 'ca' => 'Catalan' ,
264 'co' => 'Corsican' ,
265 'cs' => 'Czech' ,
266 'cy' => 'Welsh' ,
267 'da' => 'Danish' ,
268 'de' => 'German' ,
269 'dz' => 'Bhutani' ,
270 'el' => 'Greek' ,
271 'eo' => 'Esperanto' ,
272 'es' => 'Spanish' ,
273 'et' => 'Estonian' ,
274 'eu' => 'Basque' ,
275 'fa' => 'Persian' ,
276 'fi' => 'Finnish' ,
277 'fj' => 'Fiji' ,
278 'fo' => 'Faeroese' ,
279 'fr' => 'French' ,
280 'fy' => 'Frisian' ,
281 'ga' => 'Irish' ,
282 'gd' => 'Scots/Gaelic' ,
283 'gl' => 'Galician' ,
284 'gn' => 'Guarani' ,
285 'gu' => 'Gujarati' ,
286 'ha' => 'Hausa' ,
287 'hi' => 'Hindi' ,
288 'hr' => 'Croatian' ,
289 'hu' => 'Hungarian' ,
290 'hy' => 'Armenian' ,
291 'ia' => 'Interlingua' ,
292 'ie' => 'Interlingue' ,
293 'ik' => 'Inupiak' ,
294 'in' => 'Indonesian' ,
295 'is' => 'Icelandic' ,
296 'it' => 'Italian' ,
297 'iw' => 'Hebrew' ,
298 'ja' => 'Japanese' ,
299 'ji' => 'Yiddish' ,
300 'jw' => 'Javanese' ,
301 'ka' => 'Georgian' ,
302 'kk' => 'Kazakh' ,
303 'kl' => 'Greenlandic' ,
304 'km' => 'Cambodian' ,
305 'kn' => 'Kannada' ,
306 'ko' => 'Korean' ,
307 'ks' => 'Kashmiri' ,
308 'ku' => 'Kurdish' ,
309 'ky' => 'Kirghiz' ,
310 'la' => 'Latin' ,
311 'ln' => 'Lingala' ,
312 'lo' => 'Laothian' ,
313 'lt' => 'Lithuanian' ,
314 'lv' => 'Latvian/Lettish' ,
315 'mg' => 'Malagasy' ,
316 'mi' => 'Maori' ,
317 'mk' => 'Macedonian' ,
318 'ml' => 'Malayalam' ,
319 'mn' => 'Mongolian' ,
320 'mo' => 'Moldavian' ,
321 'mr' => 'Marathi' ,
322 'ms' => 'Malay' ,
323 'mt' => 'Maltese' ,
324 'my' => 'Burmese' ,
325 'na' => 'Nauru' ,
326 'ne' => 'Nepali' ,
327 'nl' => 'Dutch' ,
328 'no' => 'Norwegian' ,
329 'oc' => 'Occitan' ,
330 'om' => '(Afan)/Oromoor/Oriya' ,
331 'pa' => 'Punjabi' ,
332 'pl' => 'Polish' ,
333 'ps' => 'Pashto/Pushto' ,
334 'pt' => 'Portuguese' ,
335 'qu' => 'Quechua' ,
336 'rm' => 'Rhaeto-Romance' ,
337 'rn' => 'Kirundi' ,
338 'ro' => 'Romanian' ,
339 'ru' => 'Russian' ,
340 'rw' => 'Kinyarwanda' ,
341 'sa' => 'Sanskrit' ,
342 'sd' => 'Sindhi' ,
343 'sg' => 'Sangro' ,
344 'sh' => 'Serbo-Croatian' ,
345 'si' => 'Singhalese' ,
346 'sk' => 'Slovak' ,
347 'sl' => 'Slovenian' ,
348 'sm' => 'Samoan' ,
349 'sn' => 'Shona' ,
350 'so' => 'Somali' ,
351 'sq' => 'Albanian' ,
352 'sr' => 'Serbian' ,
353 'ss' => 'Siswati' ,
354 'st' => 'Sesotho' ,
355 'su' => 'Sundanese' ,
356 'sv' => 'Swedish' ,
357 'sw' => 'Swahili' ,
358 'ta' => 'Tamil' ,
359 'te' => 'Tegulu' ,
360 'tg' => 'Tajik' ,
361 'th' => 'Thai' ,
362 'ti' => 'Tigrinya' ,
363 'tk' => 'Turkmen' ,
364 'tl' => 'Tagalog' ,
365 'tn' => 'Setswana' ,
366 'to' => 'Tonga' ,
367 'tr' => 'Turkish' ,
368 'ts' => 'Tsonga' ,
369 'tt' => 'Tatar' ,
370 'tw' => 'Twi' ,
371 'uk' => 'Ukrainian' ,
372 'ur' => 'Urdu' ,
373 'uz' => 'Uzbek' ,
374 'vi' => 'Vietnamese' ,
375 'vo' => 'Volapuk' ,
376 'wo' => 'Wolof' ,
377 'xh' => 'Xhosa' ,
378 'yo' => 'Yoruba' ,
379 'zh' => 'Chinese' ,
380 'zu' => 'Zulu' ,
381 );
382
383 return apply_filters('tutor/utils/languages', $language_codes);
384 }
385
386
387 /**
388 * @param string $value
389 *
390 * Check raw data
391 *
392 * @since v.1.0.0
393 */
394 public function print_view($value = ''){
395 echo '<pre>';
396 print_r($value);
397 echo '</pre>';
398 }
399
400 /**
401 * @param array $excludes
402 *
403 * @return array|null|object
404 *
405 * Get courses
406 *
407 * @since v.1.0.0
408 */
409
410 public function get_courses($excludes = array()){
411 global $wpdb;
412
413
414 $excludes = (array) $excludes;
415 $exclude_query = '';
416 if (count($excludes)){
417 $exclude_query = implode("','", $excludes);
418 }
419
420 $course_post_type = tutor()->course_post_type;
421 $query = $wpdb->get_results("SELECT ID, post_author, post_title, post_name,post_status, menu_order
422 from {$wpdb->posts} WHERE post_status = 'publish'
423 AND ID NOT IN('$exclude_query')
424 AND post_type = '{$course_post_type}' ");
425 return $query;
426 }
427
428 /**
429 * @param int $instructor_id
430 *
431 * @return array|null|object
432 *
433 * Get courses for instructors
434 *
435 * @since v.1.0.0
436 */
437 public function get_courses_for_instructors($instructor_id = 0){
438 global $wpdb;
439
440 $instructor_id = $this->get_user_id($instructor_id);
441
442 $course_post_type = tutor()->course_post_type;
443 $query = $wpdb->get_results("SELECT ID, post_author, post_title, post_name,post_status, menu_order
444 from {$wpdb->posts}
445 WHERE post_author = {$instructor_id}
446 AND post_status IN ('publish', 'pending')
447 AND post_type = '{$course_post_type}' ");
448 return $query;
449 }
450
451 /**
452 * @param $instructor_id
453 *
454 * @return null|string
455 *
456 * Get course count by instructor
457 *
458 * @since v.1.0.0
459 */
460
461 public function get_course_count_by_instructor($instructor_id){
462 global $wpdb;
463
464 $course_post_type = tutor()->course_post_type;
465 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts}
466 INNER JOIN {$wpdb->usermeta} ON user_id = {$instructor_id} AND meta_key = '_tutor_instructor_course_id' AND meta_value = ID
467 WHERE post_status = 'publish'
468 AND post_type = '{$course_post_type}' ; ");
469
470 return $count;
471 }
472
473 /**
474 * @param $instructor_id
475 *
476 * @return array|null|object
477 *
478 * Get courses by a instructor
479 *
480 * @since v.1.0.0
481 */
482 public function get_courses_by_instructor($instructor_id = 0, $post_status = array('publish')){
483 global $wpdb;
484
485 $instructor_id = $this->get_user_id($instructor_id);
486 $course_post_type = tutor()->course_post_type;
487
488
489 if ($post_status === 'any'){
490 $where_post_status = "";
491 }else{
492 $post_status = (array) $post_status;
493 $statuses = "'".implode("','", $post_status)."'";
494 $where_post_status = "AND $wpdb->posts.post_status IN({$statuses}) ";
495 }
496
497 $querystr = "
498 SELECT $wpdb->posts.*
499 FROM $wpdb->posts
500 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
501
502 WHERE 1 = 1 {$where_post_status}
503 AND $wpdb->posts.post_type = '{$course_post_type}'
504 AND $wpdb->posts.post_date < NOW()
505 ORDER BY $wpdb->posts.post_date DESC";
506
507 $pageposts = $wpdb->get_results($querystr, OBJECT);
508 return $pageposts;
509 }
510
511 /**
512 * @return mixed
513 *
514 * Get archive page course count
515 *
516 * @since v.1.0.0
517 */
518 public function get_archive_page_course_count(){
519 global $wp_query;
520 return $wp_query->post_count;
521 }
522
523 /**
524 * @return null|string
525 *
526 * Get course count
527 *
528 * @since v.1.0.0
529 */
530 public function get_course_count(){
531 global $wpdb;
532
533 $course_post_type = tutor()->course_post_type;
534 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = '{$course_post_type}'; ");
535 return $count;
536 }
537
538 /**
539 * @return null|string
540 *
541 * Get lesson count
542 *
543 * @since v.1.0.0
544 */
545 public function get_lesson_count(){
546 global $wpdb;
547
548 $lesson_post_type = tutor()->lesson_post_type;
549 $count = $wpdb->get_var("SELECT COUNT(ID) from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = '{$lesson_post_type}'; ");
550 return $count;
551 }
552
553 /**
554 * @param int $course_id
555 * @param int $limit
556 *
557 * @return \WP_Query
558 *
559 * Get lesson
560 *
561 * @since v.1.0.0
562 */
563 public function get_lesson($course_id = 0, $limit = 10){
564 $course_id = $this->get_post_id($course_id);
565
566 $lesson_post_type = tutor()->lesson_post_type;
567 $args = array(
568 'post_status' => 'publish',
569 'post_type' => $lesson_post_type,
570 'posts_per_page' => $limit,
571 'meta_query' => array(
572 array(
573 'key' => '_tutor_course_id_for_lesson',
574 'value' => $course_id,
575 'compare' => '=',
576 ),
577 ),
578 );
579 $query = new \WP_Query($args);
580
581 return $query;
582 }
583
584 /**
585 * @param int $course_id
586 *
587 * @return int
588 *
589 * Get total lesson count by a course
590 *
591 * @since v.1.0.0
592 */
593 public function get_lesson_count_by_course($course_id = 0){
594 $course_id = $this->get_post_id($course_id);
595 global $wpdb;
596
597 $lesson_post_type = tutor()->lesson_post_type;
598
599 $course_id = $this->get_post_id($course_id);
600 $topicIDS = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'topics' AND post_parent = {$course_id} ");
601
602 $lesson_count = 0;
603 if ($this->count($topicIDS)){
604 $inIDS = implode(",", $topicIDS);
605 $lesson_count = $wpdb->get_var("SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_parent IN({$inIDS}) AND post_type = '{$lesson_post_type}' ");
606 }
607
608 return (int) $lesson_count;
609 }
610
611 /**
612 * @param int $course_id
613 * @param int $user_id
614 *
615 * @return int
616 *
617 * Get completed lesson total number by a course
618 *
619 * @since v.1.0.0
620 */
621 public function get_completed_lesson_count_by_course($course_id = 0, $user_id = 0){
622 $course_id = $this->get_post_id($course_id);
623 $user_id = $this->get_user_id($user_id);
624 global $wpdb;
625
626 $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} ");
627
628 $count = 0;
629 if (is_array($completed_lesson_ids) && count($completed_lesson_ids)){
630 $completed_lesson_meta_ids = array();
631 foreach ($completed_lesson_ids as $lesson_id){
632 $completed_lesson_meta_ids[] = '_tutor_completed_lesson_id_'.$lesson_id;
633 }
634 $in_ids = implode("','", $completed_lesson_meta_ids);
635
636 $count = (int) $wpdb->get_var("select count(umeta_id) from {$wpdb->usermeta} WHERE user_id = '{$user_id}' AND meta_key in('{$in_ids}') ");
637 }
638
639 return $count;
640 }
641
642 /**
643 * @param int $course_id
644 * @param int $user_id
645 *
646 * @return float|int
647 *
648 * @since v.1.0.0
649 */
650 public function get_course_completed_percent($course_id = 0, $user_id = 0){
651 $course_id = $this->get_post_id($course_id);
652 $user_id = $this->get_user_id($user_id);
653
654 $total_lesson = $this->get_lesson_count_by_course($course_id);
655 $completed_lesson = $this->get_completed_lesson_count_by_course($course_id, $user_id);
656
657 if ($total_lesson > 0 && $completed_lesson > 0){
658 return number_format(($completed_lesson * 100) / $total_lesson);
659 }
660
661 return 0;
662 }
663
664 /**
665 * @param int $course_id
666 *
667 * @return \WP_Query
668 *
669 * Get all topics by given course ID
670 *
671 * @since v.1.0.0
672 */
673 public function get_topics($course_id = 0){
674 $course_id = $this->get_post_id($course_id);
675
676 $args = array(
677 'post_type' => 'topics',
678 'post_parent' => $course_id,
679 'orderby' => 'menu_order',
680 'order' => 'ASC',
681 'posts_per_page' => -1,
682 );
683
684 $query = new \WP_Query($args);
685 return $query;
686 }
687
688 /**
689 * @param $course_ID
690 *
691 * @return int
692 *
693 * Get next topic order id
694 *
695 * @since v.1.0.0
696 */
697 public function get_next_topic_order_id($course_ID){
698 global $wpdb;
699
700 $last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$course_ID} AND post_type = 'topics';");
701 return $last_order + 1;
702 }
703
704 /**
705 * @param $topic_ID
706 *
707 * @return int
708 *
709 * Get next course content order id
710 *
711 * @since v.1.0.0
712 */
713 public function get_next_course_content_order_id($topic_ID){
714 global $wpdb;
715
716 $last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$topic_ID};");
717 return $last_order + 1;
718 }
719
720 /**
721 * @param int $topics_id
722 * @param int $limit
723 *
724 * @return \WP_Query
725 *
726 * Get lesson by topic
727 *
728 * @since v.1.0.0
729 */
730 public function get_lessons_by_topic($topics_id = 0, $limit = 10){
731 $topics_id = $this->get_post_id($topics_id);
732
733 $lesson_post_type = tutor()->lesson_post_type;
734 $args = array(
735 'post_type' => $lesson_post_type,
736 'post_parent' => $topics_id,
737 'posts_per_page' => $limit,
738 'orderby' => 'menu_order',
739 'order' => 'ASC',
740 );
741
742 $query = new \WP_Query($args);
743
744 return $query;
745 }
746
747 /**
748 * @param int $topics_id
749 * @param int $limit
750 *
751 * @return \WP_Query
752 *
753 * Get course content by topic
754 *
755 * @since v.1.0.0
756 */
757 public function get_course_contents_by_topic($topics_id = 0, $limit = 10){
758 $topics_id = $this->get_post_id($topics_id);
759
760 $lesson_post_type = tutor()->lesson_post_type;
761 $args = array(
762 'post_type' => apply_filters('tutor_course_contents_post_types', array($lesson_post_type, 'tutor_quiz')),
763 'post_parent' => $topics_id,
764 'posts_per_page' => $limit,
765 'orderby' => 'menu_order',
766 'order' => 'ASC',
767 );
768
769 $query = new \WP_Query($args);
770
771 return $query;
772 }
773
774 /**
775 * @param string $request_method
776 *
777 * Check actions nonce
778 *
779 * @since v.1.0.0
780 */
781 public function checking_nonce($request_method = 'post'){
782 if ($request_method === 'post'){
783 if (!isset($_POST[tutor()->nonce]) || !wp_verify_nonce($_POST[tutor()->nonce], tutor()->nonce_action)) {
784 exit('Nonce does not matched');
785 }
786 }else{
787 if (!isset($_GET[tutor()->nonce]) || !wp_verify_nonce($_GET[tutor()->nonce], tutor()->nonce_action)) {
788 exit('Nonce does not matched');
789 }
790 }
791 }
792
793 /**
794 * @param int $course_id
795 *
796 * @return bool
797 *
798 * @since v.1.0.0
799 */
800 public function is_course_purchasable($course_id = 0){
801 $course_id = $this->get_post_id($course_id);
802
803 $price_type = $this->price_type($course_id);
804 if ($price_type === 'free'){
805 $is_paid = apply_filters('is_course_paid', false, $course_id);
806 if ( ! $is_paid){
807 return false;
808 }
809 }
810 return apply_filters('is_course_purchasable', false, $course_id);
811 }
812
813 /**
814 * @param int $course_id
815 *
816 * @return null|string
817 *
818 * get course price in digits format if any
819 *
820 * @since v.1.0.0
821 */
822
823 public function get_course_price($course_id = 0){
824 $course_id = $this->get_post_id($course_id);
825
826 $price = null;
827
828 if ($this->is_course_purchasable()) {
829 $monetize_by = $this->get_option('monetize_by');
830
831 if ($this->has_wc() && $monetize_by === 'wc'){
832 $product_id = tutor_utils()->get_course_product_id($course_id);
833 $product = wc_get_product( $product_id );
834
835 if ( $product ) {
836 $price = $product->get_price();
837 }
838 }else{
839 $price = apply_filters('get_tutor_course_price', null, $course_id);
840 }
841 }
842
843 return $price;
844 }
845
846 /**
847 * @param int $course_id
848 *
849 * @return object
850 *
851 * Get raw course price and sale price of a course
852 * It could help you to calculate something
853 * Such as Calculate discount by regular price and sale price
854 *
855 * @since v.1.3.1
856 */
857 public function get_raw_course_price($course_id = 0){
858 $course_id = $this->get_post_id($course_id);
859
860 $prices = array(
861 'regular_price' => 0,
862 'sale_price' => 0,
863 );
864
865 $monetize_by = $this->get_option('monetize_by');
866
867 //if ($this->is_course_purchasable($course_id)){
868 $product_id = $this->get_course_product_id($course_id);
869 if ($product_id) {
870 if ( $monetize_by === 'wc' && $this->has_wc() ) {
871 $prices['regular_price'] = get_post_meta( $product_id, '_regular_price', true );
872 $prices['sale_price'] = get_post_meta( $product_id, '_sale_price', true );
873 } elseif ( $monetize_by === 'edd' && $this->has_edd() ) {
874 $prices['regular_price'] = get_post_meta( $product_id, 'edd_price', true );
875 $prices['sale_price'] = get_post_meta( $product_id, 'edd_price', true );
876 }
877 }
878 //}
879
880 return (object) $prices;
881 }
882
883 /**
884 * @param int $course_id
885 *
886 * @return mixed
887 *
888 * Get the course price type
889 *
890 * @since v.1.3.5
891 */
892
893 public function price_type($course_id = 0){
894 $course_id = $this->get_post_id($course_id);
895
896 $price_type = get_post_meta($course_id, '_tutor_course_price_type', true);
897 return $price_type;
898 }
899
900 /**
901 * @param int $course_id
902 *
903 * @return array|bool|null|object
904 *
905 * Check if current user has been enrolled or not
906 *
907 * @since v.1.0.0
908 */
909
910 public function is_enrolled($course_id = 0, $user_id = 0){
911 $course_id = $this->get_post_id($course_id);
912 $user_id = $this->get_user_id($user_id);
913
914 if (is_user_logged_in()) {
915 global $wpdb;
916
917 $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'; " );
918
919 if ( $getEnrolledInfo ) {
920 return $getEnrolledInfo;
921 }
922 }
923 return false;
924 }
925
926 /**
927 * @param int $course_id
928 * @param int $user_id
929 *
930 * @return array|bool|null|object|void
931 *
932 * Has any enrolled for a user in a course
933 *
934 * @since v.1.0.0
935 */
936 public function has_any_enrolled($course_id = 0, $user_id = 0){
937 $course_id = $this->get_post_id($course_id);
938 $user_id = $this->get_user_id($user_id);
939
940 if (is_user_logged_in()) {
941 global $wpdb;
942
943 $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}; " );
944
945 if ( $getEnrolledInfo ) {
946 return $getEnrolledInfo;
947 }
948 }
949 return false;
950 }
951
952 /**
953 * @param int $lesson_id
954 * @param int $user_id
955 *
956 * @return array|bool|null|object
957 *
958 * Get the course Enrolled confirmation by lesson ID
959 *
960 * @since v.1.0.0
961 */
962
963 public function is_course_enrolled_by_lesson($lesson_id = 0, $user_id = 0){
964 $lesson_id = $this->get_post_id($lesson_id);
965 $user_id = $this->get_user_id($user_id);
966
967 return $this->is_enrolled($this->get_course_id_by_lesson($lesson_id));
968 }
969
970 /**
971 * @param int $lesson_id
972 *
973 * @return bool|mixed
974 *
975 * Get the course ID by Lesson
976 *
977 * @since v.1.0.0
978 */
979 public function get_course_id_by_lesson($lesson_id = 0){
980 $lesson_id = $this->get_post_id($lesson_id);
981 return get_post_meta($lesson_id, '_tutor_course_id_for_lesson', true);
982 }
983
984 /**
985 * @param int $course_id
986 *
987 * @return bool|false|string
988 *
989 * Get first lesson of a course
990 *
991 * @since v.1.0.0
992 */
993 public function get_course_first_lesson($course_id = 0){
994 $course_id = $this->get_post_id($course_id);
995 global $wpdb;
996
997 $lesson_id = $wpdb->get_var("
998 SELECT post_id as lesson_id
999 FROM $wpdb->postmeta
1000 INNER JOIN {$wpdb->posts} ON post_id = {$wpdb->posts}.ID
1001 WHERE meta_key = '_tutor_course_id_for_lesson' AND meta_value = {$course_id}
1002
1003 ORDER BY menu_order ASC LIMIT 1
1004 ");
1005
1006 /*
1007 $lesson_id = $wpdb->get_var(" select main_posts.ID from {$wpdb->posts} main_posts
1008 WHERE post_parent =
1009 (SELECT sub_posts.ID FROM {$wpdb->posts} sub_posts
1010 WHERE post_type = 'topics' AND
1011 sub_posts.post_parent = {$course_id} ORDER BY sub_posts.menu_order ASC LIMIT 1 )
1012 ORDER BY main_posts.menu_order ASC LIMIT 1 ;");
1013 */
1014
1015 if ($lesson_id){
1016 return get_permalink($lesson_id);
1017 }
1018 return false;
1019 }
1020
1021 /**
1022 *
1023 * Get course sub pages in course dashboard
1024 *
1025 * @since v.1.0.0
1026 */
1027 public function course_sub_pages(){
1028 $nav_items = array(
1029 'overview' => __('Overview', 'tutor'),
1030 );
1031
1032 $enable_q_and_a_on_course = tutor_utils()->get_option('enable_q_and_a_on_course');
1033 if ($enable_q_and_a_on_course){
1034 $nav_items['questions'] = __('Q&A', 'tutor');
1035 }
1036 $nav_items['announcements'] = __('Announcements', 'tutor');
1037
1038 return apply_filters('tutor_course/single/enrolled/nav_items', $nav_items);
1039 }
1040
1041 /**
1042 * @param int $post_id
1043 *
1044 * @return bool|array
1045 *
1046 * @since v.1.0.0
1047 */
1048 public function get_video($post_id = 0){
1049 $post_id = $this->get_post_id($post_id);
1050 $attachments = get_post_meta($post_id, '_video', true);
1051 if ($attachments) {
1052 $attachments = maybe_unserialize($attachments);
1053 }
1054 return $attachments;
1055 }
1056
1057 /**
1058 * @param int $post_id
1059 * @param array $video_data
1060 *
1061 * @return bool
1062 *
1063 * Update the video Info
1064 */
1065 public function update_video($post_id = 0, $video_data = array()){
1066 $post_id = $this->get_post_id($post_id);
1067
1068 if (is_array($video_data) && count($video_data)){
1069 update_post_meta($post_id, '_video', $video_data);
1070 }
1071 }
1072
1073 /**
1074 * @param int $post_id
1075 *
1076 * @return bool|mixed
1077 *
1078 * @since v.1.0.0
1079 */
1080 public function get_attachments($post_id = 0){
1081 $post_id = $this->get_post_id($post_id);
1082 $attachments_arr = array();
1083 $attachments = maybe_unserialize(get_post_meta($post_id, '_tutor_attachments', true));
1084
1085 $font_icons = apply_filters('tutor_file_types_icon', array(
1086 'archive',
1087 'audio',
1088 'code',
1089 'default',
1090 'document',
1091 'interactive',
1092 'spreadsheet',
1093 'text',
1094 'video',
1095 'image',
1096 ));
1097
1098 if ( is_array($attachments) && count($attachments)) {
1099 foreach ( $attachments as $attachment ) {
1100 $url = wp_get_attachment_url( $attachment );
1101 $file_type = wp_check_filetype( $url );
1102 $ext = $file_type['ext'];
1103 $title = get_the_title($attachment);
1104
1105 $file_path = get_attached_file( $attachment );
1106 $size_bytes = file_exists($file_path) ? filesize( $file_path ) : 0;
1107 $size = size_format( $size_bytes, 2 );
1108 $type = wp_ext2type( $ext );
1109
1110 $icon = 'default';
1111 if ( $type && in_array( $type, $font_icons ) ) {
1112 $icon = $type;
1113 }
1114
1115 $data = array(
1116 'post_id' => $post_id,
1117 'id' => $attachment,
1118 'url' => $url,
1119 'name' => $title . '.' . $ext,
1120 'title' => $title,
1121 'ext' => $ext,
1122 'size' => $size,
1123 'size_bytes' => $size_bytes,
1124 'icon' => $icon,
1125 );
1126
1127 $attachments_arr[] = (object) apply_filters( 'tutor/posts/attachments', $data );
1128 }
1129 }
1130
1131 return $attachments_arr;
1132 }
1133
1134
1135 /**
1136 * @param $seconds
1137 *
1138 * @return string
1139 *
1140 * return seconds to formatted playtime
1141 *
1142 * @since v.1.0.0
1143 */
1144 public function playtime_string($seconds) {
1145 $sign = (($seconds < 0) ? '-' : '');
1146 $seconds = round(abs($seconds));
1147 $H = (int) floor( $seconds / 3600);
1148 $M = (int) floor(($seconds - (3600 * $H) ) / 60);
1149 $S = (int) round( $seconds - (3600 * $H) - (60 * $M) );
1150 return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
1151 }
1152
1153 /**
1154 * @param $seconds
1155 *
1156 * @return array
1157 *
1158 * Get the playtime in array
1159 *
1160 * @since v.1.0.0
1161 */
1162 public function playtime_array($seconds){
1163 $run_time_format = array(
1164 'hours' => '00',
1165 'minutes' => '00',
1166 'seconds' => '00',
1167 );
1168
1169 if ($seconds <= 0 ){
1170 return $run_time_format;
1171 }
1172
1173 $playTimeString = $this->playtime_string($seconds);
1174 $timeInArray = explode(':', $playTimeString);
1175
1176 $run_time_size = count($timeInArray);
1177 if ($run_time_size === 3){
1178 $run_time_format['hours'] = $timeInArray[0];
1179 $run_time_format['minutes'] = $timeInArray[1];
1180 $run_time_format['seconds'] = $timeInArray[2];
1181 }elseif($run_time_size === 2){
1182 $run_time_format['minutes'] = $timeInArray[0];
1183 $run_time_format['seconds'] = $timeInArray[1];
1184 }
1185
1186 return $run_time_format;
1187 }
1188
1189 /**
1190 * @param $seconds
1191 *
1192 * @return string
1193 *
1194 * Convert seconds to human readable time
1195 *
1196 * @since v.1.0.0
1197 */
1198 public function seconds_to_time_context($seconds) {
1199 $sign = (($seconds < 0) ? '-' : '');
1200 $seconds = round(abs($seconds));
1201 $H = (int) floor( $seconds / 3600);
1202 $M = (int) floor(($seconds - (3600 * $H) ) / 60);
1203 $S = (int) round( $seconds - (3600 * $H) - (60 * $M) );
1204
1205 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';
1206 }
1207
1208 /**
1209 * @param int $lesson_id
1210 *
1211 * @return bool|object
1212 *
1213 * @since v.1.0.0
1214 */
1215
1216 public function get_video_info($lesson_id = 0){
1217 $lesson_id = $this->get_post_id($lesson_id);
1218 $video = $this->get_video($lesson_id);
1219
1220 if ( ! $video){
1221 return false;
1222 }
1223
1224 $info = array(
1225 'playtime' => '00:00',
1226 );
1227
1228 $types = apply_filters('tutor_video_types', array("mp4"=>"video/mp4", "webm"=>"video/webm", "ogg"=>"video/ogg"));
1229
1230 $videoSource = $this->avalue_dot('source', $video);
1231 if ($videoSource === 'html5'){
1232 $sourceVideoID = $this->avalue_dot('source_video_id', $video);
1233 $video_info = get_post_meta($sourceVideoID, '_wp_attachment_metadata', true);
1234
1235 if ($video_info){
1236 $path = get_attached_file($sourceVideoID);
1237 $info['playtime'] = $video_info['length_formatted'];
1238 $info['path'] = $path;
1239 $info['url'] = wp_get_attachment_url($sourceVideoID);
1240 $info['ext'] = strtolower(pathinfo($path, PATHINFO_EXTENSION));
1241 $info['type'] = $types[$info['ext']];
1242 }
1243 }
1244
1245 if ($videoSource !== 'html5'){
1246 $video = maybe_unserialize(get_post_meta($lesson_id, '_video', true));
1247
1248 $runtimeHours = tutor_utils()->avalue_dot('runtime.hours', $video);
1249 $runtimeMinutes = tutor_utils()->avalue_dot('runtime.minutes', $video);
1250 $runtimeSeconds = tutor_utils()->avalue_dot('runtime.seconds', $video);
1251
1252 $runtimeHours = $runtimeHours ? $runtimeHours : '00';
1253 $runtimeMinutes = $runtimeMinutes ? $runtimeMinutes : '00';
1254 $runtimeSeconds = $runtimeSeconds ? $runtimeSeconds : '00';
1255
1256 $info['playtime'] = "$runtimeHours:$runtimeMinutes:$runtimeSeconds";
1257 }
1258
1259 $info = array_merge($info, $video);
1260
1261 return (object) $info;
1262 }
1263
1264 /**
1265 * @param int $post_id
1266 *
1267 * @return bool
1268 *
1269 * Ensure if attached video is self hosted or not
1270 *
1271 * @since v.1.0.0
1272 */
1273 public function is_html5_video($post_id = 0){
1274 $post_id = $this->get_post_id($post_id);
1275
1276 $video = $this->get_video($post_id);
1277 if ( ! $video){
1278 return false;
1279 }
1280 $videoSource = $this->avalue_dot('source', $video);
1281 return $videoSource === 'html5';
1282 }
1283
1284 /**
1285 *
1286 * return lesson type icon
1287 *
1288 * @param int $lesson_id
1289 * @param bool $html
1290 * @param bool $echo
1291 *
1292 * @return string
1293 *
1294 * @since v.1.0.0
1295 */
1296
1297 public function get_lesson_type_icon($lesson_id = 0, $html = false, $echo = false){
1298 $post_id = $this->get_post_id($lesson_id);
1299 $video = tutor_utils()->get_video_info($post_id);
1300
1301 $play_time = false;
1302 if ($video){
1303 $play_time = $video->playtime;
1304 }
1305
1306 $tutor_lesson_type_icon = $play_time ? 'youtube' : 'document';
1307
1308 if ($html){
1309 $tutor_lesson_type_icon = "<i class='tutor-icon-$tutor_lesson_type_icon'></i> ";
1310 }
1311
1312 if ($tutor_lesson_type_icon){
1313 echo $tutor_lesson_type_icon;
1314 }
1315
1316 return $tutor_lesson_type_icon;
1317 }
1318
1319 /**
1320 * @param int $lesson_id
1321 * @param int $user_id
1322 *
1323 * @return bool|mixed
1324 *
1325 * @since v.1.0.0
1326 */
1327
1328 public function is_completed_lesson($lesson_id = 0, $user_id = 0){
1329 $lesson_id = $this->get_post_id($lesson_id);
1330 $user_id = $this->get_user_id($user_id);
1331
1332 $is_completed = get_user_meta($user_id, '_tutor_completed_lesson_id_'.$lesson_id, true);
1333
1334 if ($is_completed){
1335 return $is_completed;
1336 }
1337
1338 return false;
1339 }
1340
1341 /**
1342 * @param int $course_id
1343 * @param int $user_id
1344 *
1345 * @return array|bool|null|object|void
1346 *
1347 * Determine if a course completed
1348 *
1349 * @since v.1.0.0
1350 */
1351
1352 public function is_completed_course($course_id = 0, $user_id = 0){
1353 if ( ! is_user_logged_in()){
1354 return false;
1355 }
1356
1357 global $wpdb;
1358 $course_id = $this->get_post_id($course_id);
1359 $user_id = $this->get_user_id($user_id);
1360
1361 $is_completed = $wpdb->get_row("SELECT comment_ID,
1362 comment_post_ID as course_id,
1363 comment_author as completed_user_id,
1364 comment_date as completion_date,
1365 comment_content as completed_hash
1366 from {$wpdb->comments}
1367 WHERE comment_agent = 'TutorLMSPlugin'
1368 AND comment_type = 'course_completed'
1369 AND comment_post_ID = {$course_id}
1370 AND user_id = {$user_id} ;");
1371
1372 if ($is_completed){
1373 return $is_completed;
1374 }
1375
1376 return false;
1377 }
1378
1379 /**
1380 * @param array $input
1381 *
1382 * @return array
1383 *
1384 * Sanitize input array
1385 *
1386 * @since v.1.0.0
1387 */
1388 public function sanitize_array($input = array()){
1389 $array = array();
1390
1391 if (is_array($input) && count($input)){
1392 foreach ($input as $key => $value){
1393 if (is_array($value)){
1394 $array[$key] = $this->sanitize_array($value);
1395 }else{
1396 $key = sanitize_text_field($key);
1397 $value = sanitize_text_field($value);
1398 $array[$key] = $value;
1399 }
1400 }
1401 }
1402
1403 return $array;
1404 }
1405
1406 /**
1407 * @param int $post_id
1408 *
1409 * @return array|bool
1410 *
1411 * Determine if has any video in single
1412 *
1413 * @since v.1.0.0
1414 */
1415
1416 public function has_video_in_single($post_id = 0){
1417 if (is_single()) {
1418 $post_id = $this->get_post_id($post_id);
1419
1420 $video = $this->get_video( $post_id );
1421 if ( $video ) {
1422 return $video;
1423 }
1424 }
1425 return false;
1426
1427 }
1428
1429 /**
1430 * @param int $start
1431 * @param int $limit
1432 * @param string $search_term
1433 * @param int $course_id
1434 *
1435 * @return array|null|object
1436 *
1437 *
1438 * Get the enrolled students for all courses.
1439 *
1440 * Pass course id in 4th parameter to get students course wise.
1441 *
1442 * @since v.1.0.0
1443 */
1444 public function get_students($start = 0, $limit = 10, $search_term = ''){
1445 $meta_key = '_is_tutor_student';
1446
1447 global $wpdb;
1448
1449 if ($search_term){
1450 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
1451 }
1452
1453 $students = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
1454 INNER JOIN {$wpdb->usermeta}
1455 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
1456 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
1457 ORDER BY {$wpdb->usermeta}.meta_value DESC
1458 LIMIT {$start}, {$limit} ");
1459
1460 return $students;
1461 }
1462
1463 /**
1464 * @return int
1465 *
1466 * @since v.1.0.0
1467 *
1468 * get the total students
1469 * pass course id to get course wise total students
1470 *
1471 * @since v.1.0.0
1472 */
1473 public function get_total_students($search_term = ''){
1474 $meta_key = '_is_tutor_student';
1475
1476 global $wpdb;
1477
1478 if ($search_term){
1479 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
1480 }
1481
1482 $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 ");
1483
1484 return (int) $count;
1485 }
1486
1487 /**
1488 * @param int $user_id
1489 *
1490 * @return array
1491 *
1492 * Get complete courses ids by user
1493 *
1494 * @since v.1.0.0
1495 */
1496 public function get_completed_courses_ids_by_user($user_id = 0){
1497 global $wpdb;
1498
1499 $user_id = $this->get_user_id($user_id);
1500
1501 $course_ids = (array) $wpdb->get_col("SELECT comment_post_ID as course_id
1502 from {$wpdb->comments}
1503 WHERE comment_agent = 'TutorLMSPlugin'
1504 AND comment_type = 'course_completed'
1505 AND user_id = {$user_id} ;");
1506
1507 return $course_ids;
1508 }
1509
1510 /**
1511 * @param int $user_id
1512 *
1513 * @return bool|\WP_Query
1514 *
1515 * Return courses by user_id
1516 *
1517 * @since v.1.0.0
1518 */
1519 public function get_courses_by_user($user_id = 0){
1520 $user_id = $this->get_user_id($user_id);
1521 $course_ids = $this->get_completed_courses_ids_by_user($user_id);
1522
1523 if (count($course_ids)){
1524 $course_post_type = tutor()->course_post_type;
1525 $course_args = array(
1526 'post_type' => $course_post_type,
1527 'post_status' => 'publish',
1528 'post__in' => $course_ids,
1529 );
1530
1531 return new \WP_Query($course_args);
1532 }
1533
1534 return false;
1535 }
1536
1537 /**
1538 * @param int $user_id
1539 *
1540 * @return bool|\WP_Query
1541 *
1542 * Get the active course by user
1543 *
1544 * @since v.1.0.0
1545 */
1546
1547 public function get_active_courses_by_user($user_id = 0){
1548 $user_id = $this->get_user_id($user_id);
1549
1550 $course_ids = $this->get_completed_courses_ids_by_user($user_id);
1551 $enrolled_course_ids = $this->get_enrolled_courses_ids_by_user($user_id);
1552 $active_courses = array_diff($enrolled_course_ids, $course_ids);
1553
1554 if (count($active_courses)){
1555 $course_post_type = tutor()->course_post_type;
1556 $course_args = array(
1557 'post_type' => $course_post_type,
1558 'post_status' => 'publish',
1559 'post__in' => $active_courses,
1560 );
1561
1562 return new \WP_Query($course_args);
1563 }
1564
1565 return false;
1566 }
1567
1568 /**
1569 * @param int $user_id
1570 *
1571 * @return array
1572 *
1573 * Get enrolled course ids by a user
1574 *
1575 * @since v.1.0.0
1576 */
1577
1578 public function get_enrolled_courses_ids_by_user($user_id = 0){
1579 global $wpdb;
1580 $user_id = $this->get_user_id($user_id);
1581 $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'; ");
1582
1583 return $course_ids;
1584 }
1585
1586 /**
1587 * @param int $course_id
1588 *
1589 * @return int
1590 *
1591 * Get the total enrolled users at course
1592 */
1593 public function count_enrolled_users_by_course($course_id = 0){
1594 global $wpdb;
1595 $course_id = $this->get_post_id($course_id);
1596
1597 $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'; ");
1598
1599 return (int) $course_ids;
1600 }
1601
1602 /**
1603 * @param int $user_id
1604 *
1605 * @return bool|\WP_Query
1606 *
1607 * Get the enrolled courses by user
1608 */
1609 public function get_enrolled_courses_by_user($user_id = 0){
1610 global $wpdb;
1611
1612 $user_id = $this->get_user_id($user_id);
1613 $course_ids = $this->get_enrolled_courses_ids_by_user($user_id);
1614
1615 if (count($course_ids)){
1616 $course_post_type = tutor()->course_post_type;
1617 $course_args = array(
1618 'post_type' => $course_post_type,
1619 'post_status' => 'publish',
1620 'post__in' => $course_ids,
1621 );
1622 return new \WP_Query($course_args);
1623 }
1624 return false;
1625 }
1626
1627
1628 /**
1629 * @param int $post_id
1630 *
1631 * @return string
1632 *
1633 * Get the video streaming URL by post/lesson/course ID
1634 */
1635 public function get_video_stream_url($post_id = 0){
1636 $post_id = $this->get_post_id($post_id);
1637 $post = get_post($post_id);
1638
1639 if ($post->post_type === tutor()->lesson_post_type ){
1640 $video_url = trailingslashit(home_url()).'video-url/'.$post->post_name;
1641 }else{
1642 $video_info = tutor_utils()->get_video_info($post_id);
1643 $video_url = $video_info->url;
1644 }
1645
1646 return $video_url;
1647 }
1648
1649 /**
1650 * @param int $lesson_id
1651 * @param int $user_id
1652 *
1653 * @return array|bool|mixed
1654 *
1655 * Get student lesson reading current info
1656 *
1657 * @since v.1.0.0
1658 */
1659 public function get_lesson_reading_info_full($lesson_id = 0, $user_id = 0){
1660 $lesson_id = $this->get_post_id($lesson_id);
1661 $user_id = $this->get_user_id($user_id);
1662
1663 $lesson_info = (array) maybe_unserialize(get_user_meta($user_id, '_lesson_reading_info', true));
1664 return $this->avalue_dot($lesson_id, $lesson_info);
1665 }
1666
1667 /**
1668 * @param int $post_id
1669 *
1670 * @return bool|false|int
1671 *
1672 * Get current post id or given post id
1673 *
1674 * @since v.1.0.0
1675 */
1676 public function get_post_id($post_id = 0){
1677 if ( ! $post_id){
1678 $post_id = get_the_ID();
1679 if ( ! $post_id){
1680 return false;
1681 }
1682 }
1683
1684 return $post_id;
1685 }
1686
1687 /**
1688 * @param int $user_id
1689 *
1690 * @return bool|int
1691 *
1692 * Get current user or given user ID
1693 *
1694 * @since v.1.0.0
1695 */
1696 public function get_user_id($user_id = 0){
1697 if ( ! $user_id){
1698 $user_id = get_current_user_id();
1699 if ( ! $user_id){
1700 return false;
1701 }
1702 }
1703
1704 return $user_id;
1705 }
1706
1707 /**
1708 * @param int $lesson_id
1709 * @param int $user_id
1710 * @param string $key
1711 *
1712 * @return array|bool|mixed
1713 *
1714 * Get lesson reading info by key
1715 *
1716 * @since v.1.0.0
1717 */
1718
1719 public function get_lesson_reading_info($lesson_id = 0, $user_id = 0, $key = ''){
1720 $lesson_id = $this->get_post_id($lesson_id);
1721 $user_id = $this->get_user_id($user_id);
1722
1723 $lesson_info = $this->get_lesson_reading_info_full($lesson_id, $user_id);
1724
1725 return $this->avalue_dot($key, $lesson_info);
1726 }
1727
1728 /**
1729 * @param int $lesson_id
1730 * @param int $user_id
1731 * @param array $data
1732 *
1733 * @return bool
1734 *
1735 * Update student lesson reading info
1736 *
1737 * @since v.1.0.0
1738 */
1739 public function update_lesson_reading_info($lesson_id = 0, $user_id = 0, $key = '', $value = ''){
1740 $lesson_id = $this->get_post_id($lesson_id);
1741 $user_id = $this->get_user_id($user_id);
1742
1743 if ($key && $value){
1744 $lesson_info = (array) maybe_unserialize(get_user_meta($user_id, '_lesson_reading_info', true));
1745 $lesson_info[$lesson_id][$key] = $value;
1746 update_user_meta($user_id, '_lesson_reading_info', $lesson_info);
1747 }
1748 }
1749
1750 /**
1751 * @param string $url
1752 *
1753 * @return bool
1754 *
1755 * Get the Youtube Video ID from URL
1756 *
1757 * @since v.1.0.0
1758 */
1759 public function get_youtube_video_id($url = ''){
1760 if (!$url){
1761 return false;
1762 }
1763 preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
1764
1765 if (isset($match[1])) {
1766 $youtube_id = $match[1];
1767 return $youtube_id;
1768 }
1769
1770 return false;
1771 }
1772
1773 /**
1774 * @param string $url
1775 *
1776 * @return bool
1777 *
1778 * Get the vimeo video id from URL
1779 *
1780 * @since v.1.0.0
1781 */
1782 public function get_vimeo_video_id($url = ''){
1783 if (preg_match('%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(?:[?]?.*)$%im', $url, $match)) {
1784 if (isset($match[3])){
1785 return $match[3];
1786 }
1787 }
1788 return false;
1789 }
1790
1791 /**
1792 * @param int $post_id
1793 *
1794 * Mark lesson complete
1795 *
1796 * @since v.1.0.0
1797 */
1798 public function mark_lesson_complete($post_id = 0, $user_id = 0){
1799 $post_id = $this->get_post_id($post_id);
1800 $user_id = $this->get_user_id($user_id);
1801
1802 do_action('tutor_mark_lesson_complete_before', $post_id, $user_id);
1803 update_user_meta($user_id, '_tutor_completed_lesson_id_'.$post_id, time());
1804 do_action('tutor_mark_lesson_complete_after', $post_id, $user_id);
1805
1806 }
1807
1808 /**
1809 * Saving enroll information to posts table
1810 * post_author = enrolled_student_id (wp_users id)
1811 * post_parent = enrolled course id
1812 *
1813 * @type: call when need
1814 * @return bool;
1815 *
1816 * @since v.1.0.0
1817 */
1818 public function do_enroll($course_id = 0, $order_id = 0){
1819 if ( ! $course_id){
1820 return false;
1821 }
1822
1823 do_action('tutor_before_enroll', $course_id);
1824 $user_id = get_current_user_id();
1825 $title = __('Course Enrolled', 'tutor')." &ndash; ".date_i18n(get_option('date_format')) .' @ '.date_i18n(get_option('time_format') ) ;
1826
1827 $enrolment_status = 'completed';
1828
1829 if ($this->is_course_purchasable($course_id)) {
1830 /**
1831 * We need to verify this enrollment, we will change the status later after payment confirmation
1832 */
1833 $enrolment_status = 'pending';
1834 }
1835
1836 $enroll_data = apply_filters('tutor_enroll_data',
1837 array(
1838 'post_type' => 'tutor_enrolled',
1839 'post_title' => $title,
1840 'post_status' => $enrolment_status,
1841 'post_author' => $user_id,
1842 'post_parent' => $course_id,
1843 )
1844 );
1845
1846 // Insert the post into the database
1847 $isEnrolled = wp_insert_post( $enroll_data );
1848 if ($isEnrolled) {
1849 do_action('tutor_after_enroll', $course_id, $isEnrolled);
1850
1851 //Mark Current User as Students with user meta data
1852 update_user_meta( $user_id, '_is_tutor_student', time() );
1853
1854 if ($order_id) {
1855 //Mark order for course and user
1856 $product_id = $this->get_course_product_id($course_id);
1857 update_post_meta( $isEnrolled, '_tutor_enrolled_by_order_id', $order_id );
1858 update_post_meta( $isEnrolled, '_tutor_enrolled_by_product_id', $product_id );
1859 update_post_meta( $order_id, '_is_tutor_order_for_course', time() );
1860 update_post_meta( $order_id, '_tutor_order_for_course_id_'.$course_id, $isEnrolled );
1861 }
1862 return true;
1863 }
1864
1865 return false;
1866 }
1867
1868 /**
1869 * @param $order_id
1870 *
1871 * Complete course enrollment and do some task
1872 *
1873 * @since v.1.0.0
1874 */
1875 public function complete_course_enroll($order_id){
1876 if ( ! tutor_utils()->is_tutor_order($order_id)){
1877 return;
1878 }
1879
1880 global $wpdb;
1881
1882 $enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id($order_id);
1883 if ($enrolled_ids_with_course){
1884 $enrolled_ids = wp_list_pluck($enrolled_ids_with_course, 'enrolled_id');
1885
1886 if (is_array($enrolled_ids) && count($enrolled_ids)){
1887 foreach ($enrolled_ids as $enrolled_id){
1888 $wpdb->update( $wpdb->posts, array( 'post_status' => 'completed' ), array( 'ID' => $enrolled_id ) );
1889 }
1890 }
1891 }
1892 }
1893
1894 /**
1895 * @param $order_id
1896 *
1897 * @return array|bool
1898 *
1899 * @since v.1.0.0
1900 */
1901 public function get_course_enrolled_ids_by_order_id($order_id){
1902 global $wpdb;
1903 //Getting all of courses ids within this order
1904
1905 $courses_ids = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE post_id = {$order_id} AND meta_key LIKE '_tutor_order_for_course_id_%' ");
1906
1907 if (is_array($courses_ids) && count($courses_ids)){
1908 $course_enrolled_by_order = array();
1909 foreach ($courses_ids as $courses_id){
1910 $course_id = str_replace('_tutor_order_for_course_id_', '',$courses_id->meta_key);
1911 //array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id))
1912 $course_enrolled_by_order[] = array('course_id' => $course_id, 'enrolled_id' => $courses_id->meta_value, 'order_id' => $courses_id->post_id );
1913 }
1914 return $course_enrolled_by_order;
1915 }
1916 return false;
1917 }
1918
1919 /**
1920 * Get wc product in efficient query
1921 *
1922 * @since v.1.0.0
1923 */
1924
1925 /**
1926 * @return array|null|object
1927 *
1928 * WooCommerce specific utils
1929 */
1930 public function get_wc_products_db(){
1931 global $wpdb;
1932 $query = $wpdb->get_results("SELECT ID, post_title from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'product' ");
1933
1934 return $query;
1935 }
1936
1937 /**
1938 * @return array|null|object
1939 *
1940 * Get EDD Products
1941 */
1942 public function get_edd_products(){
1943 global $wpdb;
1944 $query = $wpdb->get_results("SELECT ID, post_title from {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'download' ");
1945
1946 return $query;
1947 }
1948
1949 /**
1950 * @param int $course_id
1951 *
1952 * @return int
1953 *
1954 * Get course productID
1955 *
1956 * @since v.1.0.0
1957 */
1958 public function get_course_product_id($course_id = 0){
1959 $course_id = $this->get_post_id($course_id);
1960 $product_id = (int) get_post_meta($course_id, '_tutor_course_product_id', true);
1961
1962 return $product_id;
1963 }
1964
1965 /**
1966 * @param int $product_id
1967 *
1968 * @return array|null|object|void
1969 *
1970 * Get Product belongs with course
1971 *
1972 * @since v.1.0.0
1973 */
1974
1975 public function product_belongs_with_course($product_id = 0){
1976 global $wpdb;
1977
1978 $query = $wpdb->get_row("select * from {$wpdb->postmeta} WHERE meta_key='_tutor_course_product_id' AND meta_value = {$product_id} limit 1 ");
1979 return $query;
1980 }
1981
1982 /**
1983 * #End WooCommerce specific utils
1984 *
1985 * @since v.1.0.0
1986 */
1987
1988 public function get_enrolled_statuses(){
1989 return apply_filters(
1990 'tutor_get_enrolled_statuses',
1991 array (
1992 'pending',
1993 'processing',
1994 'on-hold',
1995 'completed',
1996 'cancelled',
1997 'refunded',
1998 'failed',
1999 )
2000 );
2001 }
2002
2003 /**
2004 * @param $order_id
2005 *
2006 * @return mixed
2007 *
2008 * determine is this a tutor order
2009 *
2010 * @since v.1.0.0
2011 */
2012 public function is_tutor_order($order_id){
2013 return get_post_meta($order_id, '_is_tutor_order_for_course', true);
2014 }
2015
2016 /**
2017 * @return mixed
2018 *
2019 * @deprecated
2020 */
2021 public function tutor_student_dashboard_pages(){
2022 _deprecated_function(__METHOD__, '1.1.2', 'tutor_dashboard_pages');
2023 return $this->tutor_dashboard_pages();
2024 }
2025
2026 /**
2027 * @return mixed
2028 *
2029 * Tutor Dashboard Pages, supporting for the URL rewriting
2030 *
2031 * @since v.1.0.0
2032 */
2033
2034 public function tutor_dashboard_pages(){
2035 $nav_items = apply_filters('tutor_dashboard/nav_items', array(
2036 'index' => __('Dashboard', 'tutor'),
2037 'my-profile' => __('My Profile', 'tutor'),
2038 'create-course' => array('title' => __('Create Course', 'tutor'), 'show_ui' => false, 'auth_cap' => tutor()->instructor_role),
2039 'enrolled-courses' => __('Enrolled Courses', 'tutor'),
2040 'wishlist' => __('Wishlist', 'tutor'),
2041 'reviews' => __('Reviews', 'tutor'),
2042
2043 'my-courses' => array('title' => __('My Courses', 'tutor'), 'auth_cap' => tutor()->instructor_role),
2044 'quiz-attempts' => array('title' => __('Quiz Attempts', 'tutor'), 'auth_cap' => tutor()->instructor_role),
2045 'earning' => array('title' => __('Earning', 'tutor'), 'auth_cap' => tutor()->instructor_role),
2046 'withdraw' => array('title' => __('Withdraw', 'tutor'), 'auth_cap' => tutor()->instructor_role),
2047
2048 'purchase_history' => __('Purchase History', 'tutor'),
2049 ));
2050
2051 $new_navs = array(
2052 'settings' => __('Settings', 'tutor'),
2053 'logout' => __('Logout', 'tutor'),
2054 );
2055
2056 $all_nav_items = array_merge($nav_items, $new_navs);
2057
2058 return apply_filters('tutor_dashboard/nav_items_all', $all_nav_items);
2059 }
2060
2061 /**
2062 * @return mixed
2063 *
2064 * Tutor Dashboard UI nav, only for using in the nav, it's handling user permission based
2065 * Dashboard nav items
2066 *
2067 * @since v.1.3.4
2068 */
2069 public function tutor_dashboard_nav_ui_items(){
2070 $nav_items = $this->tutor_dashboard_pages();
2071
2072 foreach ($nav_items as $key => $nav_item){
2073 if (is_array($nav_item)){
2074
2075 if ( isset($nav_item['show_ui']) && ! tutor_utils()->array_get('show_ui', $nav_item)){
2076 unset($nav_items[$key]);
2077 }
2078 if ( isset($nav_item['auth_cap'] ) && ! current_user_can($nav_item['auth_cap']) ){
2079 unset($nav_items[$key]);
2080 }
2081 }
2082 }
2083
2084 return apply_filters('tutor_dashboard/nav_ui_items', $nav_items);
2085 }
2086
2087 /**
2088 * @param string $page_key
2089 * @param int $page_id
2090 *
2091 * @return string
2092 *
2093 * Get tutor dashboard page single URL
2094 *
2095 * @since v.1.0.0
2096 */
2097 public function get_tutor_dashboard_page_permalink($page_key = '', $page_id = 0){
2098 if ($page_key === 'index'){
2099 $page_key = '';
2100 }
2101 $page_id = $this->get_post_id($page_id);
2102 return trailingslashit(get_permalink($page_id)).$page_key;
2103 }
2104
2105 /**
2106 * @param string $input
2107 *
2108 * @return array|bool|mixed|string
2109 *
2110 * Get old input
2111 *
2112 * @since v.1.0.0
2113 */
2114 public function input_old($input = ''){
2115 $value = $this->avalue_dot($input, $_REQUEST);
2116 if ($value){
2117 return $value;
2118 }
2119 return '';
2120 }
2121
2122 /**
2123 * @param int $user_id
2124 *
2125 * @return mixed
2126 *
2127 * Determine if is instructor or not
2128 *
2129 * @since v.1.0.0
2130 */
2131 public function is_instructor($user_id = 0){
2132 $user_id = $this->get_user_id($user_id);
2133 return get_user_meta($user_id, '_is_tutor_instructor', true);
2134 }
2135
2136 /**
2137 * @param int $user_id
2138 * @param bool $status_name
2139 *
2140 * @return bool|mixed
2141 *
2142 * Instructor status
2143 *
2144 * @since v.1.0.0
2145 */
2146 public function instructor_status($user_id = 0, $status_name = true){
2147 $user_id = $this->get_user_id($user_id);
2148
2149 $instructor_status = apply_filters('tutor_instructor_statuses', array(
2150 'pending' => __('Pending', 'tutor'),
2151 'approved' => __('Approved', 'tutor'),
2152 'blocked' => __('Blocked', 'tutor'),
2153 ));
2154
2155 $status = get_user_meta($user_id, '_tutor_instructor_status', true);
2156
2157 if (isset($instructor_status[$status])){
2158 if ( ! $status_name){
2159 return $status;
2160 }
2161 return $instructor_status[$status];
2162 }
2163 return false;
2164 }
2165
2166 /**
2167 * @param string $search_term
2168 *
2169 * @return int
2170 *
2171 * Get total number of instructors
2172 *
2173 * @since v.1.0.0
2174 */
2175
2176 public function get_total_instructors($search_term = ''){
2177 $meta_key = '_is_tutor_instructor';
2178
2179 global $wpdb;
2180
2181 if ($search_term){
2182 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2183 }
2184
2185 $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 ");
2186
2187 return (int) $count;
2188 }
2189
2190 /**
2191 * @param int $start
2192 * @param int $limit
2193 * @param string $search_term
2194 *
2195 * @return array|null|object
2196 *
2197 * Get all instructors
2198 *
2199 * @since v.1.0.0
2200 */
2201 public function get_instructors($start = 0, $limit = 10, $search_term = ''){
2202 $meta_key = '_is_tutor_instructor';
2203 global $wpdb;
2204
2205 if ($search_term){
2206 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2207 }
2208
2209 $instructors = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
2210 INNER JOIN {$wpdb->usermeta}
2211 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
2212 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
2213 ORDER BY {$wpdb->usermeta}.meta_value DESC
2214 LIMIT {$start}, {$limit} ");
2215
2216 return $instructors;
2217 }
2218
2219 /**
2220 * @param int $course_id
2221 *
2222 * @return array|bool|null|object
2223 *
2224 * Get all instructors by course
2225 *
2226 * @since v.1.0.0
2227 */
2228 public function get_instructors_by_course($course_id = 0){
2229 global $wpdb;
2230 $course_id = $this->get_post_id($course_id);
2231
2232 $instructors = $wpdb->get_results("select ID, display_name,
2233 get_course.meta_value as taught_course_id,
2234 tutor_job_title.meta_value as tutor_profile_job_title,
2235 tutor_bio.meta_value as tutor_profile_bio,
2236 tutor_photo.meta_value as tutor_profile_photo
2237 from {$wpdb->users}
2238 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}
2239 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2240 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2241 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2242 ");
2243
2244 if (is_array($instructors) && count($instructors)){
2245 return $instructors;
2246 }
2247
2248 return false;
2249 }
2250
2251 /**
2252 * @param $instructor_id
2253 *
2254 * Get total Students by instructor
2255 * 1 enrollment = 1 student, so total enrolled for a equivalent total students (Tricks)
2256 *
2257 * @return int
2258 *
2259 * @since v.1.0.0
2260 */
2261
2262 public function get_total_students_by_instructor($instructor_id){
2263 global $wpdb;
2264
2265 $course_post_type = tutor()->course_post_type;
2266 $count = $wpdb->get_var("SELECT COUNT(courses.ID) from {$wpdb->posts} courses
2267
2268 INNER JOIN {$wpdb->posts} enrolled ON courses.ID = enrolled.post_parent AND enrolled.post_type = 'tutor_enrolled'
2269 WHERE courses.post_status = 'publish'
2270 AND courses.post_type = '{$course_post_type}'
2271 AND courses.post_author = {$instructor_id} ; ");
2272 return (int) $count;
2273 }
2274
2275 /**
2276 * @param float $input
2277 *
2278 * @return float|string
2279 *
2280 * Get rating format from value
2281 *
2282 * @since v.1.0.0
2283 */
2284 public function get_rating_value($input = 0.00){
2285
2286 if ( $input > 0){
2287 $input = number_format($input, 2);
2288 $int_value = (int) $input;
2289 $fraction = $input - $int_value;
2290
2291 if ($fraction == 0){
2292 $fraction = 0.00;
2293 }elseif($fraction > 0.5){
2294 $fraction = 1;
2295 }else{
2296 $fraction = 0.5;
2297 }
2298
2299 return number_format( ($int_value + $fraction), 2);
2300 }
2301 return 0.00;
2302 }
2303
2304 /**
2305 * @param float $current_rating
2306 * @param bool $echo
2307 *
2308 * @return string
2309 *
2310 * Generate star rating based in given rating value
2311 *
2312 * @since v.1.0.0
2313 */
2314 public function star_rating_generator($current_rating = 0.00, $echo = true){
2315 $output = '<div class="tutor-star-rating-group">';
2316
2317 for ($i = 1; $i <=5 ; $i++){
2318 $intRating = (int) $current_rating;
2319
2320 if ($intRating >= $i){
2321 $output.= '<i class="tutor-icon-star-full" data-rating-value="'.$i.'"></i>';
2322 } else{
2323 if ( ($current_rating - $i) == -0.5){
2324 $output.= '<i class="tutor-icon-star-half" data-rating-value="'.$i.'"></i>';
2325 }else{
2326 $output.= '<i class="tutor-icon-star-line" data-rating-value="'.$i.'"></i>';
2327 }
2328 }
2329 }
2330
2331 $output .= "<div class='tutor-rating-gen-input'><input type='hidden' name='tutor_rating_gen_input' value='{$current_rating}' /> </div>";
2332
2333 $output .= "</div>";
2334
2335 if ($echo){
2336 echo $output;
2337 }
2338 return $output;
2339 }
2340
2341 /**
2342 * @param null $name
2343 *
2344 * @return string
2345 *
2346 * Generate text to avatar
2347 *
2348 * @since v.1.0.0
2349 */
2350 public function get_tutor_avatar($user_id = null, $size = 'thumbnail'){
2351 global $wpdb;
2352
2353 if ( ! $user_id){
2354 return '';
2355 }
2356
2357 $user = $this->get_tutor_user($user_id);
2358 if ($user->tutor_profile_photo){
2359 return '<img src="'.wp_get_attachment_image_url($user->tutor_profile_photo, $size).'" class="tutor-image-avatar" alt="" /> ';
2360 }
2361
2362 $name = $user->display_name;
2363 $arr = explode(' ', trim($name));
2364
2365 if (count($arr) > 1){
2366 $first_char = substr($arr[0], 0, 1) ;
2367 $second_char = substr($arr[1], 0, 1) ;
2368 }else{
2369 $first_char = substr($arr[0], 0, 1) ;
2370 $second_char = substr($arr[0], 1, 1) ;
2371 }
2372
2373 $initial_avatar = strtoupper($first_char.$second_char);
2374
2375 $bg_color = '#'.substr(md5($initial_avatar), 0, 6);
2376 $initial_avatar = "<span class='tutor-text-avatar' style='background-color: {$bg_color}; color: #fff8e5'>{$initial_avatar}</span>";
2377
2378 return $initial_avatar;
2379 }
2380
2381 /**
2382 * @param $user_id
2383 *
2384 * @return array|null|object|void
2385 *
2386 * Get tutor user
2387 *
2388 * @since v.1.0.0
2389 */
2390
2391 public function get_tutor_user($user_id){
2392 global $wpdb;
2393
2394 $user = $wpdb->get_row("select ID, display_name,
2395 tutor_job_title.meta_value as tutor_profile_job_title,
2396 tutor_bio.meta_value as tutor_profile_bio,
2397 tutor_photo.meta_value as tutor_profile_photo
2398
2399 from {$wpdb->users}
2400 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2401 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2402 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2403
2404 WHERE ID = {$user_id} ");
2405 return $user;
2406 }
2407
2408 /**
2409 * @param int $course_id
2410 * @param int $offset
2411 * @param int $limit
2412 *
2413 * @return array|null|object
2414 *
2415 * get course reviews
2416 *
2417 * @since v.1.0.0
2418 */
2419 public function get_course_reviews($course_id = 0, $offset = 0, $limit = 150){
2420 $course_id = $this->get_post_id($course_id);
2421 global $wpdb;
2422
2423 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2424 {$wpdb->comments}.comment_post_ID,
2425 {$wpdb->comments}.comment_author,
2426 {$wpdb->comments}.comment_author_email,
2427 {$wpdb->comments}.comment_date,
2428 {$wpdb->comments}.comment_content,
2429 {$wpdb->comments}.user_id,
2430 {$wpdb->commentmeta}.meta_value as rating,
2431 {$wpdb->users}.display_name
2432
2433 from {$wpdb->comments}
2434 INNER JOIN {$wpdb->commentmeta}
2435 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2436 INNER JOIN {$wpdb->users}
2437 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2438 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2439 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2440 );
2441
2442 return $reviews;
2443 }
2444
2445 /**
2446 * @param int $course_id
2447 *
2448 * @return object
2449 *
2450 * Get course rating
2451 *
2452 * @since v.1.0.0
2453 */
2454 public function get_course_rating($course_id = 0){
2455 $course_id = $this->get_post_id($course_id);
2456
2457 $ratings = array(
2458 'rating_count' => 0,
2459 'rating_sum' => 0,
2460 'rating_avg' => 0.00,
2461 'count_by_value' => array(5 => 0, 4 => 0, 3 => 0, 2 => 0, 1 => 0)
2462 );
2463
2464 global $wpdb;
2465
2466 $rating = $wpdb->get_row("select COUNT(meta_value) as rating_count, SUM(meta_value) as rating_sum
2467 from {$wpdb->comments}
2468 INNER JOIN {$wpdb->commentmeta}
2469 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2470 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2471 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2472 AND meta_key = 'tutor_rating' ;"
2473 );
2474
2475 if ($rating->rating_count){
2476 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2477
2478 /**
2479 * Get individual Rating by integer
2480 */
2481 $five_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2482 from {$wpdb->comments}
2483 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2484 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2485 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2486 AND meta_key = 'tutor_rating' AND meta_value = 5 ;"
2487 );
2488 $four_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2489 from {$wpdb->comments}
2490 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2491 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2492 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2493 AND meta_key = 'tutor_rating' AND meta_value = 4 ;"
2494 );
2495 $three_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2496 from {$wpdb->comments}
2497 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2498 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2499 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2500 AND meta_key = 'tutor_rating' AND meta_value = 3 ;"
2501 );
2502 $two_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2503 from {$wpdb->comments}
2504 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2505 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2506 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2507 AND meta_key = 'tutor_rating' AND meta_value = 2 ;"
2508 );
2509 $one_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2510 from {$wpdb->comments}
2511 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2512 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2513 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2514 AND meta_key = 'tutor_rating' AND meta_value = 1 ;"
2515 );
2516
2517 $ratings = array(
2518 'rating_count' => $rating->rating_count,
2519 'rating_sum' => $rating->rating_sum,
2520 'rating_avg' => $avg_rating,
2521 'count_by_value' => array(5 => $five_stars_count, 4 => $four_stars_count, 3 => $three_stars_count, 2 => $two_stars_count, 1 => $one_stars_count)
2522 );
2523
2524 }
2525
2526 return (object) $ratings;
2527 }
2528
2529 /**
2530 * @param int $user_id
2531 * @param int $offset
2532 * @param int $limit
2533 *
2534 * @return array|null|object
2535 *
2536 * Get reviews by a user
2537 *
2538 * @since v.1.0.0
2539 */
2540 public function get_reviews_by_user($user_id = 0, $offset = 0, $limit = 150){
2541 $user_id = $this->get_user_id($user_id);
2542 global $wpdb;
2543
2544 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2545 {$wpdb->comments}.comment_post_ID,
2546 {$wpdb->comments}.comment_author,
2547 {$wpdb->comments}.comment_author_email,
2548 {$wpdb->comments}.comment_date,
2549 {$wpdb->comments}.comment_content,
2550 {$wpdb->comments}.user_id,
2551 {$wpdb->commentmeta}.meta_value as rating,
2552 {$wpdb->users}.display_name
2553
2554 from {$wpdb->comments}
2555 INNER JOIN {$wpdb->commentmeta}
2556 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2557 INNER JOIN {$wpdb->users}
2558 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2559 WHERE {$wpdb->comments}.user_id = {$user_id}
2560 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2561 );
2562
2563 return $reviews;
2564 }
2565
2566 /**
2567 * @param $instructor_id
2568 *
2569 * @return object
2570 *
2571 * Get instructors rating
2572 *
2573 * @since v.1.0.0
2574 */
2575 public function get_instructor_ratings($instructor_id){
2576 global $wpdb;
2577
2578 $ratings = array(
2579 'rating_count' => 0,
2580 'rating_sum' => 0,
2581 'rating_avg' => 0.00,
2582 );
2583
2584 $rating = $wpdb->get_row("SELECT COUNT(rating.meta_value) as rating_count, SUM(rating.meta_value) as rating_sum
2585 FROM {$wpdb->usermeta} courses
2586 INNER JOIN {$wpdb->comments} reviews ON courses.meta_value = reviews.comment_post_ID AND reviews.comment_type = 'tutor_course_rating'
2587 INNER JOIN {$wpdb->commentmeta} rating ON reviews.comment_ID = rating.comment_id AND rating.meta_key = 'tutor_rating'
2588 WHERE courses.user_id = {$instructor_id} AND courses.meta_key = '_tutor_instructor_course_id'");
2589
2590 if ($rating->rating_count){
2591 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2592
2593 $ratings = array(
2594 'rating_count' => $rating->rating_count,
2595 'rating_sum' => $rating->rating_sum,
2596 'rating_avg' => $avg_rating,
2597 );
2598 }
2599
2600 return (object) $ratings;
2601 }
2602
2603 /**
2604 * @param int $course_id
2605 * @param int $user_id
2606 *
2607 * @return object
2608 *
2609 * Get course rating by user
2610 *
2611 * @since v.1.0.0
2612 */
2613 public function get_course_rating_by_user($course_id = 0, $user_id = 0){
2614 $course_id = $this->get_post_id($course_id);
2615 $user_id = $this->get_user_id($user_id);
2616
2617 $ratings = array(
2618 'rating' => 0,
2619 'review' => '',
2620 );
2621
2622 global $wpdb;
2623
2624 $rating = $wpdb->get_row("select meta_value as rating, comment_content as review from {$wpdb->comments}
2625 INNER JOIN {$wpdb->commentmeta}
2626 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2627 WHERE {$wpdb->comments}.comment_post_ID = {$course_id} AND user_id = {$user_id}
2628 AND meta_key = 'tutor_rating' ;"
2629 );
2630
2631 if ($rating){
2632 $rating_format = number_format($rating->rating, 2);
2633
2634 $ratings = array(
2635 'rating' => $rating_format,
2636 'review' => $rating->review,
2637 );
2638 }
2639 return (object) $ratings;
2640 }
2641
2642 /**
2643 * @param int $user_id
2644 *
2645 * @return null|string
2646 *
2647 * @since v.1.0.0
2648 */
2649 public function count_reviews_wrote_by_user($user_id = 0){
2650 global $wpdb;
2651 $user_id = $this->get_user_id($user_id);
2652
2653 $count_reviews = $wpdb->get_var("SELECT COUNT(comment_ID) from {$wpdb->comments} WHERE user_id = {$user_id} AND comment_type = 'tutor_course_rating' ");
2654 return $count_reviews;
2655 }
2656
2657 /**
2658 * @param $size
2659 *
2660 * @return bool|int|string
2661 *
2662 * This function transforms the php.ini notation for numbers (like '2M') to an integer.
2663 *
2664 * @since v.1.0.0
2665 */
2666
2667 function let_to_num( $size ) {
2668 $l = substr( $size, -1 );
2669 $ret = substr( $size, 0, -1 );
2670 $byte = 1024;
2671
2672 switch ( strtoupper( $l ) ) {
2673 case 'P':
2674 $ret *= 1024;
2675 // No break.
2676 case 'T':
2677 $ret *= 1024;
2678 // No break.
2679 case 'G':
2680 $ret *= 1024;
2681 // No break.
2682 case 'M':
2683 $ret *= 1024;
2684 // No break.
2685 case 'K':
2686 $ret *= 1024;
2687 // No break.
2688 }
2689 return $ret;
2690 }
2691
2692 /**
2693 * @return array
2694 *
2695 * Get Database version
2696 *
2697 * @since v.1.0.0
2698 */
2699 function get_db_version() {
2700 global $wpdb;
2701
2702 if ( empty( $wpdb->is_mysql ) ) {
2703 return array(
2704 'string' => '',
2705 'number' => '',
2706 );
2707 }
2708
2709 if ( $wpdb->use_mysqli ) {
2710 $server_info = mysqli_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2711 } else {
2712 $server_info = mysql_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2713 }
2714
2715 return array(
2716 'string' => $server_info,
2717 'number' => preg_replace( '/([^\d.]+).*/', '', $server_info ),
2718 );
2719 }
2720
2721 public function help_tip($tip = ''){
2722 return '<span class="tutor-help-tip" data-tip="' . $tip . '"></span>';
2723 }
2724
2725 /**
2726 * @param int $course_id
2727 * @param int $user_id
2728 * @param int $offset
2729 * @param int $limit
2730 *
2731 * @return array|null|object
2732 *
2733 * Get top question
2734 *
2735 * @since v.1.0.0
2736 */
2737 public function get_top_question($course_id = 0, $user_id = 0, $offset = 0, $limit = 20){
2738 $course_id = $this->get_post_id($course_id);
2739 $user_id = $this->get_user_id($user_id);
2740
2741 global $wpdb;
2742
2743 $questions = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2744 {$wpdb->comments}.comment_post_ID,
2745 {$wpdb->comments}.comment_author,
2746 {$wpdb->comments}.comment_date,
2747 {$wpdb->comments}.comment_content,
2748 {$wpdb->comments}.user_id,
2749 {$wpdb->commentmeta}.meta_value as question_title,
2750 {$wpdb->users}.display_name
2751
2752 from {$wpdb->comments}
2753 INNER JOIN {$wpdb->commentmeta}
2754 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2755 INNER JOIN {$wpdb->users}
2756 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2757 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2758 AND {$wpdb->comments}.user_id = {$user_id}
2759 AND {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2760 AND meta_key = 'tutor_question_title' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2761 );
2762
2763 return $questions;
2764 }
2765
2766 /**
2767 * @param string $search_term
2768 *
2769 * @return int
2770 *
2771 * Get total number of Q&A questions
2772 *
2773 * @since v.1.0.0
2774 */
2775 public function get_total_qa_question($search_term = ''){
2776 global $wpdb;
2777
2778 if ($search_term){
2779 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2780 }
2781
2782 $user_id = get_current_user_id();
2783 $course_type = tutor()->course_post_type;
2784
2785 $in_question_id_query = '';
2786 /**
2787 * Get only assinged courses questions if current user is a
2788 */
2789 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2790 $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' " );
2791 $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} " );
2792 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2793
2794 if ( $this->count( $my_course_ids ) ) {
2795 $implode_ids = implode( ',', $my_course_ids );
2796 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2797 }
2798 }
2799
2800 $count = $wpdb->get_var("SELECT COUNT({$wpdb->comments}.comment_ID) FROM {$wpdb->comments}
2801 INNER JOIN {$wpdb->commentmeta}
2802 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2803 WHERE comment_type = 'tutor_q_and_a' AND comment_parent = 0 {$in_question_id_query} {$search_term} ");
2804
2805 return (int) $count;
2806 }
2807
2808 /**
2809 * @param int $start
2810 * @param int $limit
2811 * @param string $search_term
2812 *
2813 * @return array|null|object
2814 *
2815 *
2816 * Get question and answer query
2817 *
2818 * @since v.1.0.0
2819 */
2820 public function get_qa_questions($start = 0, $limit = 10, $search_term = '') {
2821 global $wpdb;
2822
2823 if ($search_term){
2824 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2825 }
2826
2827 $user_id = get_current_user_id();
2828 $course_type = tutor()->course_post_type;
2829
2830 $in_question_id_query = '';
2831 /**
2832 * Get only assinged courses questions if current user is a
2833 */
2834 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2835 $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' " );
2836 $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} " );
2837 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2838
2839 if ( $this->count( $my_course_ids ) ) {
2840 $implode_ids = implode( ',', $my_course_ids );
2841 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2842 }
2843 }
2844
2845 $query = $wpdb->get_results("SELECT
2846 {$wpdb->comments}.comment_ID,
2847 {$wpdb->comments}.comment_post_ID,
2848 {$wpdb->comments}.comment_author,
2849 {$wpdb->comments}.comment_date,
2850 {$wpdb->comments}.comment_content,
2851 {$wpdb->comments}.user_id,
2852 {$wpdb->commentmeta}.meta_value as question_title,
2853 {$wpdb->users}.display_name,
2854 {$wpdb->posts}.post_title,
2855
2856 (SELECT COUNT(answers_t.comment_ID) FROM {$wpdb->comments} answers_t
2857 WHERE answers_t.comment_parent = {$wpdb->comments}.comment_ID ) as answer_count
2858
2859 FROM {$wpdb->comments}
2860
2861 INNER JOIN {$wpdb->commentmeta}
2862 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2863
2864 INNER JOIN {$wpdb->posts}
2865 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2866
2867 INNER JOIN {$wpdb->users}
2868 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2869
2870 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_parent = 0 {$search_term}
2871 {$in_question_id_query}
2872 ORDER BY {$wpdb->comments}.comment_ID DESC
2873 LIMIT {$start},{$limit}; ");
2874
2875 return $query;
2876 }
2877
2878 /**
2879 * @param $question_id
2880 *
2881 * @return array|null|object|void
2882 *
2883 * Get question for Q&A
2884 *
2885 * @since v.1.0.0
2886 */
2887 public function get_qa_question($question_id){
2888 global $wpdb;
2889 $query = $wpdb->get_row("SELECT
2890 {$wpdb->comments}.comment_ID,
2891 {$wpdb->comments}.comment_post_ID,
2892 {$wpdb->comments}.comment_author,
2893 {$wpdb->comments}.comment_date,
2894 {$wpdb->comments}.comment_content,
2895 {$wpdb->comments}.user_id,
2896 {$wpdb->commentmeta}.meta_value as question_title,
2897 {$wpdb->users}.display_name,
2898 {$wpdb->posts}.post_title
2899
2900 FROM {$wpdb->comments}
2901 INNER JOIN {$wpdb->commentmeta}
2902 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2903
2904 INNER JOIN {$wpdb->posts}
2905 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2906
2907 INNER JOIN {$wpdb->users}
2908 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2909 WHERE comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_ID = {$question_id}");
2910
2911 return $query;
2912 }
2913
2914 /**
2915 * @param $question_id
2916 *
2917 * @return array|null|object
2918 *
2919 * Get question and asnwer by question
2920 */
2921 public function get_qa_answer_by_question($question_id){
2922 global $wpdb;
2923 $query = $wpdb->get_results("SELECT
2924 {$wpdb->comments}.comment_ID,
2925 {$wpdb->comments}.comment_post_ID,
2926 {$wpdb->comments}.comment_author,
2927 {$wpdb->comments}.comment_date,
2928 {$wpdb->comments}.comment_content,
2929 {$wpdb->comments}.comment_parent,
2930 {$wpdb->comments}.user_id,
2931 {$wpdb->users}.display_name
2932
2933 FROM {$wpdb->comments}
2934
2935 INNER JOIN {$wpdb->users}
2936 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2937 WHERE comment_type = 'tutor_q_and_a'
2938 AND {$wpdb->comments}.comment_parent = {$question_id} ORDER BY {$wpdb->comments}.comment_ID ASC ");
2939
2940 return $query;
2941 }
2942
2943 public function unanswered_question_count(){
2944 global $wpdb;
2945
2946 $count = $wpdb->get_var("select COUNT({$wpdb->comments}.comment_ID)
2947 from {$wpdb->comments}
2948 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2949 AND {$wpdb->comments}.comment_approved = 'waiting_for_answer'
2950 AND {$wpdb->comments}.comment_parent = 0;");
2951 return (int) $count;
2952 }
2953
2954 /**
2955 * @param int $course_id
2956 *
2957 * @return array|null|object
2958 *
2959 * Return all of announcements for a course
2960 *
2961 * @since v.1.0.0
2962 */
2963 public function get_announcements($course_id = 0){
2964 $course_id = $this->get_post_id($course_id);
2965 global $wpdb;
2966
2967 $query = $wpdb->get_results("select {$wpdb->posts}.ID, post_author, post_date, post_content, post_title, display_name
2968 from {$wpdb->posts}
2969 INNER JOIN {$wpdb->users} ON post_author = {$wpdb->users}.ID
2970 WHERE post_type = 'tutor_announcements'
2971 AND post_parent = {$course_id} ORDER BY {$wpdb->posts}.ID DESC;");
2972 return $query;
2973 }
2974
2975 /**
2976 * @param string $content
2977 *
2978 * @return mixed
2979 *
2980 * Announcement content
2981 *
2982 * @since v.1.0.0
2983 */
2984
2985 public function announcement_content($content = ''){
2986 $search = array('{user_display_name}');
2987
2988 $user_display_name = 'User';
2989 if (is_user_logged_in()){
2990 $user = wp_get_current_user();
2991 $user_display_name = $user->display_name;
2992 }
2993 $replace = array($user_display_name);
2994
2995 return str_replace($search, $replace, $content);
2996 }
2997
2998 /**
2999 * @param int $post_id
3000 * @param string $option_key
3001 * @param bool $default
3002 *
3003 * @return array|bool|mixed
3004 *
3005 * Get the quiz option from meta
3006 */
3007 public function get_quiz_option($post_id = 0, $option_key = '', $default = false){
3008 $post_id = $this->get_post_id($post_id);
3009 $get_option_meta = maybe_unserialize(get_post_meta($post_id, 'tutor_quiz_option', true));
3010
3011 if ( ! $option_key && ! empty($get_option_meta)) {
3012 return $get_option_meta;
3013 }
3014
3015 $value = $this->avalue_dot( $option_key, $get_option_meta );
3016 if ( $value ) {
3017 return $value;
3018 }
3019 return $default;
3020 }
3021
3022
3023 /**
3024 * @param int $quiz_id
3025 *
3026 * @return array|bool|null|object
3027 *
3028 * Get the questions by quiz ID
3029 */
3030 public function get_questions_by_quiz($quiz_id = 0){
3031 $quiz_id = $this->get_post_id($quiz_id);
3032 global $wpdb;
3033
3034 //$questions = $wpdb->get_results("SELECT ID, post_content, post_title, post_parent from {$wpdb->posts} WHERE post_type = 'tutor_question'
3035 // AND post_parent = {$quiz_id} ORDER BY menu_order ASC ");
3036
3037 $questions = $wpdb->get_results("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY question_order ASC ");
3038
3039 if (is_array($questions) && count($questions)){
3040 return $questions;
3041 }
3042 return false;
3043 }
3044
3045 /**
3046 * @param int $question_id
3047 *
3048 * @return array|bool|object|void|null
3049 *
3050 * Get Quiz question by question id
3051 */
3052 public function get_quiz_question_by_id($question_id = 0){
3053 global $wpdb;
3054
3055 if ($question_id){
3056 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} LIMIT 0,1 ;");
3057 return $question;
3058 }
3059
3060 return false;
3061 }
3062
3063 /**
3064 * @param null $type
3065 *
3066 * @return array|mixed
3067 *
3068 * Get all question types
3069 *
3070 * @since v.1.0.0
3071 */
3072
3073 public function get_question_types($type = null){
3074 $types = array(
3075 'true_false' => array('name' => __('True/False', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-yes-no"></i>', 'is_pro' => false),
3076 'single_choice' => array('name' => __('Single Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-mark"></i>', 'is_pro' => false),
3077 'multiple_choice' => array('name' => __('Multiple Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-multiple-choice"></i>', 'is_pro' => false),
3078 'open_ended' => array('name' => __('Open Ended/Essay', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-open-ended"></i>', 'is_pro' => false),
3079 '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),
3080 'short_answer' => array('name' => __('Short Answer', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-short-ans"></i>', 'is_pro' => true),
3081 'matching' => array('name' => __('Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-matching"></i>', 'is_pro' => true),
3082 'image_matching' => array('name' => __('Image Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-matching"></i>', 'is_pro' => true),
3083 'image_answering' => array('name' => __('Image Answering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-ans"></i>', 'is_pro' => true),
3084 'ordering' => array('name' => __('Ordering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-ordering"></i>', 'is_pro' => true),
3085 );
3086
3087 if (isset($types[$type])){
3088 return $types[$type];
3089 }
3090 return $types;
3091 }
3092
3093 public function get_quiz_answer_options_by_question($question_id){
3094 global $wpdb;
3095
3096 $answer_options = $wpdb->get_results("select
3097 {$wpdb->comments}.comment_ID,
3098 {$wpdb->comments}.comment_post_ID,
3099 {$wpdb->comments}.comment_content
3100
3101 FROM {$wpdb->comments}
3102 WHERE {$wpdb->comments}.comment_post_ID = {$question_id}
3103 AND {$wpdb->comments}.comment_type = 'quiz_answer_option'
3104 ORDER BY {$wpdb->comments}.comment_karma ASC ;");
3105
3106 if (is_array($answer_options) && count($answer_options)){
3107 return $answer_options;
3108 }
3109 return false;
3110 }
3111
3112 /**
3113 * @param $quiz_id
3114 *
3115 * @return int
3116 *
3117 * Get the next question order ID
3118 *
3119 * @since v.1.0.0
3120 */
3121
3122 public function quiz_next_question_order_id($quiz_id){
3123 global $wpdb;
3124
3125 //$last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$quiz_id} AND post_type =
3126 // 'tutor_question';");
3127
3128 $last_order = (int) $wpdb->get_var("SELECT MAX(question_order) FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ;");
3129 return $last_order + 1;
3130 }
3131
3132 /**
3133 * @param $quiz_id
3134 *
3135 * @return int
3136 *
3137 * new design quiz question
3138 * @since v.1.0.0
3139 */
3140 public function quiz_next_question_id(){
3141 global $wpdb;
3142
3143 $last_order = (int) $wpdb->get_var("SELECT MAX(question_id) FROM {$wpdb->prefix}tutor_quiz_questions;");
3144 return $last_order + 1;
3145 }
3146
3147 public function get_quiz_id_by_question($question_id){
3148 global $wpdb;
3149
3150 $quiz_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$question_id} AND post_type = 'tutor_question' ;");
3151 return $quiz_id;
3152 }
3153
3154 /**
3155 * @param array $config
3156 *
3157 * @return array|bool|null|object
3158 *
3159 * It was used in previous quiz algorithm
3160 *
3161 * @deprecated
3162 *
3163 * @since v.1.0.0
3164 */
3165 public function get_unattached_quiz($config = array()){
3166 global $wpdb;
3167
3168 $default_attr = array(
3169 'search_term' => '',
3170 'start' => '0',
3171 'limit' => '10',
3172 'order' => 'DESC',
3173 'order_by' => 'ID',
3174 );
3175 $attr = array_merge($default_attr, $config);
3176 extract($attr);
3177
3178 $search_query = '';
3179 if (! empty($search_term)){
3180 $search_query = "AND post_title LIKE '%{$search_term}%'";
3181 }
3182
3183 $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} ");
3184
3185 if (is_array($questions) && count($questions)){
3186 return $questions;
3187 }
3188 return false;
3189 }
3190
3191 /**
3192 * @param int $post_id
3193 *
3194 * @return array|bool|null|object
3195 *
3196 * @since v.1.0.0
3197 */
3198 public function get_attached_quiz($post_id = 0){
3199 global $wpdb;
3200
3201 $post_id = $this->get_post_id($post_id);
3202
3203 $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}");
3204
3205 if (is_array($questions) && count($questions)){
3206 return $questions;
3207 }
3208 return false;
3209 }
3210
3211 /**
3212 * @param $quiz_id
3213 *
3214 * @return array|bool|null|object|void
3215 *
3216 * Get course by quiz
3217 *
3218 * @since v.1.0.0
3219 */
3220
3221 public function get_course_by_quiz($quiz_id){
3222 global $wpdb;
3223
3224 $quiz_id = $this->get_post_id($quiz_id);
3225 $post = get_post($quiz_id);
3226
3227 if ($post) {
3228 $course_post_type = tutor()->course_post_type;
3229 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$post->post_parent} " );
3230
3231 if ($course) {
3232 //Checking if this topic
3233 if ( $course->post_type !== $course_post_type ) {
3234 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
3235 }
3236 //Checking if this lesson
3237 if ( $course->post_type !== $course_post_type ) {
3238 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
3239 }
3240
3241 return $course;
3242 }
3243 }
3244
3245 return false;
3246 }
3247
3248 /**
3249 * @param $quiz_id
3250 *
3251 * @return int
3252 *
3253 * @since v.1.0.0
3254 */
3255 public function total_questions_for_student_by_quiz($quiz_id){
3256 $quiz_id = $this->get_post_id($quiz_id);
3257 global $wpdb;
3258
3259 $total_question = (int) $wpdb->get_var("select count(ID) from {$wpdb->posts} where post_parent = {$quiz_id} AND post_type = 'tutor_question' ");
3260
3261 return $total_question;
3262 }
3263
3264 /**
3265 * @param int $quiz_id
3266 *
3267 * @return array|null|object|void
3268 *
3269 * Determine if there is any started quiz exists
3270 *
3271 * @since v.1.0.0
3272 */
3273
3274 public function is_started_quiz($quiz_id = 0){
3275 global $wpdb;
3276
3277 $quiz_id = $this->get_post_id($quiz_id);
3278 $user_id = get_current_user_id();
3279
3280 $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' ");
3281
3282 return $is_started;
3283 }
3284
3285 /**
3286 * @param $quiz_id
3287 *
3288 * Method for get the total amount of question for a quiz
3289 * Student will answer this amount of question, one quiz have many question
3290 * but student will answer a specific amount of questions
3291 *
3292 * @return int
3293 *
3294 * @since v.1.0.0
3295 */
3296
3297 public function max_questions_for_take_quiz($quiz_id){
3298 $quiz_id = $this->get_post_id($quiz_id);
3299 global $wpdb;
3300
3301 $max_questions = (int) $wpdb->get_var("select count(question_id) from {$wpdb->prefix}tutor_quiz_questions where quiz_id = {$quiz_id} ");
3302 $max_mentioned = (int) $this->get_quiz_option($quiz_id, 'max_questions_for_answer', 10);
3303
3304 if ($max_mentioned < $max_questions ){
3305 return $max_mentioned;
3306 }
3307
3308 return $max_questions;
3309 }
3310
3311 /**
3312 * @param int $attempt_id
3313 *
3314 * @return array|bool|null|object|void
3315 *
3316 * Get single quiz attempt
3317 *
3318 * @since v.1.0.0
3319 */
3320 public function get_attempt($attempt_id = 0){
3321 global $wpdb;
3322 if ( ! $attempt_id){
3323 return false;
3324 }
3325 $attempt = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE attempt_id = {$attempt_id} ");
3326 return $attempt;
3327 }
3328
3329 /**
3330 * @param $attempt_info
3331 *
3332 * @return mixed
3333 *
3334 * Get unserialize attempt info
3335 *
3336 * @since v.1.0.0
3337 */
3338
3339 public function quiz_attempt_info($attempt_info){
3340 return maybe_unserialize($attempt_info);
3341 }
3342
3343 /**
3344 * @param $quiz_attempt_id
3345 * @param array $attempt_info
3346 *
3347 * @return bool|int
3348 *
3349 * Update attempt for various action
3350 *
3351 * @since v.1.0.0
3352 */
3353 public function quiz_update_attempt_info($quiz_attempt_id, $attempt_info = array()){
3354 $answers = tutor_utils()->avalue_dot('answers', $attempt_info);
3355 $total_marks = array_sum(wp_list_pluck($answers, 'question_mark'));
3356 $earned_marks = tutor_utils()->avalue_dot('marks_earned', $attempt_info);
3357 $earned_mark_percent = $earned_marks > 0 ? ( number_format(($earned_marks * 100) / $total_marks)) : 0;
3358 update_comment_meta($quiz_attempt_id, 'earned_mark_percent', $earned_mark_percent);
3359
3360 return update_comment_meta($quiz_attempt_id,'quiz_attempt_info', $attempt_info);
3361 }
3362
3363 /**
3364 * @param int $quiz_id
3365 *
3366 * @return array|null|object
3367 *
3368 * Get random question by quiz id
3369 *
3370 * @since v.1.0.0
3371 */
3372
3373 public function get_random_question_by_quiz($quiz_id = 0){
3374 global $wpdb;
3375
3376 $quiz_id = $this->get_post_id($quiz_id);
3377 $is_attempt = $this->is_started_quiz($quiz_id);
3378
3379 $tempSql = " AND question_type = 'matching' ";
3380 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} {$tempSql} ORDER BY RAND() LIMIT 0,1 ");
3381
3382 return $questions;
3383 }
3384
3385 /**
3386 * @param int $quiz_id
3387 *
3388 * @return array|null|object
3389 *
3390 * Get random questions by quiz
3391 */
3392 public function get_random_questions_by_quiz($quiz_id = 0){
3393 global $wpdb;
3394
3395 $quiz_id = $this->get_post_id($quiz_id);
3396 $attempt = $this->is_started_quiz($quiz_id);
3397 if ( ! $attempt){
3398 return false;
3399 }
3400
3401 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY RAND() LIMIT {$attempt->total_questions} ");
3402
3403 return $questions;
3404 }
3405
3406 /**
3407 * @param $question_id
3408 * @param bool $rand
3409 *
3410 * @return array|bool|null|object
3411 *
3412 * Get answers list by quiz question
3413 *
3414 * @since v.1.0.0
3415 */
3416 public function get_answers_by_quiz_question($question_id, $rand = false){
3417 global $wpdb;
3418
3419
3420 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} ;");
3421 if ( ! $question){
3422 return false;
3423 }
3424
3425 $order = " answer_order ASC ";
3426 if ($question->question_type === 'ordering'){
3427 $order = " RAND() ";
3428 }
3429
3430 if ($rand){
3431 $order = " RAND() ";
3432 }
3433
3434 $answers = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question_id} AND belongs_question_type =
3435 '{$question->question_type}' order by {$order} ");
3436 return $answers;
3437 }
3438
3439 /**
3440 * @param int $quiz_id
3441 * @param int $user_id
3442 *
3443 * @return array|bool|null|object
3444 *
3445 * Get all of the attempts by an user of a quiz
3446 *
3447 * @since v.1.0.0
3448 */
3449
3450 public function quiz_attempts($quiz_id = 0, $user_id = 0){
3451 global $wpdb;
3452
3453 $quiz_id = $this->get_post_id($quiz_id);
3454 $user_id = $this->get_user_id($user_id);
3455
3456 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE quiz_id = {$quiz_id} AND user_id = {$user_id} ");
3457
3458 if (is_array($attempts) && count($attempts)){
3459 return $attempts;
3460 }
3461
3462 return false;
3463 }
3464
3465
3466 public function get_all_quiz_attempts_by_user($user_id = 0){
3467 global $wpdb;
3468
3469 $user_id = $this->get_user_id($user_id);
3470
3471 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE user_id = {$user_id} ");
3472
3473 if (is_array($attempts) && count($attempts)){
3474 return $attempts;
3475 }
3476
3477 return false;
3478 }
3479
3480 /**
3481 * @param string $search_term
3482 *
3483 * @return int
3484 *
3485 * Total number of quiz attempts
3486 *
3487 * @since v.1.0.0
3488 */
3489
3490 public function get_total_quiz_attempts($search_term = ''){
3491 global $wpdb;
3492
3493 if ($search_term){
3494 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3495 }
3496
3497 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3498 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3499 INNER JOIN {$wpdb->posts} quiz
3500 ON quiz_attempts.quiz_id = quiz.ID
3501 INNER JOIN {$wpdb->users}
3502 ON quiz_attempts.user_id = {$wpdb->users}.ID
3503 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3504 return (int) $count;
3505 }
3506
3507 /**
3508 * @param int $start
3509 * @param int $limit
3510 * @param string $search_term
3511 *
3512 * @return array|null|object
3513 *
3514 *
3515 * Get the all quiz attempts
3516 *
3517 * @since v.1.0.0
3518 */
3519 public function get_quiz_attempts($start = 0, $limit = 10, $search_term = '') {
3520 global $wpdb;
3521
3522 if ($search_term){
3523 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3524 }
3525
3526 $query = $wpdb->get_results("SELECT *
3527 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3528 INNER JOIN {$wpdb->posts} quiz
3529 ON quiz_attempts.quiz_id = quiz.ID
3530 INNER JOIN {$wpdb->users}
3531 ON quiz_attempts.user_id = {$wpdb->users}.ID
3532 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3533 ORDER BY quiz_attempts.attempt_id DESC
3534 LIMIT {$start},{$limit}; ");
3535 return $query;
3536 }
3537
3538 public function get_quiz_attempts_by_course_ids($start = 0, $limit = 10, $course_ids = array(), $search_term = '') {
3539 global $wpdb;
3540
3541 if ($search_term){
3542 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3543 }
3544
3545 $course_ids_in = implode($course_ids, ',');
3546 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3547 $search_term = $sql.$search_term;
3548
3549 $query = $wpdb->get_results("SELECT *
3550 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3551 INNER JOIN {$wpdb->posts} quiz
3552 ON quiz_attempts.quiz_id = quiz.ID
3553 INNER JOIN {$wpdb->users}
3554 ON quiz_attempts.user_id = {$wpdb->users}.ID
3555 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3556 ORDER BY quiz_attempts.attempt_id DESC
3557 LIMIT {$start},{$limit}; ");
3558 return $query;
3559 }
3560
3561 public function get_total_quiz_attempts_by_course_ids($course_ids = array(), $search_term = ''){
3562 global $wpdb;
3563
3564 if ($search_term){
3565 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3566 }
3567
3568 $course_ids_in = implode($course_ids, ',');
3569 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3570 $search_term = $sql.$search_term;
3571
3572 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3573 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3574 INNER JOIN {$wpdb->posts} quiz
3575 ON quiz_attempts.quiz_id = quiz.ID
3576 INNER JOIN {$wpdb->users}
3577 ON quiz_attempts.user_id = {$wpdb->users}.ID
3578 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3579 return (int) $count;
3580 }
3581
3582 /**
3583 * @param $attempt_id
3584 *
3585 * @return array|null|object
3586 *
3587 * Get quiz answers by attempt id
3588 *
3589 * @since v.1.0.0
3590 */
3591 public function get_quiz_answers_by_attempt_id($attempt_id){
3592 global $wpdb;
3593
3594 $results = $wpdb->get_results("SELECT answers.*, question.question_title, question.question_type
3595 FROM {$wpdb->prefix}tutor_quiz_attempt_answers answers
3596 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answers.question_id = question.question_id
3597 WHERE answers.quiz_attempt_id = {$attempt_id} ");
3598
3599 return $results;
3600 }
3601
3602 /**
3603 * @param $answer_id
3604 *
3605 * @return array|null|object
3606 *
3607 * Get single answer by answer_id
3608 *
3609 * @since v.1.0.0
3610 */
3611 public function get_answer_by_id($answer_id){
3612 global $wpdb;
3613
3614 if (is_array($answer_id)){
3615 $in_ids = implode(",", $answer_id);
3616 $sql = "answer.answer_id IN({$in_ids})";
3617 }else{
3618 $sql = "answer.answer_id = {$answer_id}";
3619 }
3620
3621 $answer = $wpdb->get_results("SELECT answer.*, question.question_title, question.question_type
3622 FROM {$wpdb->prefix}tutor_quiz_question_answers answer
3623 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answer.belongs_question_id = question.question_id
3624 WHERE 1=1 AND {$sql} ");
3625
3626 return $answer;
3627 }
3628
3629 /**
3630 * @param $ids
3631 *
3632 * @return array|bool|null|object
3633 *
3634 * Get quiz answers by ids
3635 *
3636 * @since v.1.0.0
3637 */
3638
3639 public function get_quiz_answers_by_ids($ids){
3640 $ids = (array) $ids;
3641
3642 if (!count($ids)){
3643 return false;
3644 }
3645
3646 $in_ids = implode(",", $ids);
3647
3648 global $wpdb;
3649 $query = $wpdb->get_results("SELECT
3650 comment_ID,
3651 comment_content
3652 FROM {$wpdb->comments}
3653 WHERE comment_type = 'quiz_answer_option' AND comment_ID IN({$in_ids}) ");
3654
3655 if (is_array($query) && count($query)){
3656 return $query;
3657 }
3658
3659 return false;
3660 }
3661
3662 /**
3663 * @param null $level
3664 *
3665 * @return mixed
3666 *
3667 * Get the users / students / course levels
3668 *
3669 * @since v.1.0.0
3670 */
3671
3672 public function course_levels($level = null){
3673 $levels = apply_filters('tutor_course_level', array(
3674 'all_levels' => __('All Levels', 'tutor'),
3675 'beginner' => __('Beginner', 'tutor'),
3676 'intermediate' => __('Intermediate', 'tutor'),
3677 'expert' => __('Expert', 'tutor'),
3678 ));
3679
3680 if ($level){
3681 if (isset($levels[$level])){
3682 return $levels[$level];
3683 }else{
3684 return '';
3685 }
3686 }
3687
3688 return $levels;
3689 }
3690
3691 /**
3692 * @return mixed|void
3693 *
3694 * Get user permalink for dashboard
3695 *
3696 * @since v.1.0.0
3697 */
3698 public function user_profile_permalinks(){
3699 $permalinks = array(
3700 'courses_taken' => __('Courses Taken', 'tutor'),
3701 );
3702
3703 $show_enrolled_course = tutor_utils()->get_option('show_courses_completed_by_student');
3704 $enable_show_reviews_wrote = tutor_utils()->get_option('students_own_review_show_at_profile');
3705
3706 if ($show_enrolled_course){
3707 $permalinks['enrolled_course'] = __('Enrolled Course', 'tutor');
3708 }
3709 if ($enable_show_reviews_wrote){
3710 $permalinks['reviews_wrote'] = __('Reviews Written', 'tutor');
3711 }
3712
3713
3714 return apply_filters('tutor_public_profile/permalinks', $permalinks);
3715 }
3716
3717 /**
3718 * @return bool|false|string
3719 *
3720 * Student registration form
3721 *
3722 * @since v.1.0.0
3723 */
3724 public function student_register_url(){
3725 $student_register_page = (int) $this->get_option('student_register_page');
3726
3727 if ($student_register_page){
3728 return get_the_permalink($student_register_page);
3729 }
3730 return false;
3731 }
3732 /**
3733 * @return bool|false|string
3734 *
3735 * Instructor registration form
3736 *
3737 * @since v.1.2.13
3738 */
3739 public function instructor_register_url(){
3740 $instructor_register_page = (int) $this->get_option('instructor_register_page');
3741
3742 if ($instructor_register_page){
3743 return get_the_permalink($instructor_register_page);
3744 }
3745 return false;
3746 }
3747
3748 /**
3749 * @return false|string
3750 *
3751 * Get frontend dashboard URL
3752 */
3753 public function tutor_dashboard_url($sub_url = ''){
3754 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3755 $page_id = apply_filters('tutor_dashboard_page_id', $page_id);
3756 return trailingslashit(get_the_permalink($page_id)).$sub_url;
3757 }
3758
3759 /**
3760 * Get the tutor dashboard page ID
3761 *
3762 * @return int
3763 *
3764 */
3765 public function dashboard_page_id(){
3766 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3767 $page_id = apply_filters('tutor_dashboard_page_id', $page_id);
3768 return $page_id;
3769 }
3770
3771 /**
3772 * @param int $course_id
3773 * @param int $user_id
3774 *
3775 * @return bool
3776 *
3777 * is_wishlisted();
3778 *
3779 * @since v.1.0.0
3780 */
3781 public function is_wishlisted($course_id = 0, $user_id = 0){
3782 $course_id = $this->get_post_id($course_id);
3783 $user_id = $this->get_user_id($user_id);
3784 if ( ! $user_id){
3785 return false;
3786 }
3787
3788 global $wpdb;
3789 $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} ;");
3790
3791 return $if_added_to_list;
3792 }
3793
3794 /**
3795 * @param int $user_id
3796 *
3797 * @return array|null|object
3798 *
3799 * Get the wish lists by an user
3800 *
3801 * @since v.1.0.0
3802 */
3803 public function get_wishlist($user_id = 0){
3804 $user_id = $this->get_user_id($user_id);
3805 global $wpdb;
3806
3807 $query = "SELECT $wpdb->posts.*
3808 FROM $wpdb->posts
3809 LEFT JOIN $wpdb->usermeta ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
3810 WHERE $wpdb->usermeta.meta_key = '_tutor_course_wishlist'
3811 AND $wpdb->usermeta.user_id = {$user_id}
3812 ORDER BY $wpdb->usermeta.umeta_id DESC ";
3813 $pageposts = $wpdb->get_results($query, OBJECT);
3814 return $pageposts;
3815 }
3816
3817 /**
3818 * @param int $limit
3819 *
3820 * @return array|null|object
3821 *
3822 * Getting popular courses
3823 *
3824 * @since v.1.0.0
3825 */
3826 public function most_popular_courses($limit = 10){
3827 global $wpdb;
3828
3829 $courses = $wpdb->get_results("
3830 SELECT COUNT(enrolled.ID) as total_enrolled,
3831 enrolled.post_parent as course_id,
3832 course.*
3833 from {$wpdb->posts} enrolled
3834 INNER JOIN {$wpdb->posts} course ON enrolled.post_parent = course.ID
3835 WHERE enrolled.post_type = 'tutor_enrolled' AND enrolled.post_status = 'completed'
3836
3837 GROUP BY course_id
3838 ORDER BY total_enrolled DESC LIMIT 0,{$limit} ;");
3839
3840 return $courses;
3841 }
3842
3843 /**
3844 * @param int $limit
3845 *
3846 * @return array|bool|null|object
3847 *
3848 * Get most rated courses lists
3849 *
3850 * @since v.1.0.0
3851 */
3852 public function most_rated_courses($limit = 10){
3853 global $wpdb;
3854
3855 $result = $wpdb->get_results("
3856 SELECT COUNT(comment_ID) AS total_rating,
3857 comment_ID,
3858 comment_post_ID,
3859 course.*
3860 FROM {$wpdb->comments}
3861 INNER JOIN {$wpdb->posts} course ON comment_post_ID = course.ID
3862 WHERE {$wpdb->comments}.comment_type = 'tutor_course_rating' AND {$wpdb->comments}.comment_approved = 'approved'
3863 GROUP BY comment_post_ID ORDER BY total_rating DESC LIMIT 0,{$limit}
3864 ;");
3865
3866 if (is_array($result) && count($result)){
3867 return $result;
3868 }
3869 return false;
3870 }
3871
3872 /**
3873 * @param null $addon_field
3874 *
3875 * @return bool
3876 *
3877 * Get Addon config
3878 *
3879 * @since v.1.0.0
3880 */
3881 public function get_addon_config($addon_field = null){
3882 if ( ! $addon_field){
3883 return false;
3884 }
3885
3886 $addonsConfig = maybe_unserialize(get_option('tutor_addons_config'));
3887
3888 if (isset($addonsConfig[$addon_field])){
3889 return $addonsConfig[$addon_field];
3890 }
3891
3892 return false;
3893 }
3894
3895 /**
3896 * @return array|false|string
3897 *
3898 * Get the IP from visitor
3899 *
3900 * @since v.1.0.0
3901 */
3902 function get_ip() {
3903 $ipaddress = '';
3904 if (getenv('HTTP_CLIENT_IP'))
3905 $ipaddress = getenv('HTTP_CLIENT_IP');
3906 else if(getenv('HTTP_X_FORWARDED_FOR'))
3907 $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
3908 else if(getenv('HTTP_X_FORWARDED'))
3909 $ipaddress = getenv('HTTP_X_FORWARDED');
3910 else if(getenv('HTTP_FORWARDED_FOR'))
3911 $ipaddress = getenv('HTTP_FORWARDED_FOR');
3912 else if(getenv('HTTP_FORWARDED'))
3913 $ipaddress = getenv('HTTP_FORWARDED');
3914 else if(getenv('REMOTE_ADDR'))
3915 $ipaddress = getenv('REMOTE_ADDR');
3916 else
3917 $ipaddress = 'UNKNOWN';
3918 return $ipaddress;
3919 }
3920
3921 /**
3922 * @return mixed|void
3923 *
3924 * Get the social icons
3925 *
3926 * @since v.1.0.4
3927 */
3928
3929 public function tutor_social_share_icons(){
3930 $icons = array(
3931 'facebook' => array('share_class' => 's_facebook', 'icon_html' => '<i class="tutor-icon-facebook"></i>' ),
3932 'twitter' => array('share_class' => 's_twitter', 'icon_html' => '<i class="tutor-icon-twitter"></i>' ),
3933 'linkedin' => array('share_class' => 's_linkedin', 'icon_html' => '<i class="tutor-icon-linkdin"></i>' ),
3934 'tumblr' => array('share_class' => 's_tumblr', 'icon_html' => '<i class="tutor-icon-tumblr"></i>' ),
3935 );
3936
3937 return apply_filters('tutor_social_share_icons', $icons);
3938 }
3939
3940 /**
3941 * @param array $array
3942 *
3943 * @return bool
3944 *
3945 * count method with check is_array
3946 *
3947 * @since v.1.0.4
3948 */
3949 public function count($array = array()){
3950 if (is_array($array) && count($array)){
3951 return count($array);
3952 }
3953 return false;
3954 }
3955
3956 /**
3957 * @return array
3958 *
3959 * get all screen ids
3960 *
3961 * @since v.1.1.2
3962 */
3963 public function tutor_get_screen_ids(){
3964 $screen_ids = array(
3965 "edit-course",
3966 "course",
3967 "edit-course-category",
3968 "edit-course-tag",
3969 "tutor-lms_page_tutor-students",
3970 "tutor-lms_page_tutor-instructors",
3971 "tutor-lms_page_question_answer",
3972 "tutor-lms_page_tutor_quiz_attempts",
3973 "tutor-lms_page_tutor-addons",
3974 "tutor-lms_page_tutor-status",
3975 "tutor-lms_page_tutor_report",
3976 "tutor-lms_page_tutor_settings",
3977 "tutor-lms_page_tutor_emails",
3978 );
3979
3980 return apply_filters('tutor_get_screen_ids', $screen_ids);
3981 }
3982
3983
3984 /**
3985 * @return mixed
3986 *
3987 * get earning transaction completed status
3988 *
3989 * @since v.1.1.2
3990 */
3991 public function get_earnings_completed_statuses(){
3992 return apply_filters(
3993 'tutor_get_earnings_completed_statuses',
3994 array (
3995 'wc-completed',
3996 'completed',
3997 'complete',
3998 )
3999 );
4000 }
4001
4002 /**
4003 * @param int $user_id
4004 * @param array $date_filter
4005 *
4006 * @return array|null|object
4007 *
4008 * Get all time earning sum for an instructor with all commission
4009 *
4010 * @since v.1.1.2
4011 */
4012
4013 public function get_earning_sum($user_id = 0, $date_filter = array()){
4014 global $wpdb;
4015
4016 $user_id = $this->get_user_id($user_id);
4017 $date_query = '';
4018 if ($this->count($date_filter)){
4019 extract($date_filter);
4020
4021 if ( ! empty($dataFor)){
4022 if ($dataFor === 'yearly'){
4023 if (empty($year)){
4024 $year = date('Y');
4025 }
4026 $date_query = "AND YEAR(created_at) = {$year} ";
4027 }
4028 }else{
4029 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
4030 }
4031 }
4032
4033 $complete_status = tutor_utils()->get_earnings_completed_statuses();
4034 $complete_status = "'".implode("','", $complete_status)."'";
4035
4036 $earning_sum = $wpdb->get_row("SELECT SUM(course_price_total) as course_price_total,
4037 SUM(course_price_grand_total) as course_price_grand_total,
4038 SUM(instructor_amount) as instructor_amount,
4039 (SELECT SUM(amount) FROM {$wpdb->prefix}tutor_withdraws WHERE user_id = {$user_id} AND status != 'rejected' ) as
4040 withdraws_amount,
4041 SUM(admin_amount) as admin_amount,
4042 SUM(deduct_fees_amount) as deduct_fees_amount
4043 FROM {$wpdb->prefix}tutor_earnings
4044 WHERE user_id = {$user_id} AND order_status IN({$complete_status}) {$date_query} ");
4045
4046 //TODO: need to check
4047 // (SUM(instructor_amount) - (SELECT withdraws_amount) ) as balance,
4048
4049
4050 if ( $earning_sum->course_price_total){
4051 $earning_sum->balance = $earning_sum->instructor_amount - $earning_sum->withdraws_amount;
4052 }else{
4053
4054 $earning_sum = (object) array(
4055 'course_price_total' => 0,
4056 'course_price_grand_total' => 0,
4057 'instructor_amount' => 0,
4058 'withdraws_amount' => 0,
4059 'balance' => 0,
4060 'admin_amount' => 0,
4061 'deduct_fees_amount' => 0,
4062 );
4063 }
4064
4065 return $earning_sum;
4066 }
4067
4068 /**
4069 * @param int $user_id
4070 * @param array $date_filter
4071 *
4072 * @return array|null|object
4073 *
4074 * Get earning statements
4075 *
4076 * @since v.1.1.2
4077 */
4078 public function get_earning_statements($user_id = 0, $filter_data = array()){
4079 global $wpdb;
4080
4081 $user_sql = "";
4082 if ($user_id){
4083 $user_sql = " AND user_id='{$user_id}' ";
4084 }
4085
4086 $date_query = '';
4087 $query_by_status = '';
4088 $pagination_query = '';
4089
4090 /**
4091 * Query by Date Filter
4092 */
4093 if ($this->count($filter_data)){
4094 extract($filter_data);
4095
4096 if ( ! empty($dataFor)){
4097 if ($dataFor === 'yearly'){
4098 if (empty($year)){
4099 $year = date('Y');
4100 }
4101 $date_query = "AND YEAR(created_at) = {$year} ";
4102 }
4103 }else{
4104 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
4105 }
4106
4107 /**
4108 * Query by order status related to this earning transaction
4109 */
4110 if ( ! empty($statuses)) {
4111 if ( $this->count( $statuses ) ) {
4112 $status = "'" . implode( "','", $statuses ) . "'";
4113 $query_by_status = "AND order_status IN({$status})";
4114 } elseif ( $statuses === 'completed' ) {
4115
4116 $get_earnings_completed_statuses = $this->get_earnings_completed_statuses();
4117 if ( $this->count( $get_earnings_completed_statuses ) ) {
4118 $status = "'" . implode( "','", $get_earnings_completed_statuses ) . "'";
4119 $query_by_status = "AND order_status IN({$status})";
4120 }
4121 }
4122 }
4123
4124 if ( ! empty($per_page)){
4125 $offset = (int) ! empty($offset) ? $offset : 0;
4126
4127 $pagination_query = " LIMIT {$offset}, {$per_page} ";
4128
4129 }
4130
4131
4132 }
4133
4134 $query = $wpdb->get_results("SELECT earning_tbl.*, course.post_title as course_title
4135 FROM {$wpdb->prefix}tutor_earnings earning_tbl
4136 LEFT JOIN {$wpdb->posts} course ON earning_tbl.course_id = course.ID
4137 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC {$pagination_query} ");
4138
4139
4140 $query_count = (int) $wpdb->get_var("SELECT COUNT(earning_tbl.earning_id)
4141 FROM {$wpdb->prefix}tutor_earnings earning_tbl
4142 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC ");
4143
4144 return (object) array(
4145 'count' => $query_count,
4146 'results' => $query,
4147 );
4148 }
4149
4150 /**
4151 * @param int $price
4152 *
4153 * @return int|string
4154 *
4155 * Get the price format
4156 *
4157 * @since v.1.1.2
4158 */
4159
4160 public function tutor_price($price = 0){
4161 if (function_exists('wc_price')){
4162 return wc_price($price);
4163 }elseif (function_exists('edd_currency_filter')){
4164 return edd_currency_filter(edd_format_amount($price));
4165 }else{
4166 return number_format_i18n($price);
4167 }
4168 }
4169
4170 /**
4171 * @return mixed
4172 *
4173 * Get currency symbol from activated plugin, WC,EDD
4174 *
4175 * @since v.1.3.4
4176 */
4177
4178 public function currency_symbol(){
4179 $enable_tutor_edd = tutor_utils()->get_option('enable_tutor_edd');
4180 $monetize_by = $this->get_option('monetize_by');
4181
4182 $symbol = '&#36;';
4183 if ($enable_tutor_edd && function_exists('edd_currency_symbol')){
4184 $symbol = edd_currency_symbol();
4185 }
4186
4187 if ($monetize_by === 'wc' && function_exists('get_woocommerce_currency_symbol') ){
4188 $symbol = get_woocommerce_currency_symbol();
4189 }
4190
4191 return apply_filters('get_tutor_currency_symbol', $symbol);
4192 }
4193
4194 /**
4195 * @param int $user_id
4196 *
4197 * @return bool|mixed
4198 *
4199 * Get withdraw method for a specific
4200 */
4201 public function get_user_withdraw_method($user_id = 0){
4202 $user_id = $this->get_user_id($user_id);
4203
4204 $account = get_user_meta($user_id, '_tutor_withdraw_method_data', true);
4205 if ($account){
4206 return maybe_unserialize($account);
4207 }
4208
4209 return false;
4210 }
4211
4212 /**
4213 * @param int $user_id
4214 * @param array $filter
4215 *
4216 * get withdrawal history
4217 *
4218 * @return object
4219 */
4220 public function get_withdrawals_history($user_id = 0, $filter = array()){
4221 global $wpdb;
4222
4223 $filter = (array) $filter;
4224 extract($filter);
4225
4226 $query_by_status_sql = "";
4227 $query_by_user_sql = "";
4228 $query_by_pagination = "";
4229
4230 if ( ! empty($status)){
4231 $status = (array) $status;
4232 $status = "'".implode("','", $status)."'";
4233
4234 $query_by_status_sql = " AND status IN({$status}) ";
4235 }
4236
4237 if ( ! empty($per_page)){
4238 if ( empty($start))
4239 $start = 0;
4240
4241 $query_by_pagination = " LIMIT {$start}, {$per_page} ";
4242 }
4243
4244 if ($user_id){
4245 $query_by_user_sql = " AND user_id = {$user_id} ";
4246 }
4247
4248
4249 $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} ");
4250
4251 $results = $wpdb->get_results("SELECT withdraw_tbl.*,
4252 user_tbl.display_name as user_name,
4253 user_tbl.user_email
4254 FROM {$wpdb->prefix}tutor_withdraws withdraw_tbl
4255 INNER JOIN {$wpdb->users} user_tbl ON withdraw_tbl.user_id = user_tbl.ID
4256 WHERE 1=1
4257 {$query_by_user_sql}
4258 {$query_by_status_sql} ORDER BY
4259 created_at DESC {$query_by_pagination} ");
4260
4261 $withdraw_history = array(
4262 'count' => 0,
4263 'results' => null,
4264 );
4265
4266 if ($count){
4267 $withdraw_history['count'] = $count;
4268 }
4269
4270 if (tutor_utils()->count($results)){
4271 $withdraw_history['results'] = $results;
4272 }
4273 return (object) $withdraw_history;
4274
4275 }
4276
4277 /**
4278 * @param int $instructor_id
4279 *
4280 * Add Instructor role to any user by user iD
4281 */
4282 public function add_instructor_role($instructor_id = 0){
4283 if ( ! $instructor_id){
4284 return;
4285 }
4286 do_action('tutor_before_approved_instructor', $instructor_id);
4287
4288 update_user_meta($instructor_id, '_tutor_instructor_status', 'approved');
4289 update_user_meta($instructor_id, '_tutor_instructor_approved', time());
4290
4291 $instructor = new \WP_User($instructor_id);
4292 $instructor->add_role(tutor()->instructor_role);
4293
4294 do_action('tutor_after_approved_instructor', $instructor_id);
4295 }
4296
4297 /**
4298 * @param int $instructor_id
4299 *
4300 * Remove instructor role by instructor id
4301 */
4302 public function remove_instructor_role($instructor_id = 0){
4303 if ( ! $instructor_id){
4304 return;
4305 }
4306
4307 do_action('tutor_before_blocked_instructor', $instructor_id);
4308 update_user_meta($instructor_id, '_tutor_instructor_status', 'blocked');
4309
4310 $instructor = new \WP_User($instructor_id);
4311 $instructor->remove_role(tutor()->instructor_role);
4312 do_action('tutor_after_blocked_instructor', $instructor_id);
4313 }
4314
4315 /**
4316 * @param string $msg
4317 * @param string $name
4318 *
4319 * Set Flash Message to view in next action / route
4320 */
4321 public function set_flash_msg($msg = '', $name = 'success'){
4322 global $wp_filesystem;
4323 if ( ! $wp_filesystem ) {
4324 require_once( ABSPATH . 'wp-admin/includes/file.php' );
4325 }
4326
4327 $filename = "tutor_flash_msg_{$name}.txt";
4328 $upload_dir = wp_upload_dir();
4329 $dir = trailingslashit($upload_dir['basedir']) . 'tutor/';
4330
4331 WP_Filesystem( false, $upload_dir['basedir'], true );
4332
4333 if( ! $wp_filesystem->is_dir( $dir ) ) {
4334 $wp_filesystem->mkdir( $dir );
4335 }
4336 $wp_filesystem->put_contents( $dir . $filename, $msg );
4337 }
4338
4339 /**
4340 * @param null $name
4341 *
4342 * @return mixed|string|void
4343 *
4344 * Get Flash Message
4345 */
4346 public function get_flash_msg($name = null){
4347 if ( ! $name){
4348 return '';
4349 }
4350
4351 $upload_dir = wp_get_upload_dir();
4352 $upload_dir = trailingslashit($upload_dir['basedir']);
4353 $msg_name = 'tutor_flash_msg_'.$name;
4354
4355 $msg = '';
4356 $flash_msg_file_name = $upload_dir."tutor/{$msg_name}.txt";
4357 if (file_exists($flash_msg_file_name)){
4358 $msg = file_get_contents($flash_msg_file_name);
4359 unlink($flash_msg_file_name);
4360 }
4361
4362 return apply_filters('tutor_get_flash_msg', $msg, $name);
4363 }
4364
4365 /**
4366 * @param int $user_id
4367 *
4368 * @return array|null|object
4369 *
4370 * Get purchase history by customer id
4371 */
4372
4373 public function get_orders_by_user_id($user_id = 0){
4374 global $wpdb;
4375
4376 $user_id = $this->get_user_id();
4377
4378 $query = $wpdb->get_results("SELECT {$wpdb->posts}.* FROM {$wpdb->posts}
4379 INNER JOIN {$wpdb->postmeta} customer ON ID = customer.post_id AND customer.meta_key = '_customer_user'
4380 INNER JOIN {$wpdb->postmeta} tutor_order ON ID = tutor_order.post_id AND tutor_order.meta_key = '_is_tutor_order_for_course'
4381 where post_type = 'shop_order' AND customer.meta_value = {$user_id} ");
4382 return $query;
4383 }
4384
4385 /**
4386 * @param null $status
4387 *
4388 * @return string
4389 *
4390 * Get status contact formatted for order
4391 *
4392 * @since v.1.3.1
4393 */
4394 public function order_status_context($status = null){
4395 $status = str_replace('wc-', '', $status);
4396 $status_name = ucwords(str_replace('-', ' ', $status));
4397
4398 return "<span class='label-order-status label-status-{$status}'>$status_name</span>";
4399 }
4400
4401 public function get_course_id_by_assignment($assignment_id = 0){
4402 $assignment_id = $this->get_post_id($assignment_id);
4403 return get_post_meta($assignment_id, '_tutor_course_id_for_assignments', true);
4404 }
4405
4406 /**
4407 * @param int $assignment_id
4408 * @param string $option_key
4409 * @param bool $default
4410 *
4411 * @return array|bool|mixed
4412 *
4413 * Get assignment options
4414 *
4415 * @since v.1.3.3
4416 */
4417 public function get_assignment_option($assignment_id = 0, $option_key = '', $default = false){
4418 $assignment_id = $this->get_post_id($assignment_id);
4419 $get_option_meta = maybe_unserialize(get_post_meta($assignment_id, 'assignment_option', true));
4420
4421 if ( ! $option_key && ! empty($get_option_meta)) {
4422 return $get_option_meta;
4423 }
4424
4425 $value = $this->avalue_dot( $option_key, $get_option_meta );
4426 if ( $value ) {
4427 return $value;
4428 }
4429 return $default;
4430 }
4431
4432 /**
4433 * @param int $assignment_id
4434 * @param int $user_id
4435 *
4436 * @return int
4437 *
4438 * Is running any assignment submitting
4439 *
4440 * @since v.1.3.3
4441 */
4442 public function is_assignment_submitting($assignment_id = 0, $user_id = 0){
4443 global $wpdb;
4444
4445 $assignment_id = $this->get_post_id($assignment_id);
4446 $user_id = $this->get_user_id($user_id);
4447
4448 $is_running_submit = (int) $wpdb->get_var("SELECT comment_ID FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitting' AND user_id = {$user_id} AND comment_post_ID =
4449 {$assignment_id} ");
4450
4451 return $is_running_submit;
4452 }
4453
4454 /**
4455 * @param int $assignment_id
4456 * @param int $user_id
4457 *
4458 * @return array|null|object
4459 *
4460 * Determine if any assignment submitted by user to a assignment
4461 *
4462 * @since v.1.3.3
4463 */
4464
4465 public function is_assignment_submitted($assignment_id = 0, $user_id = 0){
4466 global $wpdb;
4467
4468 $assignment_id = $this->get_post_id($assignment_id);
4469 $user_id = $this->get_user_id($user_id);
4470
4471 $has_submitted = $wpdb->get_row("SELECT * FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitted' AND user_id = {$user_id} AND comment_post_ID = {$assignment_id} ");
4472
4473 return $has_submitted;
4474 }
4475
4476 public function get_assignment_submit_info($assignment_submitted_id = 0){
4477 global $wpdb;
4478
4479 $assignment_submitted_id = $this->get_post_id($assignment_submitted_id);
4480 $submitted_info = $wpdb->get_row("SELECT * FROM {$wpdb->comments} WHERE comment_ID = {$assignment_submitted_id} AND comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4481
4482 return $submitted_info;
4483 }
4484
4485 public function get_total_assignments(){
4486 global $wpdb;
4487
4488 $count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4489
4490 return (int) $count;
4491 }
4492
4493 public function get_assignments(){
4494 global $wpdb;
4495
4496 $results = $wpdb->get_results("SELECT * FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4497
4498 return $results;
4499 }
4500
4501 /**
4502 * @param int $user_id
4503 *
4504 * @return array
4505 *
4506 * Get all courses id assigned or owned by an instructors
4507 *
4508 * @since v.1.3.3
4509 */
4510 public function get_assigned_courses_ids_by_instructors($user_id = 0){
4511 global $wpdb;
4512 $user_id = $this->get_user_id($user_id);
4513
4514 $course_post_type = tutor()->course_post_type;
4515 $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} GROUP BY meta_value ; ");
4516
4517 /*
4518 $author_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} where post_type = '{$course_post_type}' AND post_author = {$user_id}");
4519 $final_course_ids = array_merge($get_assigned_courses_ids, $author_ids);
4520 $final_course_ids = array_unique($final_course_ids);
4521 */
4522
4523 return $get_assigned_courses_ids;
4524 }
4525
4526 /**
4527 * @param int $parent
4528 *
4529 * @return array
4530 *
4531 * Get course categories in array with child
4532 *
4533 * @since v.1.3.4
4534 */
4535
4536 public function get_course_categories($parent = 0 ){
4537 $args = apply_filters('tutor_get_course_categories_args', array(
4538 'taxonomy' => 'course-category',
4539 'hide_empty' => false,
4540 'parent' => $parent,
4541 ));
4542
4543 $terms = get_terms($args);
4544
4545 $children = array();
4546 foreach ( $terms as $term ){
4547 $term->children = $this->get_course_categories( $term->term_id );
4548 $children[ $term->term_id ] = $term;
4549 }
4550
4551 return $children;
4552 }
4553
4554 /**
4555 * @param int $parent_id
4556 *
4557 * @return array|int|\WP_Error
4558 *
4559 * Get course categories terms in raw array
4560 *
4561 * @since v.1.3.5
4562 */
4563 public function get_course_categories_term($parent_id = 0){
4564 $args = apply_filters('tutor_get_course_categories_terms_args', array(
4565 'taxonomy' => 'course-category',
4566 'parent' => $parent_id,
4567 'hide_empty' => false,
4568 ));
4569
4570 $terms = get_terms($args);
4571
4572 return $terms;
4573 }
4574
4575 /**
4576 * @return mixed
4577 *
4578 * Get back url from the request
4579 * @since v.1.3.4
4580 */
4581 public function referer(){
4582 $url = $this->array_get('_wp_http_referer', $_REQUEST);
4583 return apply_filters('tutor_referer_url', $url);
4584 }
4585
4586 /**
4587 * @param int $course_id
4588 *
4589 * @return false|string
4590 *
4591 * Get the frontend dashboard course edit page
4592 *
4593 * @since v.1.3.4
4594 */
4595 public function course_edit_link($course_id = 0){
4596 $course_id = $this->get_post_id($course_id);
4597
4598 $url = admin_url("post.php?post={$course_id}&action=edit");
4599 if (tutor()->has_pro){
4600 $url = $this->tutor_dashboard_url("create-course/?course_ID=".$course_id);
4601 }
4602
4603 return $url;
4604 }
4605
4606 public function get_assignments_by_instructor($instructor_id = 0, $filter_data = array()){
4607 global $wpdb;
4608
4609 $instructor_id = $this->get_user_id($instructor_id);
4610 $course_ids = tutor_utils()->get_assigned_courses_ids_by_instructors($instructor_id);
4611
4612 //$new_course_ids = tutils()->get_courses_by_instructor();
4613
4614 //die($this->print_view($course_ids));
4615
4616 $in_course_ids = implode("','", $course_ids);
4617
4618 $count = (int) $wpdb->get_var("SELECT COUNT(ID) FROM {$wpdb->postmeta} post_meta
4619 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4620 where post_type = 'tutor_assignments' AND post_meta.meta_value IN('$in_course_ids') ORDER BY ID DESC ");
4621
4622 $pagination_query = '';
4623 if ($this->count($filter_data)) {
4624 extract( $filter_data );
4625
4626 if ( ! empty( $per_page ) ) {
4627 $offset = (int) ! empty( $offset ) ? $offset : 0;
4628 $pagination_query = " LIMIT {$offset}, {$per_page} ";
4629 }
4630 }
4631
4632 $query = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} post_meta
4633 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4634 where post_type = 'tutor_assignments' AND post_meta.meta_value IN('$in_course_ids') ORDER BY ID DESC {$pagination_query} ");
4635
4636 return (object) array('count' => $count, 'results' => $query);
4637 }
4638
4639 /**
4640 * @param int $course_id
4641 *
4642 * @return bool|object
4643 *
4644 * Get assignments by course id
4645 */
4646 public function get_assignments_by_course($course_id = 0){
4647 if ( ! $course_id){
4648 return false;
4649 }
4650 global $wpdb;
4651
4652 $count = (int) $wpdb->get_var("SELECT COUNT(ID) FROM {$wpdb->postmeta} post_meta
4653 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4654 where post_type = 'tutor_assignments' AND post_meta.meta_value = {$course_id} ORDER BY ID DESC ");
4655
4656 $query = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} post_meta
4657 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4658 where post_type = 'tutor_assignments' AND post_meta.meta_value = {$course_id} ORDER BY ID DESC");
4659
4660 return (object) array('count' => $count, 'results' => $query);
4661 }
4662
4663 /**
4664 * @return bool
4665 *
4666 * Determine if script debug
4667 *
4668 * @since v.1.3.4
4669 */
4670 public function is_script_debug(){
4671 return ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
4672 }
4673
4674 }