PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.3.9
Tutor LMS – eLearning and online course solution v1.3.9
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Utils.php
tutor / classes Last commit date
Addons.php 6 years ago Admin.php 6 years ago Ajax.php 6 years ago Assets.php 6 years ago Course.php 6 years ago Course_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
4726 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 $total_questions = (int) $attempt->total_questions;
3406 if ( ! $attempt){
3407 return false;
3408 }
3409
3410 $limit = '';
3411 if ($total_questions){
3412 $limit = "LIMIT {$total_questions} ";
3413 }
3414
3415 $questions = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ORDER BY RAND() {$limit} ");
3416
3417 return $questions;
3418 }
3419
3420 /**
3421 * @param $question_id
3422 * @param bool $rand
3423 *
3424 * @return array|bool|null|object
3425 *
3426 * Get answers list by quiz question
3427 *
3428 * @since v.1.0.0
3429 */
3430 public function get_answers_by_quiz_question($question_id, $rand = false){
3431 global $wpdb;
3432
3433 $question = $wpdb->get_row("SELECT * from {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} ;");
3434 if ( ! $question){
3435 return false;
3436 }
3437
3438 $order = " answer_order ASC ";
3439 if ($question->question_type === 'ordering'){
3440 $order = " RAND() ";
3441 }
3442
3443 if ($rand){
3444 $order = " RAND() ";
3445 }
3446
3447 $answers = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question_id} AND belongs_question_type = '{$question->question_type}' order by {$order} ");
3448 return $answers;
3449 }
3450
3451 /**
3452 * @param int $quiz_id
3453 * @param int $user_id
3454 *
3455 * @return array|bool|null|object
3456 *
3457 * Get all of the attempts by an user of a quiz
3458 *
3459 * @since v.1.0.0
3460 */
3461
3462 public function quiz_attempts($quiz_id = 0, $user_id = 0){
3463 global $wpdb;
3464
3465 $quiz_id = $this->get_post_id($quiz_id);
3466 $user_id = $this->get_user_id($user_id);
3467
3468 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE quiz_id = {$quiz_id} AND user_id = {$user_id} ");
3469
3470 if (is_array($attempts) && count($attempts)){
3471 return $attempts;
3472 }
3473
3474 return false;
3475 }
3476
3477
3478 public function get_all_quiz_attempts_by_user($user_id = 0){
3479 global $wpdb;
3480
3481 $user_id = $this->get_user_id($user_id);
3482
3483 $attempts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempts WHERE user_id = {$user_id} ");
3484
3485 if (is_array($attempts) && count($attempts)){
3486 return $attempts;
3487 }
3488
3489 return false;
3490 }
3491
3492 /**
3493 * @param string $search_term
3494 *
3495 * @return int
3496 *
3497 * Total number of quiz attempts
3498 *
3499 * @since v.1.0.0
3500 */
3501
3502 public function get_total_quiz_attempts($search_term = ''){
3503 global $wpdb;
3504
3505 if ($search_term){
3506 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3507 }
3508
3509 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3510 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3511 INNER JOIN {$wpdb->posts} quiz
3512 ON quiz_attempts.quiz_id = quiz.ID
3513 INNER JOIN {$wpdb->users}
3514 ON quiz_attempts.user_id = {$wpdb->users}.ID
3515 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3516 return (int) $count;
3517 }
3518
3519 /**
3520 * @param int $start
3521 * @param int $limit
3522 * @param string $search_term
3523 *
3524 * @return array|null|object
3525 *
3526 *
3527 * Get the all quiz attempts
3528 *
3529 * @since v.1.0.0
3530 */
3531 public function get_quiz_attempts($start = 0, $limit = 10, $search_term = '') {
3532 global $wpdb;
3533
3534 if ($search_term){
3535 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3536 }
3537
3538 $query = $wpdb->get_results("SELECT *
3539 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3540 INNER JOIN {$wpdb->posts} quiz
3541 ON quiz_attempts.quiz_id = quiz.ID
3542 INNER JOIN {$wpdb->users}
3543 ON quiz_attempts.user_id = {$wpdb->users}.ID
3544 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3545 ORDER BY quiz_attempts.attempt_id DESC
3546 LIMIT {$start},{$limit}; ");
3547 return $query;
3548 }
3549
3550 public function get_quiz_attempts_by_course_ids($start = 0, $limit = 10, $course_ids = array(), $search_term = '') {
3551 global $wpdb;
3552
3553 if ($search_term){
3554 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3555 }
3556
3557 $course_ids_in = implode($course_ids, ',');
3558 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3559 $search_term = $sql.$search_term;
3560
3561 $query = $wpdb->get_results("SELECT *
3562 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3563 INNER JOIN {$wpdb->posts} quiz
3564 ON quiz_attempts.quiz_id = quiz.ID
3565 INNER JOIN {$wpdb->users}
3566 ON quiz_attempts.user_id = {$wpdb->users}.ID
3567 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term}
3568 ORDER BY quiz_attempts.attempt_id DESC
3569 LIMIT {$start},{$limit}; ");
3570 return $query;
3571 }
3572
3573 public function get_total_quiz_attempts_by_course_ids($course_ids = array(), $search_term = ''){
3574 global $wpdb;
3575
3576 if ($search_term){
3577 $search_term = " AND ( user_email like '%{$search_term}%' OR display_name like '%{$search_term}%' OR post_title like '%{$search_term}%' ) ";
3578 }
3579
3580 $course_ids_in = implode($course_ids, ',');
3581 $sql = " AND quiz_attempts.course_id IN({$course_ids_in}) ";
3582 $search_term = $sql.$search_term;
3583
3584 $count = $wpdb->get_var("SELECT COUNT(attempt_id)
3585 FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
3586 INNER JOIN {$wpdb->posts} quiz
3587 ON quiz_attempts.quiz_id = quiz.ID
3588 INNER JOIN {$wpdb->users}
3589 ON quiz_attempts.user_id = {$wpdb->users}.ID
3590 WHERE 1=1 AND quiz_attempts.attempt_ended_at <= NOW() {$search_term} ");
3591 return (int) $count;
3592 }
3593
3594 /**
3595 * @param $attempt_id
3596 *
3597 * @return array|null|object
3598 *
3599 * Get quiz answers by attempt id
3600 *
3601 * @since v.1.0.0
3602 */
3603 public function get_quiz_answers_by_attempt_id($attempt_id){
3604 global $wpdb;
3605
3606 $results = $wpdb->get_results("SELECT answers.*, question.question_title, question.question_type
3607 FROM {$wpdb->prefix}tutor_quiz_attempt_answers answers
3608 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answers.question_id = question.question_id
3609 WHERE answers.quiz_attempt_id = {$attempt_id} ");
3610
3611 return $results;
3612 }
3613
3614 /**
3615 * @param $answer_id
3616 *
3617 * @return array|null|object
3618 *
3619 * Get single answer by answer_id
3620 *
3621 * @since v.1.0.0
3622 */
3623 public function get_answer_by_id($answer_id){
3624 global $wpdb;
3625
3626 if (is_array($answer_id)){
3627 $in_ids = implode(",", $answer_id);
3628 $sql = "answer.answer_id IN({$in_ids})";
3629 }else{
3630 $sql = "answer.answer_id = {$answer_id}";
3631 }
3632
3633 $answer = $wpdb->get_results("SELECT answer.*, question.question_title, question.question_type
3634 FROM {$wpdb->prefix}tutor_quiz_question_answers answer
3635 LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question ON answer.belongs_question_id = question.question_id
3636 WHERE 1=1 AND {$sql} ");
3637
3638 return $answer;
3639 }
3640
3641 /**
3642 * @param $ids
3643 *
3644 * @return array|bool|null|object
3645 *
3646 * Get quiz answers by ids
3647 *
3648 * @since v.1.0.0
3649 */
3650
3651 public function get_quiz_answers_by_ids($ids){
3652 $ids = (array) $ids;
3653
3654 if (!count($ids)){
3655 return false;
3656 }
3657
3658 $in_ids = implode(",", $ids);
3659
3660 global $wpdb;
3661 $query = $wpdb->get_results("SELECT
3662 comment_ID,
3663 comment_content
3664 FROM {$wpdb->comments}
3665 WHERE comment_type = 'quiz_answer_option' AND comment_ID IN({$in_ids}) ");
3666
3667 if (is_array($query) && count($query)){
3668 return $query;
3669 }
3670
3671 return false;
3672 }
3673
3674 /**
3675 * @param null $level
3676 *
3677 * @return mixed
3678 *
3679 * Get the users / students / course levels
3680 *
3681 * @since v.1.0.0
3682 */
3683
3684 public function course_levels($level = null){
3685 $levels = apply_filters('tutor_course_level', array(
3686 'all_levels' => __('All Levels', 'tutor'),
3687 'beginner' => __('Beginner', 'tutor'),
3688 'intermediate' => __('Intermediate', 'tutor'),
3689 'expert' => __('Expert', 'tutor'),
3690 ));
3691
3692 if ($level){
3693 if (isset($levels[$level])){
3694 return $levels[$level];
3695 }else{
3696 return '';
3697 }
3698 }
3699
3700 return $levels;
3701 }
3702
3703 /**
3704 * @return mixed|void
3705 *
3706 * Get user permalink for dashboard
3707 *
3708 * @since v.1.0.0
3709 */
3710 public function user_profile_permalinks(){
3711 $permalinks = array(
3712 'courses_taken' => __('Courses Taken', 'tutor'),
3713 );
3714
3715 $show_enrolled_course = tutor_utils()->get_option('show_courses_completed_by_student');
3716 $enable_show_reviews_wrote = tutor_utils()->get_option('students_own_review_show_at_profile');
3717
3718 if ($show_enrolled_course){
3719 $permalinks['enrolled_course'] = __('Enrolled Course', 'tutor');
3720 }
3721 if ($enable_show_reviews_wrote){
3722 $permalinks['reviews_wrote'] = __('Reviews Written', 'tutor');
3723 }
3724
3725
3726 return apply_filters('tutor_public_profile/permalinks', $permalinks);
3727 }
3728
3729 /**
3730 * @return bool|false|string
3731 *
3732 * Student registration form
3733 *
3734 * @since v.1.0.0
3735 */
3736 public function student_register_url(){
3737 $student_register_page = (int) $this->get_option('student_register_page');
3738
3739 if ($student_register_page){
3740 return get_the_permalink($student_register_page);
3741 }
3742 return false;
3743 }
3744 /**
3745 * @return bool|false|string
3746 *
3747 * Instructor registration form
3748 *
3749 * @since v.1.2.13
3750 */
3751 public function instructor_register_url(){
3752 $instructor_register_page = (int) $this->get_option('instructor_register_page');
3753
3754 if ($instructor_register_page){
3755 return get_the_permalink($instructor_register_page);
3756 }
3757 return false;
3758 }
3759
3760 /**
3761 * @return false|string
3762 *
3763 * Get frontend dashboard URL
3764 */
3765 public function tutor_dashboard_url($sub_url = ''){
3766 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3767 $page_id = apply_filters('tutor_dashboard_page_id', $page_id);
3768 return trailingslashit(get_the_permalink($page_id)).$sub_url;
3769 }
3770
3771 /**
3772 * Get the tutor dashboard page ID
3773 *
3774 * @return int
3775 *
3776 */
3777 public function dashboard_page_id(){
3778 $page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
3779 $page_id = apply_filters('tutor_dashboard_page_id', $page_id);
3780 return $page_id;
3781 }
3782
3783 /**
3784 * @param int $course_id
3785 * @param int $user_id
3786 *
3787 * @return bool
3788 *
3789 * is_wishlisted();
3790 *
3791 * @since v.1.0.0
3792 */
3793 public function is_wishlisted($course_id = 0, $user_id = 0){
3794 $course_id = $this->get_post_id($course_id);
3795 $user_id = $this->get_user_id($user_id);
3796 if ( ! $user_id){
3797 return false;
3798 }
3799
3800 global $wpdb;
3801 $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} ;");
3802
3803 return $if_added_to_list;
3804 }
3805
3806 /**
3807 * @param int $user_id
3808 *
3809 * @return array|null|object
3810 *
3811 * Get the wish lists by an user
3812 *
3813 * @since v.1.0.0
3814 */
3815 public function get_wishlist($user_id = 0){
3816 $user_id = $this->get_user_id($user_id);
3817 global $wpdb;
3818
3819 $query = "SELECT $wpdb->posts.*
3820 FROM $wpdb->posts
3821 LEFT JOIN $wpdb->usermeta ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
3822 WHERE $wpdb->usermeta.meta_key = '_tutor_course_wishlist'
3823 AND $wpdb->usermeta.user_id = {$user_id}
3824 ORDER BY $wpdb->usermeta.umeta_id DESC ";
3825 $pageposts = $wpdb->get_results($query, OBJECT);
3826 return $pageposts;
3827 }
3828
3829 /**
3830 * @param int $limit
3831 *
3832 * @return array|null|object
3833 *
3834 * Getting popular courses
3835 *
3836 * @since v.1.0.0
3837 */
3838 public function most_popular_courses($limit = 10){
3839 global $wpdb;
3840
3841 $courses = $wpdb->get_results("
3842 SELECT COUNT(enrolled.ID) as total_enrolled,
3843 enrolled.post_parent as course_id,
3844 course.*
3845 from {$wpdb->posts} enrolled
3846 INNER JOIN {$wpdb->posts} course ON enrolled.post_parent = course.ID
3847 WHERE enrolled.post_type = 'tutor_enrolled' AND enrolled.post_status = 'completed'
3848
3849 GROUP BY course_id
3850 ORDER BY total_enrolled DESC LIMIT 0,{$limit} ;");
3851
3852 return $courses;
3853 }
3854
3855 /**
3856 * @param int $limit
3857 *
3858 * @return array|bool|null|object
3859 *
3860 * Get most rated courses lists
3861 *
3862 * @since v.1.0.0
3863 */
3864 public function most_rated_courses($limit = 10){
3865 global $wpdb;
3866
3867 $result = $wpdb->get_results("
3868 SELECT COUNT(comment_ID) AS total_rating,
3869 comment_ID,
3870 comment_post_ID,
3871 course.*
3872 FROM {$wpdb->comments}
3873 INNER JOIN {$wpdb->posts} course ON comment_post_ID = course.ID
3874 WHERE {$wpdb->comments}.comment_type = 'tutor_course_rating' AND {$wpdb->comments}.comment_approved = 'approved'
3875 GROUP BY comment_post_ID ORDER BY total_rating DESC LIMIT 0,{$limit}
3876 ;");
3877
3878 if (is_array($result) && count($result)){
3879 return $result;
3880 }
3881 return false;
3882 }
3883
3884 /**
3885 * @param null $addon_field
3886 *
3887 * @return bool
3888 *
3889 * Get Addon config
3890 *
3891 * @since v.1.0.0
3892 */
3893 public function get_addon_config($addon_field = null){
3894 if ( ! $addon_field){
3895 return false;
3896 }
3897
3898 $addonsConfig = maybe_unserialize(get_option('tutor_addons_config'));
3899
3900 if (isset($addonsConfig[$addon_field])){
3901 return $addonsConfig[$addon_field];
3902 }
3903
3904 return false;
3905 }
3906
3907 /**
3908 * @return array|false|string
3909 *
3910 * Get the IP from visitor
3911 *
3912 * @since v.1.0.0
3913 */
3914 function get_ip() {
3915 $ipaddress = '';
3916 if (getenv('HTTP_CLIENT_IP'))
3917 $ipaddress = getenv('HTTP_CLIENT_IP');
3918 else if(getenv('HTTP_X_FORWARDED_FOR'))
3919 $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
3920 else if(getenv('HTTP_X_FORWARDED'))
3921 $ipaddress = getenv('HTTP_X_FORWARDED');
3922 else if(getenv('HTTP_FORWARDED_FOR'))
3923 $ipaddress = getenv('HTTP_FORWARDED_FOR');
3924 else if(getenv('HTTP_FORWARDED'))
3925 $ipaddress = getenv('HTTP_FORWARDED');
3926 else if(getenv('REMOTE_ADDR'))
3927 $ipaddress = getenv('REMOTE_ADDR');
3928 else
3929 $ipaddress = 'UNKNOWN';
3930 return $ipaddress;
3931 }
3932
3933 /**
3934 * @return array $array
3935 *
3936 * Get the social icons
3937 *
3938 * @since v.1.0.4
3939 */
3940
3941 public function tutor_social_share_icons(){
3942 $icons = array(
3943 'facebook' => array('share_class' => 's_facebook', 'icon_html' => '<i class="tutor-icon-facebook"></i>' ),
3944 'twitter' => array('share_class' => 's_twitter', 'icon_html' => '<i class="tutor-icon-twitter"></i>' ),
3945 'linkedin' => array('share_class' => 's_linkedin', 'icon_html' => '<i class="tutor-icon-linkedin"></i>' ),
3946 'tumblr' => array('share_class' => 's_tumblr', 'icon_html' => '<i class="tutor-icon-tumblr"></i>' ),
3947 );
3948
3949 return apply_filters('tutor_social_share_icons', $icons);
3950 }
3951
3952 /**
3953 * @return array $array
3954 *
3955 * Get the user social icons
3956 *
3957 * @since v.1.3.7
3958 */
3959
3960 public function tutor_user_social_icons(){
3961 $icons = array(
3962 '_tutor_profile_website' => array(
3963 'label' => __('Website URL', 'tutor'),
3964 'placeholder' => 'https://example.com/',
3965 'icon_classes' => 'tutor-icon-earth'
3966 ),
3967 '_tutor_profile_github' => array(
3968 'label' => __('Github URL', 'tutor'),
3969 'placeholder' => 'https://github.com/username',
3970 'icon_classes' => 'tutor-icon-github-logo'
3971 ),
3972 '_tutor_profile_facebook' => array(
3973 'label' => __('Facebook URL', 'tutor'),
3974 'placeholder' => 'https://facebook.com/username',
3975 'icon_classes' => 'tutor-icon-facebook'
3976 ),
3977 '_tutor_profile_twitter' => array(
3978 'label' => __('Twitter URL', 'tutor'),
3979 'placeholder' => 'https://twitter.com/username',
3980 'icon_classes' => 'tutor-icon-twitter'
3981 ),
3982 '_tutor_profile_linkedin' => array(
3983 'label' => __('Linkedin URL', 'tutor'),
3984 'placeholder' => 'https://linkedin.com/username',
3985 'icon_classes' => 'tutor-icon-linkedin'
3986 ),
3987 );
3988
3989 return apply_filters('tutor_user_social_icons', $icons);
3990 }
3991
3992 /**
3993 * @param array $array
3994 *
3995 * @return bool
3996 *
3997 * count method with check is_array
3998 *
3999 * @since v.1.0.4
4000 */
4001 public function count($array = array()){
4002 if (is_array($array) && count($array)){
4003 return count($array);
4004 }
4005 return false;
4006 }
4007
4008 /**
4009 * @return array
4010 *
4011 * get all screen ids
4012 *
4013 * @since v.1.1.2
4014 */
4015 public function tutor_get_screen_ids(){
4016 $screen_ids = array(
4017 "edit-course",
4018 "course",
4019 "edit-course-category",
4020 "edit-course-tag",
4021 "tutor-lms_page_tutor-students",
4022 "tutor-lms_page_tutor-instructors",
4023 "tutor-lms_page_question_answer",
4024 "tutor-lms_page_tutor_quiz_attempts",
4025 "tutor-lms_page_tutor-addons",
4026 "tutor-lms_page_tutor-status",
4027 "tutor-lms_page_tutor_report",
4028 "tutor-lms_page_tutor_settings",
4029 "tutor-lms_page_tutor_emails",
4030 );
4031
4032 return apply_filters('tutor_get_screen_ids', $screen_ids);
4033 }
4034
4035
4036 /**
4037 * @return mixed
4038 *
4039 * get earning transaction completed status
4040 *
4041 * @since v.1.1.2
4042 */
4043 public function get_earnings_completed_statuses(){
4044 return apply_filters(
4045 'tutor_get_earnings_completed_statuses',
4046 array (
4047 'wc-completed',
4048 'completed',
4049 'complete',
4050 )
4051 );
4052 }
4053
4054 /**
4055 * @param int $user_id
4056 * @param array $date_filter
4057 *
4058 * @return array|null|object
4059 *
4060 * Get all time earning sum for an instructor with all commission
4061 *
4062 * @since v.1.1.2
4063 */
4064
4065 public function get_earning_sum($user_id = 0, $date_filter = array()){
4066 global $wpdb;
4067
4068 $user_id = $this->get_user_id($user_id);
4069 $date_query = '';
4070 if ($this->count($date_filter)){
4071 extract($date_filter);
4072
4073 if ( ! empty($dataFor)){
4074 if ($dataFor === 'yearly'){
4075 if (empty($year)){
4076 $year = date('Y');
4077 }
4078 $date_query = "AND YEAR(created_at) = {$year} ";
4079 }
4080 }else{
4081 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
4082 }
4083 }
4084
4085 $complete_status = tutor_utils()->get_earnings_completed_statuses();
4086 $complete_status = "'".implode("','", $complete_status)."'";
4087
4088 $earning_sum = $wpdb->get_row("SELECT SUM(course_price_total) as course_price_total,
4089 SUM(course_price_grand_total) as course_price_grand_total,
4090 SUM(instructor_amount) as instructor_amount,
4091 (SELECT SUM(amount) FROM {$wpdb->prefix}tutor_withdraws WHERE user_id = {$user_id} AND status != 'rejected' ) as
4092 withdraws_amount,
4093 SUM(admin_amount) as admin_amount,
4094 SUM(deduct_fees_amount) as deduct_fees_amount
4095 FROM {$wpdb->prefix}tutor_earnings
4096 WHERE user_id = {$user_id} AND order_status IN({$complete_status}) {$date_query} ");
4097
4098 //TODO: need to check
4099 // (SUM(instructor_amount) - (SELECT withdraws_amount) ) as balance,
4100
4101
4102 if ( $earning_sum->course_price_total){
4103 $earning_sum->balance = $earning_sum->instructor_amount - $earning_sum->withdraws_amount;
4104 }else{
4105
4106 $earning_sum = (object) array(
4107 'course_price_total' => 0,
4108 'course_price_grand_total' => 0,
4109 'instructor_amount' => 0,
4110 'withdraws_amount' => 0,
4111 'balance' => 0,
4112 'admin_amount' => 0,
4113 'deduct_fees_amount' => 0,
4114 );
4115 }
4116
4117 return $earning_sum;
4118 }
4119
4120 /**
4121 * @param int $user_id
4122 * @param array $date_filter
4123 *
4124 * @return array|null|object
4125 *
4126 * Get earning statements
4127 *
4128 * @since v.1.1.2
4129 */
4130 public function get_earning_statements($user_id = 0, $filter_data = array()){
4131 global $wpdb;
4132
4133 $user_sql = "";
4134 if ($user_id){
4135 $user_sql = " AND user_id='{$user_id}' ";
4136 }
4137
4138 $date_query = '';
4139 $query_by_status = '';
4140 $pagination_query = '';
4141
4142 /**
4143 * Query by Date Filter
4144 */
4145 if ($this->count($filter_data)){
4146 extract($filter_data);
4147
4148 if ( ! empty($dataFor)){
4149 if ($dataFor === 'yearly'){
4150 if (empty($year)){
4151 $year = date('Y');
4152 }
4153 $date_query = "AND YEAR(created_at) = {$year} ";
4154 }
4155 }else{
4156 $date_query = " AND (created_at BETWEEN '{$start_date}' AND '{$end_date}') ";
4157 }
4158
4159 /**
4160 * Query by order status related to this earning transaction
4161 */
4162 if ( ! empty($statuses)) {
4163 if ( $this->count( $statuses ) ) {
4164 $status = "'" . implode( "','", $statuses ) . "'";
4165 $query_by_status = "AND order_status IN({$status})";
4166 } elseif ( $statuses === 'completed' ) {
4167
4168 $get_earnings_completed_statuses = $this->get_earnings_completed_statuses();
4169 if ( $this->count( $get_earnings_completed_statuses ) ) {
4170 $status = "'" . implode( "','", $get_earnings_completed_statuses ) . "'";
4171 $query_by_status = "AND order_status IN({$status})";
4172 }
4173 }
4174 }
4175
4176 if ( ! empty($per_page)){
4177 $offset = (int) ! empty($offset) ? $offset : 0;
4178
4179 $pagination_query = " LIMIT {$offset}, {$per_page} ";
4180
4181 }
4182
4183
4184 }
4185
4186 $query = $wpdb->get_results("SELECT earning_tbl.*, course.post_title as course_title
4187 FROM {$wpdb->prefix}tutor_earnings earning_tbl
4188 LEFT JOIN {$wpdb->posts} course ON earning_tbl.course_id = course.ID
4189 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC {$pagination_query} ");
4190
4191
4192 $query_count = (int) $wpdb->get_var("SELECT COUNT(earning_tbl.earning_id)
4193 FROM {$wpdb->prefix}tutor_earnings earning_tbl
4194 WHERE 1=1 {$user_sql} {$date_query} {$query_by_status} ORDER BY created_at DESC ");
4195
4196 return (object) array(
4197 'count' => $query_count,
4198 'results' => $query,
4199 );
4200 }
4201
4202 /**
4203 * @param int $price
4204 *
4205 * @return int|string
4206 *
4207 * Get the price format
4208 *
4209 * @since v.1.1.2
4210 */
4211
4212 public function tutor_price($price = 0){
4213 if (function_exists('wc_price')){
4214 return wc_price($price);
4215 }elseif (function_exists('edd_currency_filter')){
4216 return edd_currency_filter(edd_format_amount($price));
4217 }else{
4218 return number_format_i18n($price);
4219 }
4220 }
4221
4222 /**
4223 * @return mixed
4224 *
4225 * Get currency symbol from activated plugin, WC,EDD
4226 *
4227 * @since v.1.3.4
4228 */
4229
4230 public function currency_symbol(){
4231 $enable_tutor_edd = tutor_utils()->get_option('enable_tutor_edd');
4232 $monetize_by = $this->get_option('monetize_by');
4233
4234 $symbol = '&#36;';
4235 if ($enable_tutor_edd && function_exists('edd_currency_symbol')){
4236 $symbol = edd_currency_symbol();
4237 }
4238
4239 if ($monetize_by === 'wc' && function_exists('get_woocommerce_currency_symbol') ){
4240 $symbol = get_woocommerce_currency_symbol();
4241 }
4242
4243 return apply_filters('get_tutor_currency_symbol', $symbol);
4244 }
4245
4246 /**
4247 * @param int $user_id
4248 *
4249 * @return bool|mixed
4250 *
4251 * Get withdraw method for a specific
4252 */
4253 public function get_user_withdraw_method($user_id = 0){
4254 $user_id = $this->get_user_id($user_id);
4255
4256 $account = get_user_meta($user_id, '_tutor_withdraw_method_data', true);
4257 if ($account){
4258 return maybe_unserialize($account);
4259 }
4260
4261 return false;
4262 }
4263
4264 /**
4265 * @param int $user_id
4266 * @param array $filter
4267 *
4268 * get withdrawal history
4269 *
4270 * @return object
4271 */
4272 public function get_withdrawals_history($user_id = 0, $filter = array()){
4273 global $wpdb;
4274
4275 $filter = (array) $filter;
4276 extract($filter);
4277
4278 $query_by_status_sql = "";
4279 $query_by_user_sql = "";
4280 $query_by_pagination = "";
4281
4282 if ( ! empty($status)){
4283 $status = (array) $status;
4284 $status = "'".implode("','", $status)."'";
4285
4286 $query_by_status_sql = " AND status IN({$status}) ";
4287 }
4288
4289 if ( ! empty($per_page)){
4290 if ( empty($start))
4291 $start = 0;
4292
4293 $query_by_pagination = " LIMIT {$start}, {$per_page} ";
4294 }
4295
4296 if ($user_id){
4297 $query_by_user_sql = " AND user_id = {$user_id} ";
4298 }
4299
4300
4301 $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} ");
4302
4303 $results = $wpdb->get_results("SELECT withdraw_tbl.*,
4304 user_tbl.display_name as user_name,
4305 user_tbl.user_email
4306 FROM {$wpdb->prefix}tutor_withdraws withdraw_tbl
4307 INNER JOIN {$wpdb->users} user_tbl ON withdraw_tbl.user_id = user_tbl.ID
4308 WHERE 1=1
4309 {$query_by_user_sql}
4310 {$query_by_status_sql} ORDER BY
4311 created_at DESC {$query_by_pagination} ");
4312
4313 $withdraw_history = array(
4314 'count' => 0,
4315 'results' => null,
4316 );
4317
4318 if ($count){
4319 $withdraw_history['count'] = $count;
4320 }
4321
4322 if (tutor_utils()->count($results)){
4323 $withdraw_history['results'] = $results;
4324 }
4325 return (object) $withdraw_history;
4326
4327 }
4328
4329 /**
4330 * @param int $instructor_id
4331 *
4332 * Add Instructor role to any user by user iD
4333 */
4334 public function add_instructor_role($instructor_id = 0){
4335 if ( ! $instructor_id){
4336 return;
4337 }
4338 do_action('tutor_before_approved_instructor', $instructor_id);
4339
4340 update_user_meta($instructor_id, '_tutor_instructor_status', 'approved');
4341 update_user_meta($instructor_id, '_tutor_instructor_approved', time());
4342
4343 $instructor = new \WP_User($instructor_id);
4344 $instructor->add_role(tutor()->instructor_role);
4345
4346 do_action('tutor_after_approved_instructor', $instructor_id);
4347 }
4348
4349 /**
4350 * @param int $instructor_id
4351 *
4352 * Remove instructor role by instructor id
4353 */
4354 public function remove_instructor_role($instructor_id = 0){
4355 if ( ! $instructor_id){
4356 return;
4357 }
4358
4359 do_action('tutor_before_blocked_instructor', $instructor_id);
4360 update_user_meta($instructor_id, '_tutor_instructor_status', 'blocked');
4361
4362 $instructor = new \WP_User($instructor_id);
4363 $instructor->remove_role(tutor()->instructor_role);
4364 do_action('tutor_after_blocked_instructor', $instructor_id);
4365 }
4366
4367 /**
4368 * @param string $msg
4369 * @param string $name
4370 *
4371 * Set Flash Message to view in next action / route
4372 */
4373 public function set_flash_msg($msg = '', $name = 'success'){
4374 global $wp_filesystem;
4375 if ( ! $wp_filesystem ) {
4376 require_once( ABSPATH . 'wp-admin/includes/file.php' );
4377 }
4378
4379 $filename = "tutor_flash_msg_{$name}.txt";
4380 $upload_dir = wp_upload_dir();
4381 $dir = trailingslashit($upload_dir['basedir']) . 'tutor/';
4382
4383 WP_Filesystem( false, $upload_dir['basedir'], true );
4384
4385 if( ! $wp_filesystem->is_dir( $dir ) ) {
4386 $wp_filesystem->mkdir( $dir );
4387 }
4388 $wp_filesystem->put_contents( $dir . $filename, $msg );
4389 }
4390
4391 /**
4392 * @param null $name
4393 *
4394 * @return mixed|string|void
4395 *
4396 * Get Flash Message
4397 */
4398 public function get_flash_msg($name = null){
4399 if ( ! $name){
4400 return '';
4401 }
4402
4403 $upload_dir = wp_get_upload_dir();
4404 $upload_dir = trailingslashit($upload_dir['basedir']);
4405 $msg_name = 'tutor_flash_msg_'.$name;
4406
4407 $msg = '';
4408 $flash_msg_file_name = $upload_dir."tutor/{$msg_name}.txt";
4409 if (file_exists($flash_msg_file_name)){
4410 $msg = file_get_contents($flash_msg_file_name);
4411 unlink($flash_msg_file_name);
4412 }
4413
4414 return apply_filters('tutor_get_flash_msg', $msg, $name);
4415 }
4416
4417 /**
4418 * @param int $user_id
4419 *
4420 * @return array|null|object
4421 *
4422 * Get purchase history by customer id
4423 */
4424
4425 public function get_orders_by_user_id($user_id = 0){
4426 global $wpdb;
4427
4428 $user_id = $this->get_user_id();
4429
4430 $query = $wpdb->get_results("SELECT {$wpdb->posts}.* FROM {$wpdb->posts}
4431 INNER JOIN {$wpdb->postmeta} customer ON ID = customer.post_id AND customer.meta_key = '_customer_user'
4432 INNER JOIN {$wpdb->postmeta} tutor_order ON ID = tutor_order.post_id AND tutor_order.meta_key = '_is_tutor_order_for_course'
4433 where post_type = 'shop_order' AND customer.meta_value = {$user_id} ");
4434 return $query;
4435 }
4436
4437 /**
4438 * @param null $status
4439 *
4440 * @return string
4441 *
4442 * Get status contact formatted for order
4443 *
4444 * @since v.1.3.1
4445 */
4446 public function order_status_context($status = null){
4447 $status = str_replace('wc-', '', $status);
4448 $status_name = ucwords(str_replace('-', ' ', $status));
4449
4450 return "<span class='label-order-status label-status-{$status}'>$status_name</span>";
4451 }
4452
4453 public function get_course_id_by_assignment($assignment_id = 0){
4454 $assignment_id = $this->get_post_id($assignment_id);
4455 return get_post_meta($assignment_id, '_tutor_course_id_for_assignments', true);
4456 }
4457
4458 /**
4459 * @param int $assignment_id
4460 * @param string $option_key
4461 * @param bool $default
4462 *
4463 * @return array|bool|mixed
4464 *
4465 * Get assignment options
4466 *
4467 * @since v.1.3.3
4468 */
4469 public function get_assignment_option($assignment_id = 0, $option_key = '', $default = false){
4470 $assignment_id = $this->get_post_id($assignment_id);
4471 $get_option_meta = maybe_unserialize(get_post_meta($assignment_id, 'assignment_option', true));
4472
4473 if ( ! $option_key && ! empty($get_option_meta)) {
4474 return $get_option_meta;
4475 }
4476
4477 $value = $this->avalue_dot( $option_key, $get_option_meta );
4478 if ( $value ) {
4479 return $value;
4480 }
4481 return $default;
4482 }
4483
4484 /**
4485 * @param int $assignment_id
4486 * @param int $user_id
4487 *
4488 * @return int
4489 *
4490 * Is running any assignment submitting
4491 *
4492 * @since v.1.3.3
4493 */
4494 public function is_assignment_submitting($assignment_id = 0, $user_id = 0){
4495 global $wpdb;
4496
4497 $assignment_id = $this->get_post_id($assignment_id);
4498 $user_id = $this->get_user_id($user_id);
4499
4500 $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 =
4501 {$assignment_id} ");
4502
4503 return $is_running_submit;
4504 }
4505
4506 /**
4507 * @param int $assignment_id
4508 * @param int $user_id
4509 *
4510 * @return array|null|object
4511 *
4512 * Determine if any assignment submitted by user to a assignment
4513 *
4514 * @since v.1.3.3
4515 */
4516
4517 public function is_assignment_submitted($assignment_id = 0, $user_id = 0){
4518 global $wpdb;
4519
4520 $assignment_id = $this->get_post_id($assignment_id);
4521 $user_id = $this->get_user_id($user_id);
4522
4523 $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} ");
4524
4525 return $has_submitted;
4526 }
4527
4528 public function get_assignment_submit_info($assignment_submitted_id = 0){
4529 global $wpdb;
4530
4531 $assignment_submitted_id = $this->get_post_id($assignment_submitted_id);
4532 $submitted_info = $wpdb->get_row("SELECT * FROM {$wpdb->comments} WHERE comment_ID = {$assignment_submitted_id} AND comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4533
4534 return $submitted_info;
4535 }
4536
4537 public function get_total_assignments(){
4538 global $wpdb;
4539
4540 $count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4541
4542 return (int) $count;
4543 }
4544
4545 public function get_assignments(){
4546 global $wpdb;
4547
4548 $results = $wpdb->get_results("SELECT * FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_approved = 'submitted' ");
4549
4550 return $results;
4551 }
4552
4553 /**
4554 * @param int $user_id
4555 *
4556 * @return array
4557 *
4558 * Get all courses id assigned or owned by an instructors
4559 *
4560 * @since v.1.3.3
4561 */
4562 public function get_assigned_courses_ids_by_instructors($user_id = 0){
4563 global $wpdb;
4564 $user_id = $this->get_user_id($user_id);
4565
4566 $course_post_type = tutor()->course_post_type;
4567 $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 ; ");
4568
4569 /*
4570 $author_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} where post_type = '{$course_post_type}' AND post_author = {$user_id}");
4571 $final_course_ids = array_merge($get_assigned_courses_ids, $author_ids);
4572 $final_course_ids = array_unique($final_course_ids);
4573 */
4574
4575 return $get_assigned_courses_ids;
4576 }
4577
4578 /**
4579 * @param int $parent
4580 *
4581 * @return array
4582 *
4583 * Get course categories in array with child
4584 *
4585 * @since v.1.3.4
4586 */
4587
4588 public function get_course_categories($parent = 0 ){
4589 $args = apply_filters('tutor_get_course_categories_args', array(
4590 'taxonomy' => 'course-category',
4591 'hide_empty' => false,
4592 'parent' => $parent,
4593 ));
4594
4595 $terms = get_terms($args);
4596
4597 $children = array();
4598 foreach ( $terms as $term ){
4599 $term->children = $this->get_course_categories( $term->term_id );
4600 $children[ $term->term_id ] = $term;
4601 }
4602
4603 return $children;
4604 }
4605
4606 /**
4607 * @param int $parent_id
4608 *
4609 * @return array|int|\WP_Error
4610 *
4611 * Get course categories terms in raw array
4612 *
4613 * @since v.1.3.5
4614 */
4615 public function get_course_categories_term($parent_id = 0){
4616 $args = apply_filters('tutor_get_course_categories_terms_args', array(
4617 'taxonomy' => 'course-category',
4618 'parent' => $parent_id,
4619 'hide_empty' => false,
4620 ));
4621
4622 $terms = get_terms($args);
4623
4624 return $terms;
4625 }
4626
4627 /**
4628 * @return mixed
4629 *
4630 * Get back url from the request
4631 * @since v.1.3.4
4632 */
4633 public function referer(){
4634 $url = $this->array_get('_wp_http_referer', $_REQUEST);
4635 return apply_filters('tutor_referer_url', $url);
4636 }
4637
4638 /**
4639 * @param int $course_id
4640 *
4641 * @return false|string
4642 *
4643 * Get the frontend dashboard course edit page
4644 *
4645 * @since v.1.3.4
4646 */
4647 public function course_edit_link($course_id = 0){
4648 $course_id = $this->get_post_id($course_id);
4649
4650 $url = admin_url("post.php?post={$course_id}&action=edit");
4651 if (tutor()->has_pro){
4652 $url = $this->tutor_dashboard_url("create-course/?course_ID=".$course_id);
4653 }
4654
4655 return $url;
4656 }
4657
4658 public function get_assignments_by_instructor($instructor_id = 0, $filter_data = array()){
4659 global $wpdb;
4660
4661 $instructor_id = $this->get_user_id($instructor_id);
4662 $course_ids = tutor_utils()->get_assigned_courses_ids_by_instructors($instructor_id);
4663
4664 //$new_course_ids = tutils()->get_courses_by_instructor();
4665
4666 //die($this->print_view($course_ids));
4667
4668 $in_course_ids = implode("','", $course_ids);
4669
4670 $count = (int) $wpdb->get_var("SELECT COUNT(ID) FROM {$wpdb->postmeta} post_meta
4671 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4672 where post_type = 'tutor_assignments' AND post_meta.meta_value IN('$in_course_ids') ORDER BY ID DESC ");
4673
4674 $pagination_query = '';
4675 if ($this->count($filter_data)) {
4676 extract( $filter_data );
4677
4678 if ( ! empty( $per_page ) ) {
4679 $offset = (int) ! empty( $offset ) ? $offset : 0;
4680 $pagination_query = " LIMIT {$offset}, {$per_page} ";
4681 }
4682 }
4683
4684 $query = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} post_meta
4685 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4686 where post_type = 'tutor_assignments' AND post_meta.meta_value IN('$in_course_ids') ORDER BY ID DESC {$pagination_query} ");
4687
4688 return (object) array('count' => $count, 'results' => $query);
4689 }
4690
4691 /**
4692 * @param int $course_id
4693 *
4694 * @return bool|object
4695 *
4696 * Get assignments by course id
4697 */
4698 public function get_assignments_by_course($course_id = 0){
4699 if ( ! $course_id){
4700 return false;
4701 }
4702 global $wpdb;
4703
4704 $count = (int) $wpdb->get_var("SELECT COUNT(ID) 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 $query = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} post_meta
4709 INNER JOIN {$wpdb->posts} assignment ON post_meta.post_id = assignment.ID AND post_meta.meta_key = '_tutor_course_id_for_assignments'
4710 where post_type = 'tutor_assignments' AND post_meta.meta_value = {$course_id} ORDER BY ID DESC");
4711
4712 return (object) array('count' => $count, 'results' => $query);
4713 }
4714
4715 /**
4716 * @return bool
4717 *
4718 * Determine if script debug
4719 *
4720 * @since v.1.3.4
4721 */
4722 public function is_script_debug(){
4723 return ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
4724 }
4725
4726 }