PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.9.14
Tutor LMS – eLearning and online course solution v3.9.14
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 11 months ago Admin.php 2 months ago Ajax.php 9 months ago Announcements.php 1 year ago Assets.php 2 months ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Config.php 11 months ago Container.php 11 months ago Course.php 2 months ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 5 months 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 9 months ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Icon.php 8 months ago Input.php 1 year ago Instructor.php 2 months ago Instructors_List.php 2 months ago Lesson.php 2 weeks ago Options_V2.php 7 months ago Permalink.php 2 years ago Post_types.php 1 year ago Private_Course_Access.php 1 year ago Q_And_A.php 10 months ago Question_Answers_List.php 11 months ago Quiz.php 2 weeks ago QuizBuilder.php 2 days ago Quiz_Attempts_List.php 9 months ago RestAPI.php 2 years ago Reviews.php 9 months ago Rewrite_Rules.php 2 years ago Shortcode.php 9 months ago Singleton.php 1 year ago Student.php 2 months ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 9 months ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 3 weeks ago Tutor.php 2 months ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 8 months ago Upgrader.php 9 months ago User.php 4 months ago Utils.php 2 days ago Video_Stream.php 3 years ago WhatsNew.php 9 months ago Withdraw.php 2 days ago Withdraw_Requests_List.php 11 months ago WooCommerce.php 2 days 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