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