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