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