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