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