PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.6.2
Tutor LMS – eLearning and online course solution v3.6.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 / Course_Filter.php
tutor / classes Last commit date
Addons.php 1 year ago Admin.php 1 year ago Ajax.php 1 year ago Announcements.php 1 year ago Assets.php 1 year ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Course.php 1 year ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 1 year ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 1 year ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 1 year ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Input.php 1 year ago Instructor.php 1 year ago Instructors_List.php 1 year ago Lesson.php 1 year ago Options_V2.php 1 year ago Permalink.php 2 years ago Post_types.php 1 year ago Private_Course_Access.php 1 year ago Q_And_A.php 1 year ago Question_Answers_List.php 3 years ago Quiz.php 1 year ago QuizBuilder.php 1 year ago Quiz_Attempts_List.php 1 year ago RestAPI.php 2 years ago Reviews.php 3 years ago Rewrite_Rules.php 2 years ago Shortcode.php 1 year ago Singleton.php 1 year ago Student.php 1 year ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 1 year ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 1 year ago Tutor.php 1 year ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 1 year ago Upgrader.php 1 year ago User.php 1 year ago Utils.php 1 year ago Video_Stream.php 3 years ago WhatsNew.php 2 years ago Withdraw.php 1 year ago Withdraw_Requests_List.php 1 year ago WooCommerce.php 1 year ago
Course_Filter.php
346 lines
1 <?php
2 /**
3 * Manage Course Filter
4 *
5 * @package Tutor
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 use Tutor\Models\CourseModel;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Course filter class
21 *
22 * @since 1.0.0
23 */
24 class Course_Filter {
25 /**
26 * Course Category
27 *
28 * @var string
29 */
30 private $category = 'course-category';
31 /**
32 * Course Tag
33 *
34 * @var string
35 */
36 private $tag = 'course-tag';
37 /**
38 * Course term id
39 *
40 * @var null|integer
41 */
42 private $current_term_id = null;
43
44 /**
45 * Constructor
46 *
47 * @since 1.0.0
48 *
49 * @param boolean $register_hook register hook or not.
50 * @return void|null
51 */
52 public function __construct( $register_hook = true ) {
53 if ( ! $register_hook ) {
54 return;
55 }
56 add_action( 'wp_ajax_tutor_course_filter_ajax', array( $this, 'load_listing' ), 10, 0 );
57 add_action( 'wp_ajax_nopriv_tutor_course_filter_ajax', array( $this, 'load_listing' ), 10, 0 );
58 add_filter( 'term_link', __CLASS__ . '::filter_course_category_term_link', 10, 3 );
59 }
60
61 /**
62 * Load course listing
63 *
64 * @since 1.0.0
65 *
66 * @param mixed $filters filters.
67 * @param boolean $return_filter return filterd data or not.
68 * @return mixed
69 */
70 public function load_listing( $filters = null, $return_filter = false ) {
71 ! $return_filter ? tutils()->checking_nonce() : 0;
72
73 $sanitized_post = tutor_sanitize_data( null == $filters ? $_POST : $filters ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
74 ! is_array( $sanitized_post ) ? $sanitized_post = array() : 0;
75
76 $default_per_page = tutils()->get_option( 'courses_per_page', 12 );
77 $courses_per_page = (int) tutils()->array_get( 'course_per_page', $sanitized_post, $default_per_page );
78
79 // Pagination arg.
80 $current_page = (int) Input::sanitize_request_data( 'current_page', 1 );
81 $paged = max( 1, $current_page );
82 $sanitized_post['current_page'] = $paged;
83
84 // Order arg.
85 $order_by = 'post_date';
86 $order = 'DESC';
87
88 if ( isset( $sanitized_post['course_order'] ) ) {
89 switch ( $sanitized_post['course_order'] ) {
90 case 'newest_first':
91 $order_by = 'post_date';
92 $order = 'DESC';
93 break;
94
95 case 'oldest_first':
96 $order_by = 'post_date';
97 $order = 'ASC';
98 break;
99
100 case 'course_title_az':
101 $order_by = 'post_title';
102 $order = 'ASC';
103 break;
104
105 case 'course_title_za':
106 $order_by = 'post_title';
107 $order = 'DESC';
108 break;
109 }
110 }
111
112 $args = array(
113 'post_status' => 'publish',
114 'post_type' => tutor()->course_post_type,
115 'posts_per_page' => $courses_per_page,
116 'paged' => $paged,
117 'orderby' => $order_by,
118 'order' => $order,
119 'tax_query' => array(
120 'relation' => 'AND',
121 ),
122 );
123
124 $post_ids_array = tutils()->array_get( 'tutor-course-filter-post-ids', $sanitized_post, array() );
125
126 $post_ids_array = array_map(
127 function ( $post_id ) {
128 return (int) $post_id;
129 },
130 $post_ids_array
131 );
132
133 if ( count( $post_ids_array ) ) {
134 $args['post__in'] = $post_ids_array;
135 }
136
137 $exclude_ids_array = tutils()->array_get( 'tutor-course-filter-exclude-ids', $sanitized_post, array() );
138
139 $exclude_ids_array = array_map(
140 function ( $exclude_id ) {
141 return (int) $exclude_id;
142 },
143 $exclude_ids_array
144 );
145
146 if ( count( $exclude_ids_array ) ) {
147 $args['post__not_in'] = $exclude_ids_array;
148 }
149 // Prepare taxonomy.
150 foreach ( array( 'category', 'tag' ) as $taxonomy ) {
151
152 $term_array = tutils()->array_get( 'tutor-course-filter-' . $taxonomy, $sanitized_post, array() );
153 ! is_array( $term_array ) ? $term_array = array( $term_array ) : 0;
154
155 $term_array = array_filter(
156 $term_array,
157 function( $term_id ) {
158 return is_numeric( $term_id );
159 }
160 );
161
162 if ( count( $term_array ) > 0 ) {
163 $tax_query = array(
164 'taxonomy' => $this->$taxonomy,
165 'field' => 'term_id',
166 'terms' => $term_array,
167 'operator' => 'IN',
168 );
169 array_push( $args['tax_query'], $tax_query );
170 }
171 }
172
173 // Prepare level and price type.
174 $is_membership = get_tutor_option( 'monetize_by' ) == 'pmpro' && tutils()->has_pmpro();
175 $level_price = array();
176 foreach ( array( 'level', 'price' ) as $type ) {
177
178 if ( $is_membership && 'price' === $type ) {
179 continue;
180 }
181
182 $type_array = tutils()->array_get( 'tutor-course-filter-' . $type, $sanitized_post, array() );
183 $type_array = array_map( 'sanitize_text_field', ( is_array( $type_array ) ? $type_array : array( $type_array ) ) );
184
185 if ( 'level' === $type && in_array( 'all_levels', $type_array, true ) ) {
186 continue;
187 }
188
189 if ( in_array( Course::PRICE_TYPE_PAID, $type_array, true ) ) {
190 $type_array = apply_filters( 'tutor_course_filter_price_type_paid', $type_array );
191 }
192
193 if ( count( $type_array ) > 0 ) {
194 $level_price[] = array(
195 'key' => 'level' === $type ? '_tutor_course_level' : '_tutor_course_price_type',
196 'value' => $type_array,
197 'compare' => 'IN',
198 );
199 }
200 }
201 count( $level_price ) ? $args['meta_query'] = $level_price : 0;
202
203 $search_key = sanitize_text_field( tutils()->array_get( 'keyword', $sanitized_post, null ) );
204 $search_key ? $args['s'] = $search_key : 0;
205
206 if ( isset( $sanitized_post['tutor_course_filter'] ) ) {
207 switch ( $sanitized_post['tutor_course_filter'] ) {
208
209 case 'newest_first':
210 $args['orderby'] = 'post_date';
211 $args['order'] = 'desc';
212 break;
213
214 case 'oldest_first':
215 $args['orderby'] = 'post_date';
216 $args['order'] = 'asc';
217 break;
218
219 case 'course_title_az':
220 $args['orderby'] = 'post_title';
221 $args['order'] = 'asc';
222 break;
223
224 case 'course_title_za':
225 $args['orderby'] = 'post_title';
226 $args['order'] = 'desc';
227 break;
228 }
229 }
230
231 // Return filters.
232 $filters = apply_filters( 'tutor_course_filter_args', $args );
233 if ( $return_filter ) {
234 return $filters;
235 }
236
237 ob_start();
238
239 query_posts( $filters );
240 tutor_load_template( 'archive-course-init', array_merge( array( 'loop_content_only' => true ), $sanitized_post ) );
241
242 wp_send_json_success( array( 'html' => ob_get_clean() ) );
243 exit;
244 }
245
246 /**
247 * Get current term ID
248 *
249 * @since 1.0.0
250 * @return integer
251 */
252 private function get_current_term_id() {
253
254 if ( null === $this->current_term_id ) {
255 $queried = get_queried_object();
256 $this->current_term_id = ( is_object( $queried ) && property_exists( $queried, 'term_id' ) ) ? $queried->term_id : false;
257 }
258
259 return $this->current_term_id;
260 }
261
262 /**
263 * Sort terms hierarchically
264 *
265 * @since 1.0.0
266 *
267 * @param array $terms term list.
268 * @param integer $parent_id parent ID.
269 * @return array
270 */
271 private function sort_terms_hierarchically( $terms, $parent_id = 0 ) {
272 $term_array = array();
273
274 foreach ( $terms as $term ) {
275 if ( $term->parent == $parent_id ) {
276 $term->children = $this->sort_terms_hierarchically( $terms, $term->term_id );
277 $term_array[] = $term;
278 }
279 }
280
281 return $term_array;
282 }
283
284 /**
285 * Render terms hierarchically
286 *
287 * @since 1.0.0
288 *
289 * @param array $terms term list.
290 * @param string $taxonomy taxonomy name.
291 * @return void
292 */
293 private function render_terms_hierarchically( $terms, $taxonomy ) {
294 $term_id = $this->get_current_term_id();
295
296 foreach ( $terms as $term ) {
297 ?>
298 <li class="tutor-list-item">
299 <label>
300 <input type="checkbox" class="tutor-form-check-input" name="tutor-course-filter-<?php echo esc_attr( $taxonomy ); ?>" value="<?php echo esc_attr( $term->term_id ); ?>" <?php echo esc_attr( $term->term_id == $term_id ? 'checked="checked"' : '' ); ?>/>
301 <?php echo esc_html( $term->name ); ?>
302 </label>
303 </li>
304 <?php isset( $term->children ) ? $this->render_terms_hierarchically( $term->children, $taxonomy ) : 0; ?>
305 <?php
306 }
307 }
308
309 /**
310 * Render terms
311 *
312 * @since 1.0.0
313 *
314 * @param string $taxonomy taxonomy name.
315 * @return void
316 */
317 public function render_terms( $taxonomy ) {
318 $terms = get_terms(
319 array(
320 'taxonomy' => $this->$taxonomy,
321 'hide_empty' => true,
322 )
323 );
324 $this->render_terms_hierarchically( $this->sort_terms_hierarchically( $terms ), $taxonomy );
325 }
326
327 /**
328 * Filter course-category term's permalink
329 *
330 * Add a query param so that course filter can work
331 *
332 * @param string $termlink default term link.
333 * @param \WP_Term $term term obj.
334 * @param string $taxonomy taxonomy.
335 *
336 * @return string customized term link
337 */
338 public static function filter_course_category_term_link( string $termlink, \WP_Term $term, string $taxonomy ) {
339 if ( CourseModel::COURSE_CATEGORY === $taxonomy ) {
340 $termlink = add_query_arg( 'tutor-course-filter-category', $term->term_id, $termlink );
341
342 }
343 return $termlink;
344 }
345 }
346