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