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