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