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