PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.4.1
Tutor LMS – eLearning and online course solution v1.4.1
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
5111 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 */
2123 public function input_old($input = ''){
2124 $value = $this->avalue_dot($input, $_REQUEST);
2125 if ($value){
2126 return $value;
2127 }
2128 return '';
2129 }
2130
2131 /**
2132 * @param int $user_id
2133 *
2134 * @return mixed
2135 *
2136 * Determine if is instructor or not
2137 *
2138 * @since v.1.0.0
2139 */
2140 public function is_instructor($user_id = 0){
2141 $user_id = $this->get_user_id($user_id);
2142 return get_user_meta($user_id, '_is_tutor_instructor', true);
2143 }
2144
2145 /**
2146 * @param int $user_id
2147 * @param bool $status_name
2148 *
2149 * @return bool|mixed
2150 *
2151 * Instructor status
2152 *
2153 * @since v.1.0.0
2154 */
2155 public function instructor_status($user_id = 0, $status_name = true){
2156 $user_id = $this->get_user_id($user_id);
2157
2158 $instructor_status = apply_filters('tutor_instructor_statuses', array(
2159 'pending' => __('Pending', 'tutor'),
2160 'approved' => __('Approved', 'tutor'),
2161 'blocked' => __('Blocked', 'tutor'),
2162 ));
2163
2164 $status = get_user_meta($user_id, '_tutor_instructor_status', true);
2165
2166 if (isset($instructor_status[$status])){
2167 if ( ! $status_name){
2168 return $status;
2169 }
2170 return $instructor_status[$status];
2171 }
2172 return false;
2173 }
2174
2175 /**
2176 * @param string $search_term
2177 *
2178 * @return int
2179 *
2180 * Get total number of instructors
2181 *
2182 * @since v.1.0.0
2183 */
2184
2185 public function get_total_instructors($search_term = ''){
2186 $meta_key = '_is_tutor_instructor';
2187
2188 global $wpdb;
2189
2190 if ($search_term){
2191 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2192 }
2193
2194 $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 ");
2195
2196 return (int) $count;
2197 }
2198
2199 /**
2200 * @param int $start
2201 * @param int $limit
2202 * @param string $search_term
2203 *
2204 * @return array|null|object
2205 *
2206 * Get all instructors
2207 *
2208 * @since v.1.0.0
2209 */
2210 public function get_instructors($start = 0, $limit = 10, $search_term = ''){
2211 $meta_key = '_is_tutor_instructor';
2212 global $wpdb;
2213
2214 if ($search_term){
2215 $search_term = " AND ( {$wpdb->users}.display_name LIKE '%{$search_term}%' OR {$wpdb->users}.user_email LIKE '%{$search_term}%' ) ";
2216 }
2217
2218 $instructors = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.* FROM {$wpdb->users}
2219 INNER JOIN {$wpdb->usermeta}
2220 ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
2221 WHERE 1=1 AND ( {$wpdb->usermeta}.meta_key = '{$meta_key}' ) {$search_term}
2222 ORDER BY {$wpdb->usermeta}.meta_value DESC
2223 LIMIT {$start}, {$limit} ");
2224
2225 return $instructors;
2226 }
2227
2228 /**
2229 * @param int $course_id
2230 *
2231 * @return array|bool|null|object
2232 *
2233 * Get all instructors by course
2234 *
2235 * @since v.1.0.0
2236 */
2237 public function get_instructors_by_course($course_id = 0){
2238 global $wpdb;
2239 $course_id = $this->get_post_id($course_id);
2240
2241 $instructors = $wpdb->get_results("select ID, display_name,
2242 get_course.meta_value as taught_course_id,
2243 tutor_job_title.meta_value as tutor_profile_job_title,
2244 tutor_bio.meta_value as tutor_profile_bio,
2245 tutor_photo.meta_value as tutor_profile_photo
2246 from {$wpdb->users}
2247 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}
2248 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2249 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2250 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2251 ");
2252
2253 if (is_array($instructors) && count($instructors)){
2254 return $instructors;
2255 }
2256
2257 return false;
2258 }
2259
2260 /**
2261 * @param $instructor_id
2262 *
2263 * Get total Students by instructor
2264 * 1 enrollment = 1 student, so total enrolled for a equivalent total students (Tricks)
2265 *
2266 * @return int
2267 *
2268 * @since v.1.0.0
2269 */
2270
2271 public function get_total_students_by_instructor($instructor_id){
2272 global $wpdb;
2273
2274 $course_post_type = tutor()->course_post_type;
2275 $count = $wpdb->get_var("SELECT COUNT(courses.ID) from {$wpdb->posts} courses
2276
2277 INNER JOIN {$wpdb->posts} enrolled ON courses.ID = enrolled.post_parent AND enrolled.post_type = 'tutor_enrolled'
2278 WHERE courses.post_status = 'publish'
2279 AND courses.post_type = '{$course_post_type}'
2280 AND courses.post_author = {$instructor_id} ; ");
2281 return (int) $count;
2282 }
2283
2284 /**
2285 * @param float $input
2286 *
2287 * @return float|string
2288 *
2289 * Get rating format from value
2290 *
2291 * @since v.1.0.0
2292 */
2293 public function get_rating_value($input = 0.00){
2294
2295 if ( $input > 0){
2296 $input = number_format($input, 2);
2297 $int_value = (int) $input;
2298 $fraction = $input - $int_value;
2299
2300 if ($fraction == 0){
2301 $fraction = 0.00;
2302 }elseif($fraction > 0.5){
2303 $fraction = 1;
2304 }else{
2305 $fraction = 0.5;
2306 }
2307
2308 return number_format( ($int_value + $fraction), 2);
2309 }
2310 return 0.00;
2311 }
2312
2313 /**
2314 * @param float $current_rating
2315 * @param bool $echo
2316 *
2317 * @return string
2318 *
2319 * Generate star rating based in given rating value
2320 *
2321 * @since v.1.0.0
2322 */
2323 public function star_rating_generator($current_rating = 0.00, $echo = true){
2324 $output = '<div class="tutor-star-rating-group">';
2325
2326 for ($i = 1; $i <=5 ; $i++){
2327 $intRating = (int) $current_rating;
2328
2329 if ($intRating >= $i){
2330 $output.= '<i class="tutor-icon-star-full" data-rating-value="'.$i.'"></i>';
2331 } else{
2332 if ( ($current_rating - $i) == -0.5){
2333 $output.= '<i class="tutor-icon-star-half" data-rating-value="'.$i.'"></i>';
2334 }else{
2335 $output.= '<i class="tutor-icon-star-line" data-rating-value="'.$i.'"></i>';
2336 }
2337 }
2338 }
2339
2340 $output .= "<div class='tutor-rating-gen-input'><input type='hidden' name='tutor_rating_gen_input' value='{$current_rating}' /> </div>";
2341
2342 $output .= "</div>";
2343
2344 if ($echo){
2345 echo $output;
2346 }
2347 return $output;
2348 }
2349
2350 /**
2351 * @param null $name
2352 *
2353 * @return string
2354 *
2355 * Generate text to avatar
2356 *
2357 * @since v.1.0.0
2358 */
2359 public function get_tutor_avatar($user_id = null, $size = 'thumbnail'){
2360 global $wpdb;
2361
2362 if ( ! $user_id){
2363 return '';
2364 }
2365
2366 $user = $this->get_tutor_user($user_id);
2367 if ($user->tutor_profile_photo){
2368 return '<img src="'.wp_get_attachment_image_url($user->tutor_profile_photo, $size).'" class="tutor-image-avatar" alt="" /> ';
2369 }
2370
2371 $name = $user->display_name;
2372 $arr = explode(' ', trim($name));
2373
2374 if (count($arr) > 1){
2375 $first_char = substr($arr[0], 0, 1) ;
2376 $second_char = substr($arr[1], 0, 1) ;
2377 }else{
2378 $first_char = substr($arr[0], 0, 1) ;
2379 $second_char = substr($arr[0], 1, 1) ;
2380 }
2381
2382 $initial_avatar = strtoupper($first_char.$second_char);
2383
2384 $bg_color = '#'.substr(md5($initial_avatar), 0, 6);
2385 $initial_avatar = "<span class='tutor-text-avatar' style='background-color: {$bg_color}; color: #fff8e5'>{$initial_avatar}</span>";
2386
2387 return $initial_avatar;
2388 }
2389
2390 /**
2391 * @param $user_id
2392 *
2393 * @return array|null|object|void
2394 *
2395 * Get tutor user
2396 *
2397 * @since v.1.0.0
2398 */
2399
2400 public function get_tutor_user($user_id){
2401 global $wpdb;
2402
2403 $user = $wpdb->get_row("select ID, display_name,
2404 tutor_job_title.meta_value as tutor_profile_job_title,
2405 tutor_bio.meta_value as tutor_profile_bio,
2406 tutor_photo.meta_value as tutor_profile_photo
2407
2408 from {$wpdb->users}
2409 LEFT JOIN {$wpdb->usermeta} tutor_job_title ON ID = tutor_job_title.user_id AND tutor_job_title.meta_key = '_tutor_profile_job_title'
2410 LEFT JOIN {$wpdb->usermeta} tutor_bio ON ID = tutor_bio.user_id AND tutor_bio.meta_key = '_tutor_profile_bio'
2411 LEFT JOIN {$wpdb->usermeta} tutor_photo ON ID = tutor_photo.user_id AND tutor_photo.meta_key = '_tutor_profile_photo'
2412
2413 WHERE ID = {$user_id} ");
2414 return $user;
2415 }
2416
2417 /**
2418 * @param int $course_id
2419 * @param int $offset
2420 * @param int $limit
2421 *
2422 * @return array|null|object
2423 *
2424 * get course reviews
2425 *
2426 * @since v.1.0.0
2427 */
2428 public function get_course_reviews($course_id = 0, $offset = 0, $limit = 150){
2429 $course_id = $this->get_post_id($course_id);
2430 global $wpdb;
2431
2432 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2433 {$wpdb->comments}.comment_post_ID,
2434 {$wpdb->comments}.comment_author,
2435 {$wpdb->comments}.comment_author_email,
2436 {$wpdb->comments}.comment_date,
2437 {$wpdb->comments}.comment_content,
2438 {$wpdb->comments}.user_id,
2439 {$wpdb->commentmeta}.meta_value as rating,
2440 {$wpdb->users}.display_name
2441
2442 from {$wpdb->comments}
2443 INNER JOIN {$wpdb->commentmeta}
2444 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2445 INNER JOIN {$wpdb->users}
2446 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2447 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2448 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2449 );
2450
2451 return $reviews;
2452 }
2453
2454 /**
2455 * @param int $course_id
2456 *
2457 * @return object
2458 *
2459 * Get course rating
2460 *
2461 * @since v.1.0.0
2462 */
2463 public function get_course_rating($course_id = 0){
2464 $course_id = $this->get_post_id($course_id);
2465
2466 $ratings = array(
2467 'rating_count' => 0,
2468 'rating_sum' => 0,
2469 'rating_avg' => 0.00,
2470 'count_by_value' => array(5 => 0, 4 => 0, 3 => 0, 2 => 0, 1 => 0)
2471 );
2472
2473 global $wpdb;
2474
2475 $rating = $wpdb->get_row("select COUNT(meta_value) as rating_count, SUM(meta_value) as rating_sum
2476 from {$wpdb->comments}
2477 INNER JOIN {$wpdb->commentmeta}
2478 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2479 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2480 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2481 AND meta_key = 'tutor_rating' ;"
2482 );
2483
2484 if ($rating->rating_count){
2485 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2486
2487 /**
2488 * Get individual Rating by integer
2489 */
2490 $five_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2491 from {$wpdb->comments}
2492 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2493 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2494 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2495 AND meta_key = 'tutor_rating' AND meta_value = 5 ;"
2496 );
2497 $four_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2498 from {$wpdb->comments}
2499 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2500 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2501 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2502 AND meta_key = 'tutor_rating' AND meta_value = 4 ;"
2503 );
2504 $three_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2505 from {$wpdb->comments}
2506 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2507 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2508 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2509 AND meta_key = 'tutor_rating' AND meta_value = 3 ;"
2510 );
2511 $two_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2512 from {$wpdb->comments}
2513 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2514 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2515 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2516 AND meta_key = 'tutor_rating' AND meta_value = 2 ;"
2517 );
2518 $one_stars_count = $wpdb->get_var("select COUNT(meta_value) as rating_count
2519 from {$wpdb->comments}
2520 INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2521 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2522 AND {$wpdb->comments}.comment_type = 'tutor_course_rating'
2523 AND meta_key = 'tutor_rating' AND meta_value = 1 ;"
2524 );
2525
2526 $ratings = array(
2527 'rating_count' => $rating->rating_count,
2528 'rating_sum' => $rating->rating_sum,
2529 'rating_avg' => $avg_rating,
2530 'count_by_value' => array(5 => $five_stars_count, 4 => $four_stars_count, 3 => $three_stars_count, 2 => $two_stars_count, 1 => $one_stars_count)
2531 );
2532
2533 }
2534
2535 return (object) $ratings;
2536 }
2537
2538 /**
2539 * @param int $user_id
2540 * @param int $offset
2541 * @param int $limit
2542 *
2543 * @return array|null|object
2544 *
2545 * Get reviews by a user
2546 *
2547 * @since v.1.0.0
2548 */
2549 public function get_reviews_by_user($user_id = 0, $offset = 0, $limit = 150){
2550 $user_id = $this->get_user_id($user_id);
2551 global $wpdb;
2552
2553 $reviews = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2554 {$wpdb->comments}.comment_post_ID,
2555 {$wpdb->comments}.comment_author,
2556 {$wpdb->comments}.comment_author_email,
2557 {$wpdb->comments}.comment_date,
2558 {$wpdb->comments}.comment_content,
2559 {$wpdb->comments}.user_id,
2560 {$wpdb->commentmeta}.meta_value as rating,
2561 {$wpdb->users}.display_name
2562
2563 from {$wpdb->comments}
2564 INNER JOIN {$wpdb->commentmeta}
2565 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2566 INNER JOIN {$wpdb->users}
2567 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2568 WHERE {$wpdb->comments}.user_id = {$user_id}
2569 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2570 );
2571
2572 return $reviews;
2573 }
2574
2575 /**
2576 * @param int $user_id
2577 * @param int $offset
2578 * @param int $limit
2579 *
2580 * @return array|null|object
2581 *
2582 * Get reviews by instructor
2583 *
2584 * @since v.1.4.0
2585 */
2586
2587 public function get_reviews_by_instructor($instructor_id = 0, $offset = 0, $limit = 150){
2588 $instructor_id = $this->get_user_id($instructor_id);
2589 global $wpdb;
2590
2591 $results = array(
2592 'count' => 0,
2593 'results' => false,
2594 );
2595
2596 $cours_ids = (array) $this->get_assigned_courses_ids_by_instructors($instructor_id);
2597
2598 if ($this->count($cours_ids)){
2599 $implode_ids = implode( ',', $cours_ids );
2600
2601 //Count
2602 $results['count'] = $wpdb->get_var("select COUNT({$wpdb->comments}.comment_ID)
2603 from {$wpdb->comments}
2604 INNER JOIN {$wpdb->commentmeta}
2605 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2606 INNER JOIN {$wpdb->users}
2607 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2608 WHERE {$wpdb->comments}.comment_post_ID IN({$implode_ids})
2609 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating';" );
2610
2611 //Results
2612 $results['results'] = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2613 {$wpdb->comments}.comment_post_ID,
2614 {$wpdb->comments}.comment_author,
2615 {$wpdb->comments}.comment_author_email,
2616 {$wpdb->comments}.comment_date,
2617 {$wpdb->comments}.comment_content,
2618 {$wpdb->comments}.user_id,
2619 {$wpdb->commentmeta}.meta_value as rating,
2620 {$wpdb->users}.display_name
2621
2622 from {$wpdb->comments}
2623 INNER JOIN {$wpdb->commentmeta}
2624 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2625 INNER JOIN {$wpdb->users}
2626 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2627 WHERE {$wpdb->comments}.comment_post_ID IN({$implode_ids})
2628 AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;" );
2629 }
2630
2631 return (object) $results;
2632 }
2633
2634 /**
2635 * @param $instructor_id
2636 *
2637 * @return object
2638 *
2639 * Get instructors rating
2640 *
2641 * @since v.1.0.0
2642 */
2643 public function get_instructor_ratings($instructor_id){
2644 global $wpdb;
2645
2646 $ratings = array(
2647 'rating_count' => 0,
2648 'rating_sum' => 0,
2649 'rating_avg' => 0.00,
2650 );
2651
2652 $rating = $wpdb->get_row("SELECT COUNT(rating.meta_value) as rating_count, SUM(rating.meta_value) as rating_sum
2653 FROM {$wpdb->usermeta} courses
2654 INNER JOIN {$wpdb->comments} reviews ON courses.meta_value = reviews.comment_post_ID AND reviews.comment_type = 'tutor_course_rating'
2655 INNER JOIN {$wpdb->commentmeta} rating ON reviews.comment_ID = rating.comment_id AND rating.meta_key = 'tutor_rating'
2656 WHERE courses.user_id = {$instructor_id} AND courses.meta_key = '_tutor_instructor_course_id'");
2657
2658 if ($rating->rating_count){
2659 $avg_rating = number_format(($rating->rating_sum / $rating->rating_count), 2);
2660
2661 $ratings = array(
2662 'rating_count' => $rating->rating_count,
2663 'rating_sum' => $rating->rating_sum,
2664 'rating_avg' => $avg_rating,
2665 );
2666 }
2667
2668 return (object) $ratings;
2669 }
2670
2671 /**
2672 * @param int $course_id
2673 * @param int $user_id
2674 *
2675 * @return object
2676 *
2677 * Get course rating by user
2678 *
2679 * @since v.1.0.0
2680 */
2681 public function get_course_rating_by_user($course_id = 0, $user_id = 0){
2682 $course_id = $this->get_post_id($course_id);
2683 $user_id = $this->get_user_id($user_id);
2684
2685 $ratings = array(
2686 'rating' => 0,
2687 'review' => '',
2688 );
2689
2690 global $wpdb;
2691
2692 $rating = $wpdb->get_row("select meta_value as rating, comment_content as review from {$wpdb->comments}
2693 INNER JOIN {$wpdb->commentmeta}
2694 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2695 WHERE {$wpdb->comments}.comment_post_ID = {$course_id} AND user_id = {$user_id}
2696 AND meta_key = 'tutor_rating' ;"
2697 );
2698
2699 if ($rating){
2700 $rating_format = number_format($rating->rating, 2);
2701
2702 $ratings = array(
2703 'rating' => $rating_format,
2704 'review' => $rating->review,
2705 );
2706 }
2707 return (object) $ratings;
2708 }
2709
2710 /**
2711 * @param int $user_id
2712 *
2713 * @return null|string
2714 *
2715 * @since v.1.0.0
2716 */
2717 public function count_reviews_wrote_by_user($user_id = 0){
2718 global $wpdb;
2719 $user_id = $this->get_user_id($user_id);
2720
2721 $count_reviews = $wpdb->get_var("SELECT COUNT(comment_ID) from {$wpdb->comments} WHERE user_id = {$user_id} AND comment_type = 'tutor_course_rating' ");
2722 return $count_reviews;
2723 }
2724
2725 /**
2726 * @param $size
2727 *
2728 * @return bool|int|string
2729 *
2730 * This function transforms the php.ini notation for numbers (like '2M') to an integer.
2731 *
2732 * @since v.1.0.0
2733 */
2734
2735 function let_to_num( $size ) {
2736 $l = substr( $size, -1 );
2737 $ret = substr( $size, 0, -1 );
2738 $byte = 1024;
2739
2740 switch ( strtoupper( $l ) ) {
2741 case 'P':
2742 $ret *= 1024;
2743 // No break.
2744 case 'T':
2745 $ret *= 1024;
2746 // No break.
2747 case 'G':
2748 $ret *= 1024;
2749 // No break.
2750 case 'M':
2751 $ret *= 1024;
2752 // No break.
2753 case 'K':
2754 $ret *= 1024;
2755 // No break.
2756 }
2757 return $ret;
2758 }
2759
2760 /**
2761 * @return array
2762 *
2763 * Get Database version
2764 *
2765 * @since v.1.0.0
2766 */
2767 function get_db_version() {
2768 global $wpdb;
2769
2770 if ( empty( $wpdb->is_mysql ) ) {
2771 return array(
2772 'string' => '',
2773 'number' => '',
2774 );
2775 }
2776
2777 if ( $wpdb->use_mysqli ) {
2778 $server_info = mysqli_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2779 } else {
2780 $server_info = mysql_get_server_info( $wpdb->dbh ); // @codingStandardsIgnoreLine.
2781 }
2782
2783 return array(
2784 'string' => $server_info,
2785 'number' => preg_replace( '/([^\d.]+).*/', '', $server_info ),
2786 );
2787 }
2788
2789 public function help_tip($tip = ''){
2790 return '<span class="tutor-help-tip" data-tip="' . $tip . '"></span>';
2791 }
2792
2793 /**
2794 * @param int $course_id
2795 * @param int $user_id
2796 * @param int $offset
2797 * @param int $limit
2798 *
2799 * @return array|null|object
2800 *
2801 * Get top question
2802 *
2803 * @since v.1.0.0
2804 */
2805 public function get_top_question($course_id = 0, $user_id = 0, $offset = 0, $limit = 20){
2806 $course_id = $this->get_post_id($course_id);
2807 $user_id = $this->get_user_id($user_id);
2808
2809 global $wpdb;
2810
2811 $questions = $wpdb->get_results("select {$wpdb->comments}.comment_ID,
2812 {$wpdb->comments}.comment_post_ID,
2813 {$wpdb->comments}.comment_author,
2814 {$wpdb->comments}.comment_date,
2815 {$wpdb->comments}.comment_content,
2816 {$wpdb->comments}.user_id,
2817 {$wpdb->commentmeta}.meta_value as question_title,
2818 {$wpdb->users}.display_name
2819
2820 from {$wpdb->comments}
2821 INNER JOIN {$wpdb->commentmeta}
2822 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2823 INNER JOIN {$wpdb->users}
2824 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2825 WHERE {$wpdb->comments}.comment_post_ID = {$course_id}
2826 AND {$wpdb->comments}.user_id = {$user_id}
2827 AND {$wpdb->comments}.comment_type = 'tutor_q_and_a'
2828 AND meta_key = 'tutor_question_title' ORDER BY comment_ID DESC LIMIT {$offset},{$limit} ;"
2829 );
2830
2831 return $questions;
2832 }
2833
2834 /**
2835 * @param string $search_term
2836 *
2837 * @return int
2838 *
2839 * Get total number of Q&A questions
2840 *
2841 * @since v.1.0.0
2842 */
2843 public function get_total_qa_question($search_term = ''){
2844 global $wpdb;
2845
2846 if ($search_term){
2847 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2848 }
2849
2850 $user_id = get_current_user_id();
2851 $course_type = tutor()->course_post_type;
2852
2853 $in_question_id_query = '';
2854 /**
2855 * Get only assinged courses questions if current user is a
2856 */
2857 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2858 $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' " );
2859 $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} " );
2860 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2861
2862 if ( $this->count( $my_course_ids ) ) {
2863 $implode_ids = implode( ',', $my_course_ids );
2864 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2865 }
2866 }
2867
2868 $count = $wpdb->get_var("SELECT COUNT({$wpdb->comments}.comment_ID) FROM {$wpdb->comments}
2869 INNER JOIN {$wpdb->commentmeta}
2870 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2871 WHERE comment_type = 'tutor_q_and_a' AND comment_parent = 0 {$in_question_id_query} {$search_term} ");
2872
2873 return (int) $count;
2874 }
2875
2876 /**
2877 * @param int $start
2878 * @param int $limit
2879 * @param string $search_term
2880 *
2881 * @return array|null|object
2882 *
2883 *
2884 * Get question and answer query
2885 *
2886 * @since v.1.0.0
2887 */
2888 public function get_qa_questions($start = 0, $limit = 10, $search_term = '') {
2889 global $wpdb;
2890
2891 if ($search_term){
2892 $search_term = " AND {$wpdb->commentmeta}.meta_value LIKE '%{$search_term}%' ";
2893 }
2894
2895 $user_id = get_current_user_id();
2896 $course_type = tutor()->course_post_type;
2897
2898 $in_question_id_query = '';
2899 /**
2900 * Get only assinged courses questions if current user is a
2901 */
2902 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
2903 $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' " );
2904 $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} " );
2905 $my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
2906
2907 if ( $this->count( $my_course_ids ) ) {
2908 $implode_ids = implode( ',', $my_course_ids );
2909 $in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
2910 }
2911 }
2912
2913 $query = $wpdb->get_results("SELECT
2914 {$wpdb->comments}.comment_ID,
2915 {$wpdb->comments}.comment_post_ID,
2916 {$wpdb->comments}.comment_author,
2917 {$wpdb->comments}.comment_date,
2918 {$wpdb->comments}.comment_content,
2919 {$wpdb->comments}.user_id,
2920 {$wpdb->commentmeta}.meta_value as question_title,
2921 {$wpdb->users}.display_name,
2922 {$wpdb->posts}.post_title,
2923
2924 (SELECT COUNT(answers_t.comment_ID) FROM {$wpdb->comments} answers_t
2925 WHERE answers_t.comment_parent = {$wpdb->comments}.comment_ID ) as answer_count
2926
2927 FROM {$wpdb->comments}
2928
2929 INNER JOIN {$wpdb->commentmeta}
2930 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2931
2932 INNER JOIN {$wpdb->posts}
2933 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2934
2935 INNER JOIN {$wpdb->users}
2936 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2937
2938 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_parent = 0 {$search_term}
2939 {$in_question_id_query}
2940 ORDER BY {$wpdb->comments}.comment_ID DESC
2941 LIMIT {$start},{$limit}; ");
2942
2943 return $query;
2944 }
2945
2946 /**
2947 * @param $question_id
2948 *
2949 * @return array|null|object|void
2950 *
2951 * Get question for Q&A
2952 *
2953 * @since v.1.0.0
2954 */
2955 public function get_qa_question($question_id){
2956 global $wpdb;
2957 $query = $wpdb->get_row("SELECT
2958 {$wpdb->comments}.comment_ID,
2959 {$wpdb->comments}.comment_post_ID,
2960 {$wpdb->comments}.comment_author,
2961 {$wpdb->comments}.comment_date,
2962 {$wpdb->comments}.comment_content,
2963 {$wpdb->comments}.user_id,
2964 {$wpdb->commentmeta}.meta_value as question_title,
2965 {$wpdb->users}.display_name,
2966 {$wpdb->posts}.post_title
2967
2968 FROM {$wpdb->comments}
2969 INNER JOIN {$wpdb->commentmeta}
2970 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
2971
2972 INNER JOIN {$wpdb->posts}
2973 ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
2974
2975 INNER JOIN {$wpdb->users}
2976 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
2977 WHERE comment_type = 'tutor_q_and_a' AND {$wpdb->comments}.comment_ID = {$question_id}");
2978
2979 return $query;
2980 }
2981
2982 /**
2983 * @param $question_id
2984 *
2985 * @return array|null|object
2986 *
2987 * Get question and asnwer by question
2988 */
2989 public function get_qa_answer_by_question($question_id){
2990 global $wpdb;
2991 $query = $wpdb->get_results("SELECT
2992 {$wpdb->comments}.comment_ID,
2993 {$wpdb->comments}.comment_post_ID,
2994 {$wpdb->comments}.comment_author,
2995 {$wpdb->comments}.comment_date,
2996 {$wpdb->comments}.comment_content,
2997 {$wpdb->comments}.comment_parent,
2998 {$wpdb->comments}.user_id,
2999 {$wpdb->users}.display_name
3000
3001 FROM {$wpdb->comments}
3002
3003 INNER JOIN {$wpdb->users}
3004 ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
3005 WHERE comment_type = 'tutor_q_and_a'
3006 AND {$wpdb->comments}.comment_parent = {$question_id} ORDER BY {$wpdb->comments}.comment_ID ASC ");
3007
3008 return $query;
3009 }
3010
3011 public function unanswered_question_count(){
3012 global $wpdb;
3013
3014 $count = $wpdb->get_var("select COUNT({$wpdb->comments}.comment_ID)
3015 from {$wpdb->comments}
3016 WHERE {$wpdb->comments}.comment_type = 'tutor_q_and_a'
3017 AND {$wpdb->comments}.comment_approved = 'waiting_for_answer'
3018 AND {$wpdb->comments}.comment_parent = 0;");
3019 return (int) $count;
3020 }
3021
3022 /**
3023 * @param int $course_id
3024 *
3025 * @return array|null|object
3026 *
3027 * Return all of announcements for a course
3028 *
3029 * @since v.1.0.0
3030 */
3031 public function get_announcements($course_id = 0){
3032 $course_id = $this->get_post_id($course_id);
3033 global $wpdb;
3034
3035 $query = $wpdb->get_results("select {$wpdb->posts}.ID, post_author, post_date, post_content, post_title, display_name
3036 from {$wpdb->posts}
3037 INNER JOIN {$wpdb->users} ON post_author = {$wpdb->users}.ID
3038 WHERE post_type = 'tutor_announcements'
3039 AND post_parent = {$course_id} ORDER BY {$wpdb->posts}.ID DESC;");
3040 return $query;
3041 }
3042
3043 /**
3044 * @param string $content
3045 *
3046 * @return mixed
3047 *
3048 * Announcement content
3049 *
3050 * @since v.1.0.0
3051 */
3052
3053 public function announcement_content($content = ''){
3054 $search = array('{user_display_name}');
3055
3056 $user_display_name = 'User';
3057 if (is_user_logged_in()){
3058 $user = wp_get_current_user();
3059 $user_display_name = $user->display_name;
3060 }
3061 $replace = array($user_display_name);
3062
3063 return str_replace($search, $replace, $content);
3064 }
3065
3066 /**
3067 * @param int $post_id
3068 * @param string $option_key
3069 * @param bool $default
3070 *
3071 * @return array|bool|mixed
3072 *
3073 * Get the quiz option from meta
3074 */
3075 public function get_quiz_option($post_id = 0, $option_key = '', $default = false){
3076 $post_id = $this->get_post_id($post_id);
3077 $get_option_meta = maybe_unserialize(get_post_meta($post_id, 'tutor_quiz_option', true));
3078
3079 if ( ! $option_key && ! empty($get_option_meta)) {
3080 return $get_option_meta;
3081 }
3082
3083 $value = $this->avalue_dot( $option_key, $get_option_meta );
3084 if ( $value > 0 || $value !== false ) {
3085 return $value;
3086 }
3087 return $default;
3088 }
3089
3090
3091 /**
3092 * @param int $quiz_id
3093 *
3094 * @return array|bool|null|object
3095 *
3096 * Get the questions by quiz ID
3097 */
3098 public function get_questions_by_quiz($quiz_id = 0){
3099 $quiz_id = $this->get_post_id($quiz_id);
3100 global $wpdb;
3101
3102 //$questions = $wpdb->get_results("SELECT ID, post_content, post_title, post_parent from {$wpdb->posts} WHERE post_type = 'tutor_question'
3103 // AND post_parent = {$quiz_id} ORDER BY menu_order ASC ");
3104
3105 $questions = $wpdb->get_results("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY question_order ASC ");
3106
3107 if (is_array($questions) && count($questions)){
3108 return $questions;
3109 }
3110 return false;
3111 }
3112
3113 /**
3114 * @param int $question_id
3115 *
3116 * @return array|bool|object|void|null
3117 *
3118 * Get Quiz question by question id
3119 */
3120 public function get_quiz_question_by_id($question_id = 0){
3121 global $wpdb;
3122
3123 if ($question_id){
3124 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} LIMIT 0,1 ;");
3125 return $question;
3126 }
3127
3128 return false;
3129 }
3130
3131 /**
3132 * @param null $type
3133 *
3134 * @return array|mixed
3135 *
3136 * Get all question types
3137 *
3138 * @since v.1.0.0
3139 */
3140
3141 public function get_question_types($type = null){
3142 $types = array(
3143 'true_false' => array('name' => __('True/False', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-yes-no"></i>', 'is_pro' => false),
3144 'single_choice' => array('name' => __('Single Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-mark"></i>', 'is_pro' => false),
3145 'multiple_choice' => array('name' => __('Multiple Choice', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-multiple-choice"></i>', 'is_pro' => false),
3146 'open_ended' => array('name' => __('Open Ended/Essay', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-open-ended"></i>', 'is_pro' => false),
3147 '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),
3148 'short_answer' => array('name' => __('Short Answer', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-short-ans"></i>', 'is_pro' => true),
3149 'matching' => array('name' => __('Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-matching"></i>', 'is_pro' => true),
3150 'image_matching' => array('name' => __('Image Matching', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-matching"></i>', 'is_pro' => true),
3151 'image_answering' => array('name' => __('Image Answering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-image-ans"></i>', 'is_pro' => true),
3152 'ordering' => array('name' => __('Ordering', 'tutor'), 'icon' => '<i class="tutor-icon-block tutor-icon-ordering"></i>', 'is_pro' => true),
3153 );
3154
3155 if (isset($types[$type])){
3156 return $types[$type];
3157 }
3158 return $types;
3159 }
3160
3161 public function get_quiz_answer_options_by_question($question_id){
3162 global $wpdb;
3163
3164 $answer_options = $wpdb->get_results("select
3165 {$wpdb->comments}.comment_ID,
3166 {$wpdb->comments}.comment_post_ID,
3167 {$wpdb->comments}.comment_content
3168
3169 FROM {$wpdb->comments}
3170 WHERE {$wpdb->comments}.comment_post_ID = {$question_id}
3171 AND {$wpdb->comments}.comment_type = 'quiz_answer_option'
3172 ORDER BY {$wpdb->comments}.comment_karma ASC ;");
3173
3174 if (is_array($answer_options) && count($answer_options)){
3175 return $answer_options;
3176 }
3177 return false;
3178 }
3179
3180 /**
3181 * @param $quiz_id
3182 *
3183 * @return int
3184 *
3185 * Get the next question order ID
3186 *
3187 * @since v.1.0.0
3188 */
3189
3190 public function quiz_next_question_order_id($quiz_id){
3191 global $wpdb;
3192
3193 //$last_order = (int) $wpdb->get_var("SELECT MAX(menu_order) FROM {$wpdb->posts} WHERE post_parent = {$quiz_id} AND post_type =
3194 // 'tutor_question';");
3195
3196 $last_order = (int) $wpdb->get_var("SELECT MAX(question_order) FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ;");
3197 return $last_order + 1;
3198 }
3199
3200 /**
3201 * @param $quiz_id
3202 *
3203 * @return int
3204 *
3205 * new design quiz question
3206 * @since v.1.0.0
3207 */
3208 public function quiz_next_question_id(){
3209 global $wpdb;
3210
3211 $last_order = (int) $wpdb->get_var("SELECT MAX(question_id) FROM {$wpdb->prefix}tutor_quiz_questions;");
3212 return $last_order + 1;
3213 }
3214
3215 public function get_quiz_id_by_question($question_id){
3216 global $wpdb;
3217
3218 $quiz_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$question_id} AND post_type = 'tutor_question' ;");
3219 return $quiz_id;
3220 }
3221
3222 /**
3223 * @param array $config
3224 *
3225 * @return array|bool|null|object
3226 *
3227 * It was used in previous quiz algorithm
3228 *
3229 * @deprecated
3230 *
3231 * @since v.1.0.0
3232 */
3233 public function get_unattached_quiz($config = array()){
3234 global $wpdb;
3235
3236 $default_attr = array(
3237 'search_term' => '',
3238 'start' => '0',
3239 'limit' => '10',
3240 'order' => 'DESC',
3241 'order_by' => 'ID',
3242 );
3243 $attr = array_merge($default_attr, $config);
3244 extract($attr);
3245
3246 $search_query = '';
3247 if (! empty($search_term)){
3248 $search_query = "AND post_title LIKE '%{$search_term}%'";
3249 }
3250
3251 $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} ");
3252
3253 if (is_array($questions) && count($questions)){
3254 return $questions;
3255 }
3256 return false;
3257 }
3258
3259 /**
3260 * @param int $post_id
3261 *
3262 * @return array|bool|null|object
3263 *
3264 * @since v.1.0.0
3265 */
3266 public function get_attached_quiz($post_id = 0){
3267 global $wpdb;
3268
3269 $post_id = $this->get_post_id($post_id);
3270
3271 $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}");
3272
3273 if (is_array($questions) && count($questions)){
3274 return $questions;
3275 }
3276 return false;
3277 }
3278
3279 /**
3280 * @param $quiz_id
3281 *
3282 * @return array|bool|null|object|void
3283 *
3284 * Get course by quiz
3285 *
3286 * @since v.1.0.0
3287 */
3288
3289 public function get_course_by_quiz($quiz_id){
3290 global $wpdb;
3291
3292 $quiz_id = $this->get_post_id($quiz_id);
3293 $post = get_post($quiz_id);
3294
3295 if ($post) {
3296 $course_post_type = tutor()->course_post_type;
3297 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$post->post_parent} " );
3298 if ($course) {
3299 if ( $course->post_type !== $course_post_type ) {
3300 $course = $wpdb->get_row( "select ID, post_name, post_type, post_parent from {$wpdb->posts} where ID = {$course->post_parent} " );
3301 }
3302 return $course;
3303 }
3304 }
3305
3306 return false;
3307 }
3308
3309 /**
3310 * @param $quiz_id
3311 *
3312 * @return int
3313 *
3314 * @since v.1.0.0
3315 */
3316 public function total_questions_for_student_by_quiz($quiz_id){
3317 $quiz_id = $this->get_post_id($quiz_id);
3318 global $wpdb;
3319
3320 $total_question = (int) $wpdb->get_var("select count(ID) from {$wpdb->posts} where post_parent = {$quiz_id} AND post_type = 'tutor_question' ");
3321
3322 return $total_question;
3323 }
3324
3325 /**
3326 * @param int $quiz_id
3327 *
3328 * @return array|null|object|void
3329 *
3330 * Determine if there is any started quiz exists
3331 *
3332 * @since v.1.0.0
3333 */
3334
3335 public function is_started_quiz($quiz_id = 0){
3336 global $wpdb;
3337
3338 $quiz_id = $this->get_post_id($quiz_id);
3339 $user_id = get_current_user_id();
3340
3341 $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' ");
3342
3343 return $is_started;
3344 }
3345
3346 /**
3347 * @param $quiz_id
3348 *
3349 * Method for get the total amount of question for a quiz
3350 * Student will answer this amount of question, one quiz have many question
3351 * but student will answer a specific amount of questions
3352 *
3353 * @return int
3354 *
3355 * @since v.1.0.0
3356 */
3357
3358 public function max_questions_for_take_quiz($quiz_id){
3359 $quiz_id = $this->get_post_id($quiz_id);
3360 global $wpdb;
3361
3362 $max_questions = (int) $wpdb->get_var("select count(question_id) from {$wpdb->prefix}tutor_quiz_questions where quiz_id = {$quiz_id} ");
3363 $max_mentioned = (int) $this->get_quiz_option($quiz_id, 'max_questions_for_answer', 10);
3364
3365 if ($max_mentioned < $max_questions ){
3366 return $max_mentioned;
3367 }
3368
3369 return $max_questions;
3370 }
3371
3372 /**
3373 * @param int $attempt_id
3374 *
3375 * @return array|bool|null|object|void
3376 *
3377 * Get single quiz attempt
3378 *
3379 * @since v.1.0.0
3380 */
3381 public function get_attempt($attempt_id = 0){
3382 global $wpdb;
3383 if ( ! $attempt_id){
3384 return false;
3385 }
3386 $attempt = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE attempt_id = {$attempt_id} ");
3387 return $attempt;
3388 }
3389
3390 /**
3391 * @param $attempt_info
3392 *
3393 * @return mixed
3394 *
3395 * Get unserialize attempt info
3396 *
3397 * @since v.1.0.0
3398 */
3399
3400 public function quiz_attempt_info($attempt_info){
3401 return maybe_unserialize($attempt_info);
3402 }
3403
3404 /**
3405 * @param $quiz_attempt_id
3406 * @param array $attempt_info
3407 *
3408 * @return bool|int
3409 *
3410 * Update attempt for various action
3411 *
3412 * @since v.1.0.0
3413 */
3414 public function quiz_update_attempt_info($quiz_attempt_id, $attempt_info = array()){
3415 $answers = tutor_utils()->avalue_dot('answers', $attempt_info);
3416 $total_marks = array_sum(wp_list_pluck($answers, 'question_mark'));
3417 $earned_marks = tutor_utils()->avalue_dot('marks_earned', $attempt_info);
3418 $earned_mark_percent = $earned_marks > 0 ? ( number_format(($earned_marks * 100) / $total_marks)) : 0;
3419 update_comment_meta($quiz_attempt_id, 'earned_mark_percent', $earned_mark_percent);
3420
3421 return update_comment_meta($quiz_attempt_id,'quiz_attempt_info', $attempt_info);
3422 }
3423
3424 /**
3425 * @param int $quiz_id
3426 *
3427 * @return array|null|object
3428 *
3429 * Get random question by quiz id
3430 *
3431 * @since v.1.0.0
3432 */
3433
3434 public function get_random_question_by_quiz($quiz_id = 0){
3435 global $wpdb;
3436
3437 $quiz_id = $this->get_post_id($quiz_id);
3438 $is_attempt = $this->is_started_quiz($quiz_id);
3439
3440 $tempSql = " AND question_type = 'matching' ";
3441 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} {$tempSql} ORDER BY RAND() LIMIT 0,1 ");
3442
3443 return $questions;
3444 }
3445
3446 /**
3447 * @param int $quiz_id
3448 *
3449 * @return array|null|object
3450 *
3451 * Get random questions by quiz
3452 */
3453 public function get_random_questions_by_quiz($quiz_id = 0){
3454 global $wpdb;
3455
3456 $quiz_id = $this->get_post_id($quiz_id);
3457 $attempt = $this->is_started_quiz($quiz_id);
3458 $total_questions = (int) $attempt->total_questions;
3459 if ( ! $attempt){
3460 return false;
3461 }
3462
3463 $questions_order = tutor_utils()->get_quiz_option(get_the_ID(), 'questions_order', 'rand');
3464
3465 $order_by = "";
3466 if ($questions_order === 'rand'){
3467 $order_by = "ORDER BY RAND()";
3468 }elseif ($questions_order === 'asc'){
3469 $order_by = "ORDER BY question_id ASC";
3470 }elseif ($questions_order === 'desc'){
3471 $order_by = "ORDER BY question_id DESC";
3472 }elseif ($questions_order === 'sorting'){
3473 $order_by = "ORDER BY question_order ASC";
3474 }
3475
3476 $limit = '';
3477 if ($total_questions){
3478 $limit = "LIMIT {$total_questions} ";
3479 }
3480
3481 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} {$order_by} {$limit} ");
3482
3483 return $questions;
3484 }
3485
3486 /**
3487 * @param $question_id
3488 * @param bool $rand
3489 *
3490 * @return array|bool|null|object
3491 *
3492 * Get answers list by quiz question
3493 *
3494 * @since v.1.0.0
3495 */
3496 public function get_answers_by_quiz_question($question_id, $rand = false){
3497 global $wpdb;
3498
3499 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} ;");
3500 if ( ! $question){
3501 return false;
3502 }
3503
3504 $order = " answer_order ASC ";
3505 if ($question->question_type === 'ordering'){
3506 $order = " RAND() ";
3507 }
3508
3509 if ($rand){
3510 $order = " RAND() ";
3511 }
3512
3513 $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} ");
3514 return $answers;
3515 }
3516
3517 /**
3518 * @param int $quiz_id
3519 * @param int $user_id
3520 *
3521 * @return array|bool|null|object
3522 *
3523 * Get all of the attempts by an user of a quiz
3524 *
3525 * @since v.1.0.0
3526 */
3527
3528 public function quiz_attempts($quiz_id = 0, $user_id = 0){
3529 global $wpdb;
3530
3531 $quiz_id = $this->get_post_id($quiz_id);
3532 $user_id = $this->get_user_id($user_id);
3533
3534 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE quiz_id = {$quiz_id} AND user_id = {$user_id} ");
3535
3536 if (is_array($attempts) && count($attempts)){
3537 return $attempts;
3538 }
3539
3540 return false;
3541 }
3542
3543 /**
3544 * @param int $quiz_id
3545 * @param int $user_id
3546 *
3547 * @return array|bool|null|object
3548 *
3549 * Get all ended attempts by an user of a quiz
3550 *
3551 * @since v.1.4.1
3552 */
3553 public function quiz_ended_attempts($quiz_id = 0, $user_id = 0){
3554 global $wpdb;
3555
3556 $quiz_id = $this->get_post_id($quiz_id);
3557 $user_id = $this->get_user_id($user_id);
3558
3559 $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' ");
3560
3561 if (is_array($attempts) && count($attempts)){
3562 return $attempts;
3563 }
3564
3565 return false;
3566 }
3567
3568
3569 /**
3570 * @param int $user_id
3571 *
3572 * @return array|bool|null|object
3573 *
3574 * Get attempts by an user
3575 *
3576 * @since v.1.0.0
3577 */
3578 public function get_all_quiz_attempts_by_user($user_id = 0){
3579 global $wpdb;
3580
3581 $user_id = $this->get_user_id($user_id);
3582 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE user_id = {$user_id} ORDER BY attempt_id DESC ");
3583
3584 if (is_array($attempts) && count($attempts)){
3585 return $attempts;
3586 }
3587
3588 return false;
3589 }
3590
3591 /**
3592 * @param string $search_term
3593 *
3594 * @return int
3595 *
3596 * Total number of quiz attempts
3597 *
3598 * @since v.1.0.0
3599 */
3600
3601 public function get_total_quiz_attempts($search_term = ''){
3602 global $wpdb;
3603
3604 if ($search_term){
3605 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3606 }
3607
3608 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3609 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3610 INNER JOIN {$wpdb->posts} quiz
3611 ON quiz_attempts.quiz_id = quiz.ID
3612 INNER JOIN {$wpdb->users}
3613 ON quiz_attempts.user_id = {$wpdb->users}.ID
3614 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3615 return (int) $count;
3616 }
3617
3618 /**
3619 * @param int $start
3620 * @param int $limit
3621 * @param string $search_term
3622 *
3623 * @return array|null|object
3624 *
3625 *
3626 * Get the all quiz attempts
3627 *
3628 * @since v.1.0.0
3629 */
3630 public function get_quiz_attempts($start = 0, $limit = 10, $search_term = '') {
3631 global $wpdb;
3632
3633 if ($search_term){
3634 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3635 }
3636
3637 $query = $wpdb->get_results("SELECT *
3638 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3639 INNER JOIN {$wpdb->posts} quiz
3640 ON quiz_attempts.quiz_id = quiz.ID
3641 INNER JOIN {$wpdb->users}
3642 ON quiz_attempts.user_id = {$wpdb->users}.ID
3643 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3644 ORDER BY quiz_attempts.attempt_id DESC
3645 LIMIT {$start},{$limit}; ");
3646 return $query;
3647 }
3648
3649 public function get_quiz_attempts_by_course_ids($start = 0, $limit = 10, $course_ids = array(), $search_term = '') {
3650 global $wpdb;
3651
3652 if ($search_term){
3653 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3654 }
3655
3656 $course_ids_in = implode($course_ids, ',');
3657 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3658 $search_term = $sql.$search_term;
3659
3660 $query = $wpdb->get_results("SELECT *
3661 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3662 INNER JOIN {$wpdb->posts} quiz
3663 ON quiz_attempts.quiz_id = quiz.ID
3664 INNER JOIN {$wpdb->users}
3665 ON quiz_attempts.user_id = {$wpdb->users}.ID
3666 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3667 ORDER BY quiz_attempts.attempt_id DESC
3668 LIMIT {$start},{$limit}; ");
3669 return $query;
3670 }
3671
3672 public function get_total_quiz_attempts_by_course_ids($course_ids = array(), $search_term = ''){
3673 global $wpdb;
3674
3675 if ($search_term){
3676 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3677 }
3678
3679 $course_ids_in = implode($course_ids, ',');
3680 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3681 $search_term = $sql.$search_term;
3682
3683 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3684 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3685 INNER JOIN {$wpdb->posts} quiz
3686 ON quiz_attempts.quiz_id = quiz.ID
3687 INNER JOIN {$wpdb->users}
3688 ON quiz_attempts.user_id = {$wpdb->users}.ID
3689 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3690 return (int) $count;
3691 }
3692
3693 /**
3694 * @param $attempt_id
3695 *
3696 * @return array|null|object
3697 *
3698 * Get quiz answers by attempt id
3699 *
3700 * @since v.1.0.0
3701 */
3702 public function get_quiz_answers_by_attempt_id($attempt_id){
3703 global $wpdb;
3704
3705 $results = $wpdb->get_results("SELECT answers.*, question.question_title, question.question_type
3706 FROM {$wpdb->prefix}tutor_quiz_attempt_answers answers
3707 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answers.question_id = question.question_id
3708 WHERE answers.quiz_attempt_id = {$attempt_id} ");
3709
3710 return $results;
3711 }
3712
3713 /**
3714 * @param $answer_id
3715 *
3716 * @return array|null|object
3717 *
3718 * Get single answer by answer_id
3719 *
3720 * @since v.1.0.0
3721 */
3722 public function get_answer_by_id($answer_id){
3723 global $wpdb;
3724
3725 if (is_array($answer_id)){
3726 $in_ids = implode(",", $answer_id);
3727 $sql = "answer.answer_id IN({$in_ids})";
3728 }else{
3729 $sql = "answer.answer_id = {$answer_id}";
3730 }
3731
3732 $answer = $wpdb->get_results("SELECT answer.*, question.question_title, question.question_type
3733 FROM {$wpdb->prefix}tutor_quiz_question_answers answer
3734 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answer.belongs_question_id = question.question_id
3735 WHERE 1=1 AND {$sql} ");
3736
3737 return $answer;
3738 }
3739
3740 /**
3741 * @param $ids
3742 *
3743 * @return array|bool|null|object
3744 *
3745 * Get quiz answers by ids
3746 *
3747 * @since v.1.0.0
3748 */
3749
3750 public function get_quiz_answers_by_ids($ids){
3751 $ids = (array) $ids;
3752
3753 if (!count($ids)){
3754 return false;
3755 }
3756
3757 $in_ids = implode(",", $ids);
3758
3759 global $wpdb;
3760 $query = $wpdb->get_results("SELECT
3761 comment_ID,
3762 comment_content
3763 FROM {$wpdb->comments}
3764 WHERE comment_type = 'quiz_answer_option' AND comment_ID IN({$in_ids}) ");
3765
3766 if (is_array($query) && count($query)){
3767 return $query;
3768 }
3769
3770 return false;
3771 }
3772
3773 /**
3774 * @param null $level
3775 *
3776 * @return mixed
3777 *
3778 * Get the users / students / course levels
3779 *
3780 * @since v.1.0.0
3781 */
3782
3783 public function course_levels($level = null){
3784 $levels = apply_filters('tutor_course_level', array(
3785 'all_levels' => __('All Levels', 'tutor'),
3786 'beginner' => __('Beginner', 'tutor'),
3787 'intermediate' => __('Intermediate', 'tutor'),
3788 'expert' => __('Expert', 'tutor'),
3789 ));
3790
3791 if ($level){
3792 if (isset($levels[$level])){
3793 return $levels[$level];
3794 }else{
3795 return '';
3796 }
3797 }
3798
3799 return $levels;
3800 }
3801
3802 /**
3803 * @return mixed|void
3804 *
3805 * Get user permalink for dashboard
3806 *
3807 * @since v.1.0.0
3808 */
3809 public function user_profile_permalinks(){
3810 $permalinks = array(
3811 'courses_taken' => __('Courses Taken', 'tutor'),
3812 );
3813
3814 $show_enrolled_course = tutor_utils()->get_option('show_courses_completed_by_student');
3815 $enable_show_reviews_wrote = tutor_utils()->get_option('students_own_review_show_at_profile');
3816
3817 if ($show_enrolled_course){
3818 $permalinks['enrolled_course'] = __('Enrolled Course', 'tutor');
3819 }
3820 if ($enable_show_reviews_wrote){
3821 $permalinks['reviews_wrote'] = __('Reviews Written', 'tutor');
3822 }
3823
3824
3825 return apply_filters('tutor_public_profile/permalinks', $permalinks);
3826 }
3827
3828 /**
3829 * @return bool|false|string
3830 *
3831 * Student registration form
3832 *
3833 * @since v.1.0.0
3834 */
3835 public function student_register_url(){
3836 $student_register_page = (int) $this->get_option('student_register_page');
3837
3838 if ($student_register_page){
3839 return get_the_permalink($student_register_page);
3840 }
3841 return false;
3842 }
3843 /**
3844 * @return bool|false|string
3845 *
3846 * Instructor registration form
3847 *
3848 * @since v.1.2.13
3849 */
3850 public function instructor_register_url(){
3851 $instructor_register_page = (int) $this->get_option('instructor_register_page');
3852
3853 if ($instructor_register_page){
3854 return get_the_permalink($instructor_register_page);
3855 }
3856 return false;
3857 }
3858
3859 /**
3860 * @return false|string
3861 *
3862 * Get frontend dashboard URL
3863 */
3864 public function tutor_dashboard_url($sub_url = ''){
3865 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3866 $page_id = apply_filters('tutor_dashboard_page_id', $page_id);
3867 return trailingslashit(get_the_permalink($page_id)).$sub_url;
3868 }
3869
3870 /**
3871 * Get the tutor dashboard page ID
3872 *
3873 * @return int
3874 *
3875 */
3876 public function dashboard_page_id(){
3877 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3878 $page_id = apply_filters('tutor_dashboard_page_id', $page_id);
3879 return $page_id;
3880 }
3881
3882 /**
3883 * @param int $course_id
3884 * @param int $user_id
3885 *
3886 * @return bool
3887 *
3888 * is_wishlisted();
3889 *
3890 * @since v.1.0.0
3891 */
3892 public function is_wishlisted($course_id = 0, $user_id = 0){
3893 $course_id = $this->get_post_id($course_id);
3894 $user_id = $this->get_user_id($user_id);
3895 if ( ! $user_id){
3896 return false;
3897 }
3898
3899 global $wpdb;
3900 $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} ;");
3901
3902 return $if_added_to_list;
3903 }
3904
3905 /**
3906 * @param int $user_id
3907 *
3908 * @return array|null|object
3909 *
3910 * Get the wish lists by an user
3911 *
3912 * @since v.1.0.0
3913 */
3914 public function get_wishlist($user_id = 0){
3915 $user_id = $this->get_user_id($user_id);
3916 global $wpdb;
3917
3918 $query = "SELECT $wpdb->posts.*
3919 FROM $wpdb->posts
3920 LEFT JOIN $wpdb->usermeta ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
3921 WHERE $wpdb->usermeta.meta_key = '_tutor_course_wishlist'
3922 AND $wpdb->usermeta.user_id = {$user_id}
3923 ORDER BY $wpdb->usermeta.umeta_id DESC ";
3924 $pageposts = $wpdb->get_results($query, OBJECT);
3925 return $pageposts;
3926 }
3927
3928 /**
3929 * @param int $limit
3930 *
3931 * @return array|null|object
3932 *
3933 * Getting popular courses
3934 *
3935 * @since v.1.0.0
3936 */
3937 public function most_popular_courses($limit = 10){
3938 global $wpdb;
3939
3940 $courses = $wpdb->get_results("
3941 SELECT COUNT(enrolled.ID) as total_enrolled,
3942 enrolled.post_parent as course_id,
3943 course.*
3944 from {$wpdb->posts} enrolled
3945 INNER JOIN {$wpdb->posts} course ON enrolled.post_parent = course.ID
3946 WHERE enrolled.post_type = 'tutor_enrolled' AND enrolled.post_status = 'completed'
3947
3948 GROUP BY course_id
3949 ORDER BY total_enrolled DESC LIMIT 0,{$limit} ;");
3950
3951 return $courses;
3952 }
3953
3954 /**
3955 * @param int $limit
3956 *
3957 * @return array|bool|null|object
3958 *
3959 * Get most rated courses lists
3960 *
3961 * @since v.1.0.0
3962 */
3963 public function most_rated_courses($limit = 10){
3964 global $wpdb;
3965
3966 $result = $wpdb->get_results("
3967 SELECT COUNT(comment_ID) AS total_rating,
3968 comment_ID,
3969 comment_post_ID,
3970 course.*
3971 FROM {$wpdb->comments}
3972 INNER JOIN {$wpdb->posts} course ON comment_post_ID = course.ID
3973 WHERE {$wpdb->comments}.comment_type = 'tutor_course_rating' AND {$wpdb->comments}.comment_approved = 'approved'
3974 GROUP BY comment_post_ID ORDER BY total_rating DESC LIMIT 0,{$limit}
3975 ;");
3976
3977 if (is_array($result) && count($result)){
3978 return $result;
3979 }
3980 return false;
3981 }
3982
3983 /**
3984 * @param null $addon_field
3985 *
3986 * @return bool
3987 *
3988 * Get Addon config
3989 *
3990 * @since v.1.0.0
3991 */
3992 public function get_addon_config($addon_field = null){
3993 if ( ! $addon_field){
3994 return false;
3995 }
3996
3997 $addonsConfig = maybe_unserialize(get_option('tutor_addons_config'));
3998
3999 if (isset($addonsConfig[$addon_field])){
4000 return $addonsConfig[$addon_field];
4001 }
4002
4003 return false;
4004 }
4005
4006 /**
4007 * @return array|false|string
4008 *
4009 * Get the IP from visitor
4010 *
4011 * @since v.1.0.0
4012 */
4013 function get_ip() {
4014 $ipaddress = '';
4015 if (getenv('HTTP_CLIENT_IP'))
4016 $ipaddress = getenv('HTTP_CLIENT_IP');
4017 else if(getenv('HTTP_X_FORWARDED_FOR'))
4018 $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
4019 else if(getenv('HTTP_X_FORWARDED'))
4020 $ipaddress = getenv('HTTP_X_FORWARDED');
4021 else if(getenv('HTTP_FORWARDED_FOR'))
4022 $ipaddress = getenv('HTTP_FORWARDED_FOR');
4023 else if(getenv('HTTP_FORWARDED'))
4024 $ipaddress = getenv('HTTP_FORWARDED');
4025 else if(getenv('REMOTE_ADDR'))
4026 $ipaddress = getenv('REMOTE_ADDR');
4027 else
4028 $ipaddress = 'UNKNOWN';
4029 return $ipaddress;
4030 }
4031
4032 /**
4033 * @return array $array
4034 *
4035 * Get the social icons
4036 *
4037 * @since v.1.0.4
4038 */
4039
4040 public function tutor_social_share_icons(){
4041 $icons = array(
4042 'facebook' => array('share_class' => 's_facebook', 'icon_html' => '<i class="tutor-icon-facebook"></i>' ),
4043 'twitter' => array('share_class' => 's_twitter', 'icon_html' => '<i class="tutor-icon-twitter"></i>' ),
4044 'linkedin' => array('share_class' => 's_linkedin', 'icon_html' => '<i class="tutor-icon-linkedin"></i>' ),
4045 'tumblr' => array('share_class' => 's_tumblr', 'icon_html' => '<i class="tutor-icon-tumblr"></i>' ),
4046 );
4047
4048 return apply_filters('tutor_social_share_icons', $icons);
4049 }
4050
4051 /**
4052 * @return array $array
4053 *
4054 * Get the user social icons
4055 *
4056 * @since v.1.3.7
4057 */
4058
4059 public function tutor_user_social_icons(){
4060 $icons = array(
4061 '_tutor_profile_website' => array(
4062 'label' => __('Website URL', 'tutor'),
4063 'placeholder' => 'https://example.com/',
4064 'icon_classes' => 'tutor-icon-earth'
4065 ),
4066 '_tutor_profile_github' => array(
4067 'label' => __('Github URL', 'tutor'),
4068 'placeholder' => 'https://github.com/username',
4069 'icon_classes' => 'tutor-icon-github-logo'
4070 ),
4071 '_tutor_profile_facebook' => array(
4072 'label' => __('Facebook URL', 'tutor'),
4073 'placeholder' => 'https://facebook.com/username',
4074 'icon_classes' => 'tutor-icon-facebook'
4075 ),
4076 '_tutor_profile_twitter' => array(
4077 'label' => __('Twitter URL', 'tutor'),
4078 'placeholder' => 'https://twitter.com/username',
4079 'icon_classes' => 'tutor-icon-twitter'
4080 ),
4081 '_tutor_profile_linkedin' => array(
4082 'label' => __('Linkedin URL', 'tutor'),
4083 'placeholder' => 'https://linkedin.com/username',
4084 'icon_classes' => 'tutor-icon-linkedin'
4085 ),
4086 );
4087
4088 return apply_filters('tutor_user_social_icons', $icons);
4089 }
4090
4091 /**
4092 * @param array $array
4093 *
4094 * @return bool
4095 *
4096 * count method with check is_array
4097 *
4098 * @since v.1.0.4
4099 */
4100 public function count($array = array()){
4101 if (is_array($array) && count($array)){
4102 return count($array);
4103 }
4104 return false;
4105 }
4106
4107 /**
4108 * @return array
4109 *
4110 * get all screen ids
4111 *
4112 * @since v.1.1.2
4113 */
4114 public function tutor_get_screen_ids(){
4115 $screen_ids = array(
4116 "edit-course",
4117 "course",
4118 "edit-course-category",
4119 "edit-course-tag",
4120 "tutor-lms_page_tutor-students",
4121 "tutor-lms_page_tutor-instructors",
4122 "tutor-lms_page_question_answer",
4123 "tutor-lms_page_tutor_quiz_attempts",
4124 "tutor-lms_page_tutor-addons",
4125 "tutor-lms_page_tutor-status",
4126 "tutor-lms_page_tutor_report",
4127 "tutor-lms_page_tutor_settings",
4128 "tutor-lms_page_tutor_emails",
4129 );
4130
4131 return apply_filters('tutor_get_screen_ids', $screen_ids);
4132 }
4133
4134
4135 /**
4136 * @return mixed
4137 *
4138 * get earning transaction completed status
4139 *
4140 * @since v.1.1.2
4141 */
4142 public function get_earnings_completed_statuses(){
4143 return apply_filters(
4144 'tutor_get_earnings_completed_statuses',
4145 array (
4146 'wc-completed',
4147 'completed',
4148 'complete',
4149 )
4150 );
4151 }
4152
4153 /**
4154 * @param int $user_id
4155 * @param array $date_filter
4156 *
4157 * @return array|null|object
4158 *
4159 * Get all time earning sum for an instructor with all commission
4160 *
4161 * @since v.1.1.2
4162 */
4163
4164 public function get_earning_sum($user_id = 0, $date_filter = array()){
4165 global $wpdb;
4166
4167 $user_id = $this->get_user_id($user_id);
4168 $date_query = '';
4169 if ($this->count($date_filter)){
4170 extract($date_filter);
4171
4172 if ( ! empty($dataFor)){
4173 if ($dataFor === 'yearly'){
4174 if (empty($year)){
4175 $year = date('Y');
4176 }
4177 $date_query = "AND YEAR(created_at) = {$year} ";
4178 }
4179 }else{
4180 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
4181 }
4182 }
4183
4184 $complete_status = tutor_utils()->get_earnings_completed_statuses();
4185 $complete_status = "'".implode("','", $complete_status)."'";
4186
4187 $earning_sum = $wpdb->get_row("SELECT SUM(course_price_total) as course_price_total,
4188 SUM(course_price_grand_total) as course_price_grand_total,
4189 SUM(instructor_amount) as instructor_amount,
4190 (SELECT SUM(amount) FROM {$wpdb->prefix}tutor_withdraws WHERE user_id = {$user_id} AND status != 'rejected' ) as
4191 withdraws_amount,
4192 SUM(admin_amount) as admin_amount,
4193 SUM(deduct_fees_amount) as deduct_fees_amount
4194 FROM {$wpdb->prefix}tutor_earnings
4195 WHERE user_id = {$user_id} AND order_status IN({$complete_status}) {$date_query} ");
4196
4197 //TODO: need to check
4198 // (SUM(instructor_amount) - (SELECT withdraws_amount) ) as balance,
4199
4200
4201 if ( $earning_sum->course_price_total){
4202 $earning_sum->balance = $earning_sum->instructor_amount - $earning_sum->withdraws_amount;
4203 }else{
4204
4205 $earning_sum = (object) array(
4206 'course_price_total' => 0,
4207 'course_price_grand_total' => 0,
4208 'instructor_amount' => 0,
4209 'withdraws_amount' => 0,
4210 'balance' => 0,
4211 'admin_amount' => 0,
4212 'deduct_fees_amount' => 0,
4213 );
4214 }
4215
4216 return $earning_sum;
4217 }
4218
4219 /**
4220 * @param int $user_id
4221 * @param array $date_filter
4222 *
4223 * @return array|null|object
4224 *
4225 * Get earning statements
4226 *
4227 * @since v.1.1.2
4228 */
4229 public function get_earning_statements($user_id = 0, $filter_data = array()){
4230 global $wpdb;
4231
4232 $user_sql = "";
4233 if ($user_id){
4234 $user_sql = " AND user_id='{$user_id}' ";
4235 }
4236
4237 $date_query = '';
4238 $query_by_status = '';
4239 $pagination_query = '';
4240
4241 /**
4242 * Query by Date Filter
4243 */
4244 if ($this->count($filter_data)){
4245 extract($filter_data);
4246
4247 if ( ! empty($dataFor)){
4248 if ($dataFor === 'yearly'){
4249 if (empty($year)){
4250 $year = date('Y');
4251 }
4252 $date_query = "AND YEAR(created_at) = {$year} ";
4253 }
4254 }else{
4255 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
4256 }
4257
4258 /**
4259 * Query by order status related to this earning transaction
4260 */
4261 if ( ! empty($statuses)) {
4262 if ( $this->count( $statuses ) ) {
4263 $status = "'" . implode( "','", $statuses ) . "'";
4264 $query_by_status = "AND order_status IN({$status})";
4265 } elseif ( $statuses === 'completed' ) {
4266
4267 $get_earnings_completed_statuses = $this->get_earnings_completed_statuses();
4268 if ( $this->count( $get_earnings_completed_statuses ) ) {
4269 $status = "'" . implode( "','", $get_earnings_completed_statuses ) . "'";
4270 $query_by_status = "AND order_status IN({$status})";
4271 }
4272 }
4273 }
4274
4275 if ( ! empty($per_page)){
4276 $offset = (int) ! empty($offset) ? $offset : 0;
4277
4278 $pagination_query = " LIMIT {$offset}, {$per_page} ";
4279
4280 }
4281
4282
4283 }
4284
4285 $query = $wpdb->get_results("SELECT earning_tbl.*, course.post_title as course_title
4286 FROM {$wpdb->prefix}tutor_earnings earning_tbl
4287 LEFT JOIN {$wpdb->posts} course ON earning_tbl.course_id = course.ID
4288 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC {$pagination_query} ");
4289
4290
4291 $query_count = (int) $wpdb->get_var("SELECT COUNT(earning_tbl.earning_id)
4292 FROM {$wpdb->prefix}tutor_earnings earning_tbl
4293 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC ");
4294
4295 return (object) array(
4296 'count' => $query_count,
4297 'results' => $query,
4298 );
4299 }
4300
4301 /**
4302 * @param int $price
4303 *
4304 * @return int|string
4305 *
4306 * Get the price format
4307 *
4308 * @since v.1.1.2
4309 */
4310
4311 public function tutor_price($price = 0){
4312 if (function_exists('wc_price')){
4313 return wc_price($price);
4314 }elseif (function_exists('edd_currency_filter')){
4315 return edd_currency_filter(edd_format_amount($price));
4316 }else{
4317 return number_format_i18n($price);
4318 }
4319 }
4320
4321 /**
4322 * @return mixed
4323 *
4324 * Get currency symbol from activated plugin, WC,EDD
4325 *
4326 * @since v.1.3.4
4327 */
4328
4329 public function currency_symbol(){
4330 $enable_tutor_edd = tutor_utils()->get_option('enable_tutor_edd');
4331 $monetize_by = $this->get_option('monetize_by');
4332
4333 $symbol = '&#36;';
4334 if ($enable_tutor_edd && function_exists('edd_currency_symbol')){
4335 $symbol = edd_currency_symbol();
4336 }
4337
4338 if ($monetize_by === 'wc' && function_exists('get_woocommerce_currency_symbol') ){
4339 $symbol = get_woocommerce_currency_symbol();
4340 }
4341
4342 return apply_filters('get_tutor_currency_symbol', $symbol);
4343 }
4344
4345 /**
4346 * @param int $user_id
4347 *
4348 * @return bool|mixed
4349 *
4350 * Get withdraw method for a specific
4351 */
4352 public function get_user_withdraw_method($user_id = 0){
4353 $user_id = $this->get_user_id($user_id);
4354
4355 $account = get_user_meta($user_id, '_tutor_withdraw_method_data', true);
4356 if ($account){
4357 return maybe_unserialize($account);
4358 }
4359
4360 return false;
4361 }
4362
4363 /**
4364 * @param int $user_id
4365 * @param array $filter
4366 *
4367 * get withdrawal history
4368 *
4369 * @return object
4370 */
4371 public function get_withdrawals_history($user_id = 0, $filter = array()){
4372 global $wpdb;
4373
4374 $filter = (array) $filter;
4375 extract($filter);
4376
4377 $query_by_status_sql = "";
4378 $query_by_user_sql = "";
4379 $query_by_pagination = "";
4380
4381 if ( ! empty($status)){
4382 $status = (array) $status;
4383 $status = "'".implode("','", $status)."'";
4384
4385 $query_by_status_sql = " AND status IN({$status}) ";
4386 }
4387
4388 if ( ! empty($per_page)){
4389 if ( empty($start))
4390 $start = 0;
4391
4392 $query_by_pagination = " LIMIT {$start}, {$per_page} ";
4393 }
4394
4395 if ($user_id){
4396 $query_by_user_sql = " AND user_id = {$user_id} ";
4397 }
4398
4399
4400 $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} ");
4401
4402 $results = $wpdb->get_results("SELECT withdraw_tbl.*,
4403 user_tbl.display_name as user_name,
4404 user_tbl.user_email
4405 FROM {$wpdb->prefix}tutor_withdraws withdraw_tbl
4406 INNER JOIN {$wpdb->users} user_tbl ON withdraw_tbl.user_id = user_tbl.ID
4407 WHERE 1=1
4408 {$query_by_user_sql}
4409 {$query_by_status_sql} ORDER BY
4410 created_at DESC {$query_by_pagination} ");
4411
4412 $withdraw_history = array(
4413 'count' => 0,
4414 'results' => null,
4415 );
4416
4417 if ($count){
4418 $withdraw_history['count'] = $count;
4419 }
4420
4421 if (tutor_utils()->count($results)){
4422 $withdraw_history['results'] = $results;
4423 }
4424 return (object) $withdraw_history;
4425
4426 }
4427
4428 /**
4429 * @param int $instructor_id
4430 *
4431 * Add Instructor role to any user by user iD
4432 */
4433 public function add_instructor_role($instructor_id = 0){
4434 if ( ! $instructor_id){
4435 return;
4436 }
4437 do_action('tutor_before_approved_instructor', $instructor_id);
4438
4439 update_user_meta($instructor_id, '_tutor_instructor_status', 'approved');
4440 update_user_meta($instructor_id, '_tutor_instructor_approved', time());
4441
4442 $instructor = new \WP_User($instructor_id);
4443 $instructor->add_role(tutor()->instructor_role);
4444
4445 do_action('tutor_after_approved_instructor', $instructor_id);
4446 }
4447
4448 /**
4449 * @param int $instructor_id
4450 *
4451 * Remove instructor role by instructor id
4452 */
4453 public function remove_instructor_role($instructor_id = 0){
4454 if ( ! $instructor_id){
4455 return;
4456 }
4457
4458 do_action('tutor_before_blocked_instructor', $instructor_id);
4459 update_user_meta($instructor_id, '_tutor_instructor_status', 'blocked');
4460
4461 $instructor = new \WP_User($instructor_id);
4462 $instructor->remove_role(tutor()->instructor_role);
4463 do_action('tutor_after_blocked_instructor', $instructor_id);
4464 }
4465
4466 /**
4467 * @param string $msg
4468 * @param string $name
4469 *
4470 * Set Flash Message to view in next action / route
4471 */
4472 public function set_flash_msg($msg = '', $name = 'success'){
4473 global $wp_filesystem;
4474 if ( ! $wp_filesystem ) {
4475 require_once( ABSPATH . 'wp-admin/includes/file.php' );
4476 }
4477
4478 $filename = "tutor_flash_msg_{$name}.txt";
4479 $upload_dir = wp_upload_dir();
4480 $dir = trailingslashit($upload_dir['basedir']) . 'tutor/';
4481
4482 WP_Filesystem( false, $upload_dir['basedir'], true );
4483
4484 if( ! $wp_filesystem->is_dir( $dir ) ) {
4485 $wp_filesystem->mkdir( $dir );
4486 }
4487 $wp_filesystem->put_contents( $dir . $filename, $msg );
4488 }
4489
4490 /**
4491 * @param null $name
4492 *
4493 * @return mixed|string|void
4494 *
4495 * Get Flash Message
4496 */
4497 public function get_flash_msg($name = null){
4498 if ( ! $name){
4499 return '';
4500 }
4501
4502 $upload_dir = wp_get_upload_dir();
4503 $upload_dir = trailingslashit($upload_dir['basedir']);
4504 $msg_name = 'tutor_flash_msg_'.$name;
4505
4506 $msg = '';
4507 $flash_msg_file_name = $upload_dir."tutor/{$msg_name}.txt";
4508 if (file_exists($flash_msg_file_name)){
4509 $msg = file_get_contents($flash_msg_file_name);
4510 unlink($flash_msg_file_name);
4511 }
4512
4513 return apply_filters('tutor_get_flash_msg', $msg, $name);
4514 }
4515
4516 /**
4517 * @param int $user_id
4518 *
4519 * @return array|null|object
4520 *
4521 * Get purchase history by customer id
4522 */
4523
4524 public function get_orders_by_user_id($user_id = 0){
4525 global $wpdb;
4526
4527 $user_id = $this->get_user_id();
4528
4529 $query = $wpdb->get_results("SELECT {$wpdb->posts}.* FROM {$wpdb->posts}
4530 INNER JOIN {$wpdb->postmeta} customer ON ID = customer.post_id AND customer.meta_key = '_customer_user'
4531 INNER JOIN {$wpdb->postmeta} tutor_order ON ID = tutor_order.post_id AND tutor_order.meta_key = '_is_tutor_order_for_course'
4532 where post_type = 'shop_order' AND customer.meta_value = {$user_id} ");
4533 return $query;
4534 }
4535
4536 /**
4537 * @param null $status
4538 *
4539 * @return string
4540 *
4541 * Get status contact formatted for order
4542 *
4543 * @since v.1.3.1
4544 */
4545 public function order_status_context($status = null){
4546 $status = str_replace('wc-', '', $status);
4547 $status_name = ucwords(str_replace('-', ' ', $status));
4548
4549 return "<span class='label-order-status label-status-{$status}'>$status_name</span>";
4550 }
4551
4552 public function get_course_id_by_assignment($assignment_id = 0){
4553 $assignment_id = $this->get_post_id($assignment_id);
4554 return get_post_meta($assignment_id, '_tutor_course_id_for_assignments', true);
4555 }
4556
4557 /**
4558 * @param int $assignment_id
4559 * @param string $option_key
4560 * @param bool $default
4561 *
4562 * @return array|bool|mixed
4563 *
4564 * Get assignment options
4565 *
4566 * @since v.1.3.3
4567 */
4568 public function get_assignment_option($assignment_id = 0, $option_key = '', $default = false){
4569 $assignment_id = $this->get_post_id($assignment_id);
4570 $get_option_meta = maybe_unserialize(get_post_meta($assignment_id, 'assignment_option', true));
4571
4572 if ( ! $option_key && ! empty($get_option_meta)) {
4573 return $get_option_meta;
4574 }
4575
4576 $value = $this->avalue_dot( $option_key, $get_option_meta );
4577 if ( $value ) {
4578 return $value;
4579 }
4580 return $default;
4581 }
4582
4583 /**
4584 * @param int $assignment_id
4585 * @param int $user_id
4586 *
4587 * @return int
4588 *
4589 * Is running any assignment submitting
4590 *
4591 * @since v.1.3.3
4592 */
4593 public function is_assignment_submitting($assignment_id = 0, $user_id = 0){
4594 global $wpdb;
4595
4596 $assignment_id = $this->get_post_id($assignment_id);
4597 $user_id = $this->get_user_id($user_id);
4598
4599 $is_running_submit = (int) $wpdb->get_var("SELECT comment_ID FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitting' AND user_id = {$user_id} AND comment_post_ID =
4600 {$assignment_id} ");
4601
4602 return $is_running_submit;
4603 }
4604
4605 /**
4606 * @param int $assignment_id
4607 * @param int $user_id
4608 *
4609 * @return array|null|object
4610 *
4611 * Determine if any assignment submitted by user to a assignment
4612 *
4613 * @since v.1.3.3
4614 */
4615
4616 public function is_assignment_submitted($assignment_id = 0, $user_id = 0){
4617 global $wpdb;
4618
4619 $assignment_id = $this->get_post_id($assignment_id);
4620 $user_id = $this->get_user_id($user_id);
4621
4622 $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} ");
4623
4624 return $has_submitted;
4625 }
4626
4627 public function get_assignment_submit_info($assignment_submitted_id = 0){
4628 global $wpdb;
4629
4630 $assignment_submitted_id = $this->get_post_id($assignment_submitted_id);
4631 $submitted_info = $wpdb->get_row("SELECT * FROM {$wpdb->comments} WHERE comment_ID = {$assignment_submitted_id} AND comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4632
4633 return $submitted_info;
4634 }
4635
4636 public function get_total_assignments(){
4637 global $wpdb;
4638
4639 $count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4640
4641 return (int) $count;
4642 }
4643
4644 public function get_assignments(){
4645 global $wpdb;
4646
4647 $results = $wpdb->get_results("SELECT * FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4648
4649 return $results;
4650 }
4651
4652 /**
4653 * @param int $user_id
4654 *
4655 * @return array
4656 *
4657 * Get all courses id assigned or owned by an instructors
4658 *
4659 * @since v.1.3.3
4660 */
4661 public function get_assigned_courses_ids_by_instructors($user_id = 0){
4662 global $wpdb;
4663 $user_id = $this->get_user_id($user_id);
4664
4665 $course_post_type = tutor()->course_post_type;
4666 $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 ; ");
4667
4668 /*
4669 $author_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} where post_type = '{$course_post_type}' AND post_author = {$user_id}");
4670 $final_course_ids = array_merge($get_assigned_courses_ids, $author_ids);
4671 $final_course_ids = array_unique($final_course_ids);
4672 */
4673
4674 return $get_assigned_courses_ids;
4675 }
4676
4677 /**
4678 * @param int $parent
4679 *
4680 * @return array
4681 *
4682 * Get course categories in array with child
4683 *
4684 * @since v.1.3.4
4685 */
4686
4687 public function get_course_categories($parent = 0 ){
4688 $args = apply_filters('tutor_get_course_categories_args', array(
4689 'taxonomy' => 'course-category',
4690 'hide_empty' => false,
4691 'parent' => $parent,
4692 ));
4693
4694 $terms = get_terms($args);
4695
4696 $children = array();
4697 foreach ( $terms as $term ){
4698 $term->children = $this->get_course_categories( $term->term_id );
4699 $children[ $term->term_id ] = $term;
4700 }
4701
4702 return $children;
4703 }
4704
4705 /**
4706 * @param int $parent_id
4707 *
4708 * @return array|int|\WP_Error
4709 *
4710 * Get course categories terms in raw array
4711 *
4712 * @since v.1.3.5
4713 */
4714 public function get_course_categories_term($parent_id = 0){
4715 $args = apply_filters('tutor_get_course_categories_terms_args', array(
4716 'taxonomy' => 'course-category',
4717 'parent' => $parent_id,
4718 'hide_empty' => false,
4719 ));
4720
4721 $terms = get_terms($args);
4722
4723 return $terms;
4724 }
4725
4726 /**
4727 * @return mixed
4728 *
4729 * Get back url from the request
4730 * @since v.1.3.4
4731 */
4732 public function referer(){
4733 $url = $this->array_get('_wp_http_referer', $_REQUEST);
4734 return apply_filters('tutor_referer_url', $url);
4735 }
4736
4737 /**
4738 * @param int $course_id
4739 *
4740 * @return false|string
4741 *
4742 * Get the frontend dashboard course edit page
4743 *
4744 * @since v.1.3.4
4745 */
4746 public function course_edit_link($course_id = 0){
4747 $course_id = $this->get_post_id($course_id);
4748
4749 $url = admin_url("post.php?post={$course_id}&action=edit");
4750 if (tutor()->has_pro){
4751 $url = $this->tutor_dashboard_url("create-course/?course_ID=".$course_id);
4752 }
4753
4754 return $url;
4755 }
4756
4757 public function get_assignments_by_instructor($instructor_id = 0, $filter_data = array()){
4758 global $wpdb;
4759
4760 $instructor_id = $this->get_user_id($instructor_id);
4761 $course_ids = tutor_utils()->get_assigned_courses_ids_by_instructors($instructor_id);
4762
4763 //$new_course_ids = tutils()->get_courses_by_instructor();
4764
4765 //die($this->print_view($course_ids));
4766
4767 $in_course_ids = implode("','", $course_ids);
4768
4769 $count = (int) $wpdb->get_var("SELECT COUNT(ID) FROM {$wpdb->postmeta} post_meta
4770 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4771 where post_type = 'tutor_assignments' AND post_meta.meta_value IN('$in_course_ids') ORDER BY ID DESC ");
4772
4773 $pagination_query = '';
4774 if ($this->count($filter_data)) {
4775 extract( $filter_data );
4776
4777 if ( ! empty( $per_page ) ) {
4778 $offset = (int) ! empty( $offset ) ? $offset : 0;
4779 $pagination_query = " LIMIT {$offset}, {$per_page} ";
4780 }
4781 }
4782
4783 $query = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} post_meta
4784 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4785 where post_type = 'tutor_assignments' AND post_meta.meta_value IN('$in_course_ids') ORDER BY ID DESC {$pagination_query} ");
4786
4787 return (object) array('count' => $count, 'results' => $query);
4788 }
4789
4790 /**
4791 * @param int $course_id
4792 *
4793 * @return bool|object
4794 *
4795 * Get assignments by course id
4796 */
4797 public function get_assignments_by_course($course_id = 0){
4798 if ( ! $course_id){
4799 return false;
4800 }
4801 global $wpdb;
4802
4803 $count = (int) $wpdb->get_var("SELECT COUNT(ID) FROM {$wpdb->postmeta} post_meta
4804 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4805 where post_type = 'tutor_assignments' AND post_meta.meta_value = {$course_id} ORDER BY ID DESC ");
4806
4807 $query = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} post_meta
4808 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4809 where post_type = 'tutor_assignments' AND post_meta.meta_value = {$course_id} ORDER BY ID DESC");
4810
4811 return (object) array('count' => $count, 'results' => $query);
4812 }
4813
4814 /**
4815 * @return bool
4816 *
4817 * Determine if script debug
4818 *
4819 * @since v.1.3.4
4820 */
4821 public function is_script_debug(){
4822 return ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
4823 }
4824
4825 /**
4826 * Check lesson edit access by instructor
4827 *
4828 * @since v.1.4.0
4829 */
4830
4831 public function has_lesson_edit_access($lesson_id = 0, $instructor_id = 0){
4832 $lesson_id = $this->get_post_id($lesson_id);
4833 $instructor_id = $this->get_user_id($instructor_id);
4834
4835 if (user_can($instructor_id, tutor()->instructor_role)){
4836 $permitted_course_ids = tutils()->get_assigned_courses_ids_by_instructors();
4837 $course_id = tutils()->get_course_id_by_lesson($lesson_id);
4838
4839 if (in_array($course_id, $permitted_course_ids)){
4840 return true;
4841 }
4842 }
4843
4844 return false;
4845 }
4846
4847
4848 /**
4849 * Get total Enrolments
4850 * @since v.1.4.0
4851 */
4852
4853 public function get_total_enrolments($search_term = ''){
4854 global $wpdb;
4855
4856 $search_sql = '';
4857 if ($search_term){
4858 $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}%' ) ";
4859 }
4860
4861 $count = $wpdb->get_var("SELECT COUNT(enrol.ID)
4862 FROM {$wpdb->posts} enrol
4863 INNER JOIN {$wpdb->posts} course ON enrol.post_parent = course.ID
4864 INNER JOIN {$wpdb->users} student ON enrol.post_author = student.ID
4865 WHERE enrol.post_type = 'tutor_enrolled' {$search_sql} ");
4866 return (int) $count;
4867 }
4868
4869 public function get_enrolments($start = 0, $limit = 10, $search_term = ''){
4870 global $wpdb;
4871
4872 $search_sql = '';
4873 if ($search_term){
4874 $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}%' ) ";
4875 }
4876
4877 $enrolments = $wpdb->get_results("SELECT
4878 enrol.ID as enrol_id,
4879 enrol.post_author as student_id,
4880 enrol.post_date as enrol_date,
4881 enrol.post_title as enrol_title,
4882 enrol.post_status as status,
4883 enrol.post_parent as course_id,
4884
4885 course.post_title as course_title,
4886
4887 student.user_nicename,
4888 student.user_email,
4889 student.display_name
4890
4891 FROM {$wpdb->posts} enrol
4892
4893 INNER JOIN {$wpdb->posts} course ON enrol.post_parent = course.ID
4894 INNER JOIN {$wpdb->users} student ON enrol.post_author = student.ID
4895
4896 WHERE enrol.post_type = 'tutor_enrolled' {$search_sql}
4897 ORDER BY enrol_id DESC
4898 LIMIT {$start}, {$limit} ");
4899
4900 return $enrolments;
4901 }
4902
4903 /**
4904 * @param int $post_id
4905 *
4906 * @return false|string
4907 *
4908 * @since v.1.4.0
4909 */
4910
4911 public function get_current_url($post_id = 0){
4912 $page_id = $this->get_post_id($post_id);
4913
4914 if ($page_id){
4915 return get_the_permalink($page_id);
4916 }else{
4917 global $wp;
4918 $current_url = home_url( $wp->request );
4919
4920 return $current_url;
4921 }
4922 }
4923
4924
4925 /**
4926 * @param int $rating_id
4927 *
4928 * @return object
4929 *
4930 * Get rating by rating id|comment_ID
4931 *
4932 * @since v.1.4.0
4933 */
4934
4935 public function get_rating_by_id($rating_id = 0){
4936 $ratings = array(
4937 'rating' => 0,
4938 'review' => '',
4939 );
4940
4941 global $wpdb;
4942
4943 $rating = $wpdb->get_row("select meta_value as rating, comment_content as review from {$wpdb->comments}
4944 INNER JOIN {$wpdb->commentmeta}
4945 ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
4946 WHERE {$wpdb->comments}.comment_ID = {$rating_id} ;"
4947 );
4948
4949 if ($rating){
4950 $rating_format = number_format($rating->rating, 2);
4951
4952 $ratings = array(
4953 'rating' => $rating_format,
4954 'review' => $rating->review,
4955 );
4956 }
4957 return (object) $ratings;
4958 }
4959
4960 /**
4961 * @param int $course_id
4962 * @param null $key
4963 * @param bool $default
4964 *
4965 * @return array|bool|mixed
4966 *
4967 * Get course settings by course ID
4968 */
4969 public function get_course_settings($course_id = 0, $key = null, $default = false){
4970 $course_id = $this->get_post_id($course_id);
4971 $settings_meta = get_post_meta($course_id, '_tutor_course_settings', true);
4972 $settings = (array) maybe_unserialize($settings_meta);
4973
4974 return $this->array_get($key, $settings, $default);
4975 }
4976
4977 /**
4978 * @param int $lesson_id
4979 * @param null $key
4980 * @param bool $default
4981 *
4982 * @return array|bool|mixed
4983 *
4984 * Get Lesson content drip settings
4985 *
4986 * @since v.1.4.0
4987 */
4988 public function get_item_content_drip_settings($lesson_id = 0, $key = null, $default = false){
4989 $lesson_id = $this->get_post_id($lesson_id);
4990 $settings_meta = get_post_meta($lesson_id, '_content_drip_settings', true);
4991 $settings = (array) maybe_unserialize($settings_meta);
4992
4993 return $this->array_get($key, $settings, $default);
4994 }
4995
4996
4997 /**
4998 * @param null $post
4999 *
5000 * @return bool
5001 *
5002 * Get previous ID
5003 */
5004 public function get_course_previous_content_id($post = null){
5005 $current_item = get_post($post);
5006 $course_id = $this->get_course_id_by_content($current_item);
5007
5008 $topics = tutor_utils()->get_topics($course_id);
5009
5010 $contents = array();
5011 if ($topics->have_posts()) {
5012 while ( $topics->have_posts() ) {
5013 $topics->the_post();
5014 $topic_id = get_the_ID();
5015 $lessons = tutor_utils()->get_course_contents_by_topic($topic_id, -1);
5016 if ($lessons->have_posts()) {
5017 while ( $lessons->have_posts() ) {
5018 $lessons->the_post();
5019 global $post;
5020 $contents[] = $post;
5021 }
5022 }
5023
5024 }
5025 }
5026
5027 if (tutils()->count($contents)){
5028 foreach ($contents as $key => $content){
5029 if ($current_item->ID == $content->ID){
5030 if ( ! empty($contents[$key-1]->ID)){
5031 return $contents[$key-1]->ID;
5032 }
5033 }
5034 }
5035 }
5036
5037 /*
5038
5039 if ($post->menu_order > 0){
5040
5041 $contents = $wpdb->get_results("SELECT items.* FROM {$wpdb->posts} topic
5042 INNER JOIN {$wpdb->posts} items ON topic.ID = items.post_parent
5043 WHERE topic.post_parent = {$course_id} AND items.post_status = 'publish' order by topic.menu_order ASC, items.menu_order ASC;");
5044
5045
5046
5047 if (tutils()->count($contents)){
5048 foreach ($contents as $key => $content){
5049 if ($post->ID == $content->ID){
5050 if ( ! empty($contents[$key-1]->ID)){
5051 //return $contents[$key-1]->ID;
5052 }
5053 }
5054 }
5055 }
5056
5057 die(print_r($contents));
5058
5059 }else{
5060 $previous = $wpdb->get_row("SELECT items.* FROM {$wpdb->posts} topic
5061 INNER JOIN {$wpdb->posts} items ON topic.ID = items.post_parent
5062 WHERE topic.post_parent = {$course_id}
5063 AND items.post_status = 'publish'
5064 AND items.ID < {$post->ID} ORDER BY ID DESC LIMIT 1; ");
5065
5066 if ( ! empty($previous->ID)){
5067 return $previous->ID;
5068 }
5069 }*/
5070
5071 return false;
5072 }
5073
5074 /**
5075 * @param null $post
5076 *
5077 * @return int
5078 *
5079 * Get Course iD by any course content
5080 */
5081 public function get_course_id_by_content($post = null){
5082 global $wpdb;
5083 $post = get_post($post);
5084 $course_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$post->post_parent} AND post_type = 'topics'");
5085
5086 return (int) $course_id;
5087 }
5088
5089 /**
5090 * @param int $course_id
5091 *
5092 * @return array|null|object
5093 *
5094 * Get Course contents by Course ID
5095 *
5096 * @since v.1.4.1
5097 */
5098 public function get_course_contents_by_id($course_id = 0){
5099 global $wpdb;
5100
5101 $course_id = $this->get_post_id($course_id);
5102
5103 $contents = $wpdb->get_results("SELECT items.* FROM {$wpdb->posts} topic
5104 INNER JOIN {$wpdb->posts} items ON topic.ID = items.post_parent
5105 WHERE topic.post_parent = {$course_id} AND items.post_status = 'publish' order by topic.menu_order ASC, items.menu_order ASC;");
5106
5107 return $contents;
5108 }
5109
5110
5111 }