PluginProbe
Tutor LMS – eLearning and online course solution / 3.9.15
Tutor LMS – eLearning and online course solution v3.9.15
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 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 All 191 releases
← All changes | classes/Shortcode.php +466 -31 1.0.63.9.15 View file →
@@ -1,73 +1,508 @@
1 1 <?php
2 2 /**
3 - * Class Shortcode
4 - * @package TUTOR
3 + * Manage short codes
5 4 *
6 - * @since v.1.0.0
5 + * @package Tutor\ShortCode
6 + * @author Themeum <support@themeum.com>
7 + * @link https://themeum.com
8 + * @since 1.0.0
7 9 */
8 10
9 11 namespace TUTOR;
10 12
11 -if ( ! defined( 'ABSPATH' ) )
13 +use Tutor\Models\CourseModel;
14 +
15 +if ( ! defined( 'ABSPATH' ) ) {
12 16 exit;
17 +}
13 18
19 +/**
20 + * Short code class
21 + *
22 + * @since 1.0.0
23 + */
14 24 class Shortcode {
15 25
16 - public function __construct() {
17 - add_shortcode('tutor_student_registration_form', array($this, 'student_registration_form'));
18 - add_shortcode('tutor_student_dashboard', array($this, 'tutor_student_dashboard'));
19 - add_shortcode('tutor_instructor_registration_form', array($this, 'instructor_registration_form'));
26 + /**
27 + * Instructor page design layouts
28 + *
29 + * @since 1.0.0
30 + *
31 + * @var array
32 + */
33 + private $instructor_layout = array(
34 + 'default',
35 + 'cover',
36 + 'minimal',
37 + 'portrait-horizontal',
38 + 'minimal-horizontal',
39 + );
40 +
41 + /**
42 + * Register hooks
43 + *
44 + * @since 1.0.0
45 + * @since 3.8.0
46 + *
47 + * @param bool $register_hooks register hooks or not.
48 + *
49 + * @return void
50 + */
51 + public function __construct( $register_hooks = true ) {
52 + if ( ! $register_hooks ) {
53 + return;
54 + }
55 +
56 + add_shortcode( 'tutor_student_registration_form', array( $this, 'student_registration_form' ) );
57 + add_shortcode( 'tutor_dashboard', array( $this, 'tutor_dashboard' ) );
58 + add_shortcode( 'tutor_instructor_registration_form', array( $this, 'instructor_registration_form' ) );
59 + add_shortcode( 'tutor_course', array( $this, 'tutor_course' ) );
60 +
61 + add_shortcode( 'tutor_instructor_list', array( $this, 'tutor_instructor_list' ) );
62 + add_action( 'wp_ajax_load_filtered_instructor', array( $this, 'load_filtered_instructor' ) );
63 + add_action( 'wp_ajax_nopriv_load_filtered_instructor', array( $this, 'load_filtered_instructor' ) );
64 +
65 + add_shortcode( 'tutor_cart', array( $this, 'tutor_cart_page' ) );
66 + add_shortcode( 'tutor_checkout', array( $this, 'tutor_checkout_page' ) );
67 +
68 + /**
69 + * Load more categories
70 + *
71 + * @since 2.0.0
72 + */
73 + add_action( 'wp_ajax_show_more', array( $this, 'show_more' ) );
74 + add_action( 'wp_ajax_nopriv_show_more', array( $this, 'show_more' ) );
20 75 }
21 76
22 77 /**
23 - * @return mixed
78 + * Instructor Registration Shortcode
24 79 *
25 - * Instructor Registration Shortcode
80 + * @since 1.0.0
26 81 *
27 - * @since v.1.0.0
82 + * @return mixed
28 83 */
29 - public function student_registration_form(){
84 + public function student_registration_form() {
30 85 ob_start();
31 - if (is_user_logged_in()){
32 - tutor_load_template( 'dashboard.student.logged-in' );
33 - }else{
34 - tutor_load_template( 'dashboard.student.registration' );
86 + if ( is_user_logged_in() ) {
87 + tutor_load_template( 'dashboard.logged-in' );
88 + } else {
89 + tutor_load_template( 'dashboard.registration' );
35 90 }
36 91 return apply_filters( 'tutor/student/register', ob_get_clean() );
37 92 }
38 93
39 94 /**
40 - * @return mixed
95 + * Tutor Dashboard for students
41 96 *
42 - * Tutor Dashboard for students
97 + * @since 1.0.0
43 98 *
44 - * @since v.1.0.0
99 + * @return mixed
45 100 */
46 - public function tutor_student_dashboard(){
101 + public function tutor_dashboard() {
102 + global $wp_query;
103 +
47 104 ob_start();
48 - if (is_user_logged_in()){
49 - tutor_load_template( 'dashboard.student.index' );
50 - }else{
51 - tutor_load_template( 'global.login' );
105 + if ( is_user_logged_in() ) {
106 + /**
107 + * Added isset() Condition to avoid infinite loop since v.1.5.4
108 + * This has cause error by others plugin, Such AS SEO
109 + */
110 +
111 + if ( ! isset( $wp_query->query_vars['tutor_dashboard_page'] ) ) {
112 + tutor_load_template( 'dashboard', array( 'is_shortcode' => true ) );
113 + }
114 + } else {
115 + /**
116 + * If user not logged in show login form instead of
117 + * popup sign-in button
118 + *
119 + * @since 2.1.3
120 + */
121 + $login_url = tutor_utils()->get_option( 'enable_tutor_native_login', null, true, true ) ? '' : wp_login_url( tutor()->current_url );
122 + $signin_link = '<a data-login_url="' . esc_url( $login_url ) . '" href="#" class="tutor-open-login-modal">' . __( 'Sign-In', 'tutor' ) . '</a>';
123 + /* translators: %s is anchor link for signin */
124 + echo sprintf( __( 'Please %s to view this page', 'tutor' ), $signin_link ); //phpcs:ignore
52 125 }
53 - return apply_filters( 'tutor_dashboard/student/index', ob_get_clean() );
126 + return apply_filters( 'tutor_dashboard/index', ob_get_clean() );
54 127 }
55 128
56 129 /**
57 - * @return mixed
58 - *
59 130 * Instructor Registration Shortcode
60 131 *
61 132 * @since v.1.0.0
133 + *
134 + * @return mixed
62 135 */
63 - public function instructor_registration_form(){
136 + public function instructor_registration_form() {
64 137 ob_start();
65 - if (is_user_logged_in()){
138 + if ( is_user_logged_in() ) {
66 139 tutor_load_template( 'dashboard.instructor.logged-in' );
67 - }else{
140 + } else {
68 141 tutor_load_template( 'dashboard.instructor.registration' );
69 142 }
70 143 return apply_filters( 'tutor_dashboard/student/index', ob_get_clean() );
71 144 }
72 145
73 -}
146 + /**
147 + * Short code for getting course
148 + *
149 + * @since 1.0.0
150 + *
151 + * @param mixed $atts attributes.
152 + *
153 + * @return string
154 + */
155 + public function tutor_course( $atts ) {
156 + $a = shortcode_atts(
157 + array(
158 + 'post_type' => apply_filters( 'tutor_course_archive_post_types', array( tutor()->course_post_type ) ),
159 + 'post_status' => 'publish',
160 +
161 + 'id' => '',
162 + 'exclude_ids' => '',
163 + 'category' => '',
164 +
165 + 'orderby' => 'ID',
166 + 'order' => 'DESC',
167 + 'count' => tutils()->get_option( 'courses_per_page', 12 ),
168 + 'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
169 + ),
170 + $atts
171 + );
172 +
173 + $a = apply_filters( 'tutor_get_course_list_filter_args', $a );
174 +
175 + $supported_filters = tutor_utils()->get_option( 'supported_course_filters', array() );
176 + $course_filter_category = array();
177 + $course_filter_exclude_ids = array();
178 + $course_filter_post_ids = array();
179 +
180 + if ( ! empty( $a['id'] ) ) {
181 + $ids = (array) explode( ',', $a['id'] );
182 + $a['post__in'] = $ids;
183 +
184 + if ( is_array( $ids ) && count( $ids ) && ! wp_doing_ajax() ) {
185 + $_GET['tutor-course-filter-post-ids'] = $ids;
186 + $course_filter_post_ids = $ids;
187 + }
188 + }
189 +
190 + if ( ! empty( $a['exclude_ids'] ) ) {
191 + $exclude_ids = (array) explode( ',', $a['exclude_ids'] );
192 + $a['post__not_in'] = $exclude_ids;
193 + if ( is_array( $exclude_ids ) && count( $exclude_ids ) && ! wp_doing_ajax() ) {
194 + $_GET['tutor-course-filter-exclude-ids'] = $exclude_ids;
195 + $course_filter_exclude_ids = $exclude_ids;
196 + }
197 + }
198 + if ( ! empty( $a['category'] ) ) {
199 + $category = (array) explode( ',', $a['category'] );
200 +
201 + $a['tax_query'] = array();
202 +
203 + $category_ids = array_filter(
204 + $category,
205 + function ( $id ) {
206 + return is_numeric( $id );
207 + }
208 + );
209 +
210 + $category_names = array_filter(
211 + $category,
212 + function ( $id ) {
213 + return ! is_numeric( $id );
214 + }
215 + );
216 +
217 + if ( ! empty( $category_ids ) ) {
218 + $a['tax_query'] = array(
219 + array(
220 + 'taxonomy' => CourseModel::COURSE_CATEGORY,
221 + 'field' => 'term_id',
222 + 'terms' => $category_ids,
223 + 'operator' => 'IN',
224 + ),
225 + );
226 +
227 + if ( is_array( $category_ids ) && count( $category_ids ) && ! wp_doing_ajax() ) {
228 + $_GET['tutor-course-filter-category'] = $category_ids;
229 + $course_filter_category = $category_ids;
230 + unset( $supported_filters['category'] );
231 + }
232 + }
233 +
234 + if ( ! empty( $category_names ) ) {
235 + $a['tax_query'] = array(
236 + array(
237 + 'taxonomy' => CourseModel::COURSE_CATEGORY,
238 + 'field' => 'name',
239 + 'terms' => $category_names,
240 + 'operator' => 'IN',
241 + ),
242 + );
243 + }
244 + }
245 + $a['posts_per_page'] = (int) $a['count'];
246 +
247 + wp_reset_query();
248 + $the_query = new \WP_Query( $a );
249 +
250 + /**
251 + * Pagination & course filter handle from query param on page load (without ajax)
252 + *
253 + * @since 2.4.0
254 + */
255 + $get = Input::has( 'course_filter' ) ? Input::sanitize_array( $_GET ) : array();
256 + if ( Input::has( 'course_filter' ) ) {
257 + $filter = ( new \Tutor\Course_Filter( false ) )->load_listing( $get, true );
258 + $the_query = new \WP_Query( $filter );
259 + }
260 +
261 + // Load the renderer now.
262 + ob_start();
263 +
264 + if ( $the_query->have_posts() ) {
265 + tutor_load_template(
266 + 'archive-course-init',
267 + array(
268 + 'course_filter' => isset( $atts['course_filter'] ) && 'on' === $atts['course_filter'],
269 + 'supported_filters' => $supported_filters,
270 + 'loop_content_only' => false,
271 + 'column_per_row' => isset( $atts['column_per_row'] ) ? $atts['column_per_row'] : null,
272 + 'course_per_page' => $a['posts_per_page'],
273 + 'show_pagination' => isset( $atts['show_pagination'] ) && 'on' === $atts['show_pagination'],
274 + 'the_query' => $the_query,
275 + 'current_page' => isset( $get['current_page'] ) ? (int) $get['current_page'] : 1,
276 + 'course_filter_category' => ! empty( $course_filter_category ) ? json_encode( $course_filter_category ) : null,
277 + 'course_filter_exclude_ids' => ! empty( $course_filter_exclude_ids ) ? json_encode( $course_filter_exclude_ids ) : null,
278 + 'course_filter_post_ids' => ! empty( $course_filter_post_ids ) ? json_encode( $course_filter_post_ids ) : null,
279 + )
280 + );
281 + } else {
282 + tutor_utils()->tutor_empty_state( tutor_utils()->not_found_text() );
283 + }
284 +
285 + $output = ob_get_clean();
286 + wp_reset_postdata();
287 + return $output;
288 + }
289 +
290 + /**
291 + * Prepare instructor list
292 + *
293 + * @param string $current_page current page.
294 + * @param mixed $atts atts for query.
295 + * @param array $cat_ids category ids.
296 + * @param string $keyword search keyword.
297 + *
298 + * @return array
299 + */
300 + private function prepare_instructor_list( $current_page, $atts, $cat_ids = array(), $keyword = '' ) {
301 +
302 + $default_pagination = tutor_utils()->get_option( 'pagination_per_page', 9 );
303 + $limit = (int) sanitize_text_field( tutor_utils()->array_get( 'count', $atts, $default_pagination ) );
304 + $page = $current_page - 1;
305 + $rating_filter = Input::post( 'rating_filter', '' );
306 +
307 + /**
308 + * Sort by Relevant | New | Popular
309 + *
310 + * @since 2.0.0
311 + */
312 + $short_by = Input::post( 'short_by', 'ASC' );
313 +
314 + $instructors = tutor_utils()->get_instructors( $limit * $page, $limit, $keyword, '', '', $short_by, 'approved', $cat_ids, $rating_filter );
315 + $instructors_count = tutor_utils()->get_instructors( $limit * $page, $limit, $keyword, '', '', $short_by, 'approved', $cat_ids, $rating_filter, true );
316 +
317 + $layout = sanitize_text_field( tutor_utils()->array_get( 'layout', $atts, '' ) );
318 + $layout = in_array( $layout, $this->instructor_layout ) ? $layout : tutor_utils()->get_option( 'instructor_list_layout', $this->instructor_layout[0] );
319 + $default_col = tutor_utils()->get_option( 'courses_col_per_row', 3 );
320 +
321 + $payload = array(
322 + 'instructors' => is_array( $instructors ) ? $instructors : array(),
323 + 'instructors_count' => $instructors_count,
324 + 'column_count' => sanitize_text_field( tutor_utils()->array_get( 'column_per_row', $atts, $default_col ) ),
325 + 'layout' => $layout,
326 + 'limit' => $limit,
327 + 'current_page' => $current_page,
328 + 'filter' => $atts,
329 + );
330 +
331 + return $payload;
332 + }
333 +
334 + /**
335 + * Short code for getting instructors
336 + *
337 + * @param array $atts array of attrs.
338 + *
339 + * @return string
340 + */
341 + public function tutor_instructor_list( $atts ) {
342 + ! is_array( $atts ) ? $atts = array() : 0;
343 +
344 + $current_page = (int) tutor_utils()->array_get( 'instructor-page', $_GET, 1 );
345 + $current_page = Input::get( 'instructor-page', 1, Input::TYPE_INT );
346 + $current_page = $current_page >= 1 ? $current_page : 1;
347 +
348 + $show_filter = isset( $atts['filter'] ) ? 'on' === $atts['filter'] : tutor_utils()->get_option( 'instructor_list_show_filter', false );
349 + $category_limit = (int) isset( $atts['category_limit'] ) ? $atts['category_limit'] : 0;
350 + $hide_empty_category = isset( $atts['hide_empty_category'] ) ? '1' == $atts['hide_empty_category'] : false;
351 + $atts['show_filter'] = $show_filter;
352 +
353 + // Get instructor list to sow.
354 + $payload = $this->prepare_instructor_list( $current_page, $atts );
355 + $payload['show_filter'] = $show_filter;
356 +
357 + ob_start();
358 + tutor_load_template( 'shortcode.tutor-instructor', $payload );
359 + $content = ob_get_clean();
360 +
361 + if ( $show_filter ) {
362 + $course_taxonomy = CourseModel::COURSE_CATEGORY;
363 + $term_args = array(
364 + 'taxonomy' => $course_taxonomy,
365 + 'hide_empty' => $hide_empty_category,
366 + 'orderby' => 'count',
367 + 'order' => 'DESC',
368 + 'number' => $category_limit,
369 + );
370 +
371 + $course_cats = get_terms( $term_args );
372 +
373 + $attributes = $payload;
374 + unset( $attributes['instructors'] );
375 +
376 + $payload = array(
377 + 'show_filter' => $show_filter,
378 + 'content' => $content,
379 + 'categories' => $course_cats,
380 + 'attributes' => array_merge( $atts, $attributes ),
381 + );
382 +
383 + ob_start();
384 +
385 + tutor_load_template( 'shortcode.instructor-filter', $payload );
386 +
387 + $content = ob_get_clean();
388 + }
389 +
390 + return $content;
391 + }
392 +
393 + /**
394 + * Load more categories
395 + * handle ajax request
396 + *
397 + * @since 2.0.0
398 + *
399 + * @return void send wp_json response
400 + */
401 + public function show_more() {
402 + global $wpdb;
403 + tutor_utils()->checking_nonce();
404 + $term_id = Input::post( 'term_id', 0, Input::TYPE_INT );
405 + $limit = 8;
406 + $course_taxonomy = CourseModel::COURSE_CATEGORY;
407 +
408 + $remaining_categories = $wpdb->get_var(
409 + $wpdb->prepare(
410 + "SElECT
411 + COUNT(*) AS total
412 + FROM {$wpdb->terms} AS term
413 + INNER JOIN {$wpdb->term_taxonomy} AS taxonomy
414 + ON taxonomy.term_id = term.term_id AND taxonomy.taxonomy = %s
415 + WHERE term.term_id < %d
416 + ORDER BY term.term_id DESC
417 + ",
418 + $course_taxonomy,
419 + $term_id
420 + )
421 + );
422 +
423 + $add_categories = $wpdb->get_results(
424 + $wpdb->prepare(
425 + "SElECT
426 + *
427 + FROM {$wpdb->terms} term
428 + INNER JOIN {$wpdb->term_taxonomy} as taxonomy
429 + ON taxonomy.term_id = term.term_id AND taxonomy.taxonomy = %s
430 + WHERE term.term_id < %d
431 + ORDER BY term.term_id DESC
432 + LIMIT %d
433 + ",
434 + $course_taxonomy,
435 + $term_id,
436 + $limit
437 + )
438 + );
439 + $show_more = false;
440 + if ( $remaining_categories > $limit ) {
441 + $show_more = true;
442 + }
443 + $response = array(
444 + 'categories' => $add_categories,
445 + 'show_more' => $show_more,
446 + 'remaining' => $remaining_categories,
447 + );
448 + wp_send_json_success( $response );
449 + exit;
450 + }
451 +
452 + /**
453 + * Filter instructor
454 + *
455 + * @since 1.0.0
456 + *
457 + * @return void send wp_json response
458 + */
459 + public function load_filtered_instructor() {
460 + tutor_utils()->checking_nonce();
461 +
462 + // phpcs:disable WordPress.Security.NonceVerification.Missing --nonce already verified
463 + $_post = tutor_sanitize_data( $_POST );
464 + $current_page = (int) sanitize_text_field( tutor_utils()->array_get( 'current_page', $_post, 1 ) );
465 + $keyword = (string) sanitize_text_field( tutor_utils()->array_get( 'keyword', $_post, '' ) );
466 +
467 + $category = (array) tutor_utils()->array_get( 'category', $_post, array() );
468 + $category = array_filter(
469 + $category,
470 + function ( $cat ) {
471 + return is_numeric( $cat );
472 + }
473 + );
474 +
475 + $data = $this->prepare_instructor_list( $current_page, $_post, $category, $keyword );
476 +
477 + ob_start();
478 + tutor_load_template( 'shortcode.tutor-instructor', $data );
479 + wp_send_json_success( array( 'html' => ob_get_clean() ) );
480 + exit;
481 + }
482 +
483 + /**
484 + * Tutor Cart Shortcode
485 + *
486 + * @since v.3.0.0
487 + *
488 + * @return mixed
489 + */
490 + public function tutor_cart_page() {
491 + ob_start();
492 + tutor_load_template( 'ecommerce.cart' );
493 + return apply_filters( 'tutor_ecommerce/cart', ob_get_clean() );
494 + }
495 +
496 + /**
497 + * Tutor Checkout Shortcode
498 + *
499 + * @since v.3.0.0
500 + *
501 + * @return mixed
502 + */
503 + public function tutor_checkout_page() {
504 + ob_start();
505 + tutor_load_template( 'ecommerce.checkout' );
506 + return apply_filters( 'tutor_ecommerce/checkout', ob_get_clean() );
507 + }
508 +}