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