PluginProbe
Filter Everything — WordPress & WooCommerce Filters / trunk
Filter Everything — WordPress & WooCommerce Filters vtrunk
1.9.6 1.9.5 1.9.4 1.9.3 1.9.2.2 1.9.2.1 trunk 1.2.1 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.4.1 1.4.4 1.4.5 1.4.8 1.4.9 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 1.6.3 All 51 releases
filter-everything / src / wpc-utility-functions.php

wpc-utility-functions.php in Filter Everything — WordPress & WooCommerce Filters trunk, at src/wpc-utility-functions.php

466 lines 15.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined('ABSPATH') ) {
4 exit;
5 }
6
7 use FilterEverything\Filter\Container;
8
9
10 function flrt_get_set_location_groups( $no_selection = false ){
11 if( ! is_admin() ){
12 return array();
13 }
14
15 $fields = [];
16
17 if( $no_selection ){
18 $fields['empty'] = array(
19 'group_label' => esc_html__('No page selected', 'filter-everything'),
20 'entities' => array(
21 // This should be renamed as it looks like WP Page post type
22 'no_page___no_page' => esc_html__('The same page as for filtered posts', 'filter-everything'),
23 )
24 );
25 }
26
27 // Common WP pages
28 $fields['common'] = array(
29 'group_label' => esc_html__('Common', 'filter-everything'),
30 'entities' => array(
31 // This should be renamed as it looks like WP Page post type
32 'common___common' => esc_html__('Common WordPress pages', 'filter-everything'),
33 )
34 );
35
36 // Get Taxonomies
37 $excludedTaxes = flrt_excluded_taxonomies();
38 $args = array( 'public' => true, 'rewrite' => true );
39 $taxonomies = get_taxonomies( $args, 'objects' );
40 $tax_entitites = [];
41
42 foreach ( $taxonomies as $t => $taxonomy ) {
43 if ( ! in_array( $taxonomy->name, $excludedTaxes ) ) {
44 $label = ucwords( flrt_ucfirst( mb_strtolower( $taxonomy->label ) ) );
45 $tax_entitites[ 'taxonomy___' .$taxonomy->name] = $label;
46 }
47 }
48
49 if( ! empty( $tax_entitites ) ){
50 $fields['taxonomies'] = array(
51 'group_label' => esc_html__('Taxonomies', 'filter-everything'),
52 'entities' => $tax_entitites
53 );
54 }
55
56 // Get Post types
57 $filterSet = Container::instance()->getFilterSetService();
58 $post_types = $filterSet->getPostTypes();
59
60 if( ! empty( $post_types ) ){
61 $new_post_types = [];
62 foreach ($post_types as $post_type_key => $post_type_label ){
63 $new_post_types[ 'post_type___' .$post_type_key ] = $post_type_label;
64 }
65
66 $fields['post_types'] = array(
67 'group_label' => esc_html__('Post types', 'filter-everything'),
68 'entities' => $new_post_types
69 );
70 }
71
72 $fields['author'] = array(
73 'group_label' => esc_html__( 'Author', 'filter-everything' ),
74 'entities' => array(
75 'author___author' => esc_html__( 'Author', 'filter-everything' )
76 )
77 );
78
79 unset( $filterSet );
80
81 return apply_filters( 'wpc_set_location_groups', $fields, $no_selection );
82 }
83
84 function flrt_get_set_location_terms( $wpPageType = 'common___common', $postType = 'post', $full_label = true )
85 {
86 $fields = [];
87 if( ! is_admin() ){
88 return $fields;
89 }
90
91 $wpPageType = $wpPageType ? $wpPageType : 'common___common';
92
93 $pageTypeVars = explode('___', $wpPageType);
94 $typeKey = $pageTypeVars[0];
95 $typeValue = isset( $pageTypeVars[1] ) ? $pageTypeVars[1] : false;
96
97 // @todo No posts, No tags what to show in Dropdown?
98 switch ( $typeKey ){
99 case 'no_page':
100 $fields = flrt_get_no_page_terms();
101 break;
102 case 'common':
103 $fields = flrt_get_common_location_terms( $postType );
104 break;
105 case 'post_type':
106 $fields = flrt_get_post_type_location_terms( $typeValue, $full_label );
107 break;
108 case 'taxonomy':
109 $fields = flrt_get_taxonomy_location_terms( $typeValue, $full_label );
110 break;
111 case 'author':
112 $fields = flrt_get_author_location_terms();
113 break;
114 }
115
116 return apply_filters( 'wpc_set_location_terms', $fields, $wpPageType, $postType, $full_label );
117 }
118
119 function flrt_get_common_location_terms( $postType = 'post' )
120 {
121 $fields = [];
122 $link = get_post_type_archive_link( $postType );
123
124 $lang = '';
125
126 // In case of Polylang
127 if( function_exists('pll_home_url') ){
128 global $post_id;
129 $post_id = ( isset( $_POST['postId'] ) && $_POST['postId'] ) ? $_POST['postId'] : $post_id;
130 $lang = pll_get_post_language( $post_id );
131 $pll_language = PLL()->model->get_language( $lang );
132
133 if( $postType === 'post' ){
134 $page_for_posts_id = get_option( 'page_for_posts' );
135 if( $page_for_posts_id ){
136 $link = get_permalink( flrt_maybe_has_translation( $page_for_posts_id, $lang ) );
137 }else{
138 $link = pll_home_url($lang);
139 }
140 }else{
141 $translated_post_types = PLL()->model->get_translated_post_types();
142 if ( array_key_exists( $postType, $translated_post_types ) || in_array( $postType, $translated_post_types, true ) ){
143 $link = PLL()->links_model->switch_language_in_link( $link, $pll_language );
144 }
145 }
146 }
147
148 // All archive pages for this Post Type
149 if( $link ){
150 $fields = array( '1' => array(
151 'label' => esc_html__('All archive pages for this Post Type', 'filter-everything'),
152 'data-link' => $link
153 ),
154 );
155 }
156
157 // Blog page
158 $page_for_posts_id = get_option( 'page_for_posts' );
159 if( $page_for_posts_id ){
160 $blog_page_link = get_permalink( flrt_maybe_has_translation( $page_for_posts_id, $lang ) );
161 $fields['common___page_for_posts'] = array(
162 'label' => esc_html__('Blog page', 'filter-everything'),
163 'data-link' => $blog_page_link
164 );
165 }
166
167 // Homepage
168 $page_on_front_id = get_option( 'page_on_front' );
169 if( $page_on_front_id ){
170 $page_on_front_link = get_permalink( $page_on_front_id );
171 if( function_exists('pll_home_url') ){
172 $page_on_front_link = pll_home_url($lang);
173 }
174
175 $fields['common___page_on_front'] = array(
176 'label' => esc_html__('Homepage' ),
177 'data-link' => $page_on_front_link
178 );
179 if(!$link){
180 $fields['common___page_on_front']['selected'] = true;
181 }
182 }
183
184 // In case of Polylang plugin
185 $home_url = trailingslashit( get_bloginfo('url') );
186 if( function_exists('pll_home_url') ){
187 $translated_post_types = PLL()->model->get_translated_post_types();
188 if ( array_key_exists( $postType, $translated_post_types ) || in_array( $postType, $translated_post_types, true ) ){
189 $home_url = trailingslashit( pll_home_url($lang) );
190 }
191 }
192
193 $s = isset( $_GET['s'] ) ? filter_input( INPUT_GET, 's', FILTER_SANITIZE_SPECIAL_CHARS ) : 'a';
194 $fields['common___search_results'] = array(
195 'label' => esc_html__('Search results page for selected Post Type', 'filter-everything'),
196 'data-link' => add_query_arg( array('s' => $s, 'post_type' => $postType ), $home_url )
197 );
198
199 if( function_exists('is_woocommerce') ){
200
201 $shop_page_id = wc_get_page_id( 'shop' );
202 $shop_permalink = get_permalink( $shop_page_id );
203
204 if( function_exists('pll_home_url') ){
205 $translated_post_types = PLL()->model->get_translated_post_types();
206 if ( array_key_exists( 'product', $translated_post_types ) || in_array( 'product', $translated_post_types, true ) ){
207 $shop_permalink = PLL()->links_model->switch_language_in_link( $shop_permalink, $pll_language );
208 }
209 }
210
211 if ( $shop_page_id > 0 ) {
212 $fields['common___shop_page'] = array(
213 'label' => esc_html__('Shop page', 'filter-everything' ),
214 'data-link' => $shop_permalink
215 );
216 }
217 }
218
219 return $fields;
220 }
221
222 function flrt_get_post_type_location_terms( $postType = 'post', $full_label = false )
223 {
224 $postType = $postType ? $postType : 'post';
225 $fields = [];
226
227 $args = array(
228 'post_type' => $postType,
229 'posts_per_page' => -1,
230 'post_status' => array( 'publish', 'private' ),
231 'orderby' => 'title',
232 'order' => 'ASC',
233 'fields' => 'ids'
234 );
235
236 $allPosts = new \WP_Query();
237 $allPosts->parse_query($args);
238 $ids = $allPosts->get_posts();
239
240 $ids = apply_filters( 'wpc_post_type_location_terms', $ids, $postType );
241
242 $postTypeObject = get_post_type_object( $postType );
243 $label = isset( $postTypeObject->labels->singular_name ) ? $postTypeObject->labels->singular_name : flrt_ucfirst( $postType );
244
245 if ( ! empty( $ids ) ) {
246 $firstPostId = reset($ids );
247 $firstPostlink = get_permalink( $firstPostId );
248
249 if( $full_label ){
250 $any_label = sprintf( esc_html__('Any %s page (for a common query across all %s pages)', 'filter-everything'), $label, $label );
251 } else {
252 $any_label = sprintf( esc_html__('Any %s page', 'filter-everything'), $label );
253 }
254
255 $fields[$postType.'___-1'] = array(
256 'label' => $any_label,
257 'data-link' => $firstPostlink
258 );
259
260 unset( $firstPostId, $firstPostlink );
261
262 foreach ( $ids as $postId ){
263 $fields[$postType.'___'.$postId] = array(
264 'label' => get_the_title( $postId ),
265 'data-link' => get_permalink( $postId )
266 );
267 }
268 }else{
269 $fields[$postType.'___0'] = array(
270 'label' => sprintf(esc_html__('— There is no any %s yet —', 'filter-everything'), $label ),
271 'data-link' => ''
272 );
273 }
274
275 return $fields;
276 }
277
278 function flrt_get_taxonomy_location_terms( $taxonomy, $full_label = true )
279 {
280 $fields = [];
281
282 if( ! $taxonomy ){
283 return $fields;
284 }
285
286 $args = array(
287 'taxonomy' => $taxonomy,
288 'hide_empty' => false,
289 'fields' => 'id=>name'
290 );
291
292 $terms = get_terms( $args );
293
294 // The taxonomy may be unavailable (e.g. WooCommerce deactivated while a
295 // Filter Set still targets product_cat) — get_terms() then returns a
296 // WP_Error. Treat it as "no terms" so it never propagates to filters as an array.
297 if ( is_wp_error( $terms ) ) {
298 $terms = array();
299 }
300
301 $taxonomyObject = get_taxonomy( $taxonomy );
302
303 $label = isset( $taxonomyObject->labels->singular_name ) ? $taxonomyObject->labels->singular_name : flrt_ucfirst( $taxonomy );
304
305 $terms = apply_filters( 'wpc_taxonomy_location_terms', $terms, $taxonomy );
306
307 if( ! is_wp_error( $terms ) && ! empty( $terms ) ){
308
309 $firstTermId = array_key_first($terms);
310 $firstTermlink = get_term_link( $firstTermId, $taxonomy );
311 $firstTermlink = ( is_wp_error( $firstTermlink ) ) ? '' : $firstTermlink;
312
313 if( $full_label ){
314 $any_label = sprintf(esc_html__('Any %s (for a common query across all %s pages)', 'filter-everything'), $label, $label );
315 }else{
316 $any_label = sprintf(esc_html__('Any %s', 'filter-everything'), $label );
317 }
318
319 $fields[$taxonomy.'___-1'] = array(
320 'label' => $any_label,
321 'data-link' => $firstTermlink
322 );
323 unset( $firstTermId, $firstTermlink);
324
325 foreach ( $terms as $termId => $termName ){
326
327 $link = get_term_link( $termId, $taxonomy );
328 $link = ( is_wp_error( $link ) ) ? '' : $link;
329
330 $fields[$taxonomy.'___'.$termId] = array(
331 'label' => $termName,
332 'data-link' => $link
333 );
334 }
335 }else{
336 $fields[$taxonomy.'___0'] = array(
337 'label' => sprintf(esc_html__('— There is no any %s yet —', 'filter-everything'), $label ),
338 'data-link' => ''
339 );
340 }
341
342 return $fields;
343 }
344
345 function flrt_get_author_location_terms()
346 {
347 $fields = [];
348 $em = Container::instance()->getEntityManager();
349 $authors = $em->getAuthorTermsForDropdown( true );
350
351 $authors = apply_filters( 'wpc_author_location_terms', $authors );
352
353 if (! empty( $authors )){
354 $label = esc_html__('Author');
355
356 $firstAuthorKey = array_key_first($authors);
357 $keyParts = explode( ":", $firstAuthorKey );
358 $firstAuthorId = intval( $keyParts[1] );
359 $firstAuthorLink = get_author_posts_url( $firstAuthorId );
360
361 $fields['author___-1'] = array(
362 'label' => sprintf(esc_html__('Any %s (for a common query across all %s pages)', 'filter-everything'), $label, $label ),
363 'data-link' => $firstAuthorLink
364 );
365
366 unset( $firstAuthorKey, $keyParts, $firstAuthorId, $firstAuthorLink );
367
368 foreach ( $authors as $authorKey => $authorLabel ){
369 $keyParts = explode( ":", $authorKey );
370 $authorId = intval( $keyParts[1] );
371 $authorLink = get_author_posts_url( $authorId );
372
373 $fields['author___'.$authorId] = array(
374 'label' => $authorLabel,
375 'data-link' => $authorLink
376 );
377 }
378
379 }
380
381 unset( $em );
382
383 return $fields;
384 }
385
386 function flrt_get_no_page_terms()
387 {
388 $fields = [];
389
390 $fields['no_page___no_page'] = array(
391 'label' => esc_html__('— No page for selection —', 'filter-everything'),
392 'data-link' => ''
393 );
394
395 return $fields;
396 }
397
398 function flrt_filter_set_front_link($post_id)
399 {
400 $fss = Container::instance()->getFilterSetService();
401 $set_settings_fields = $fss->getSettingsLocationTypeFields($post_id);
402 $link = '';
403 foreach ($set_settings_fields as $key => $attributes) {
404 if ($attributes['id'] == $fss->generateFieldId('post_name')) {
405 $current_index = isset($attributes['value']) ? $attributes['value'] : '';
406 $options = !empty($attributes['options']) ? $attributes['options'] : [];
407 if (isset($options[$current_index]['data-link'])) {
408 $link = esc_attr($options[$current_index]['data-link']);
409 }
410 }
411 }
412 return $link;
413 }
414
415 /**
416 * Front page URL for the «Select visually» container picker: the page where
417 * the user's most likely Filter Set actually filters. Candidates in order:
418 * a WooCommerce product Set, a post Set, any other (CPT) Set — the higher
419 * Priority (menu_order) Set first within each group. With no resolvable Set
420 * at all: the shop page on WooCommerce sites, the blog page otherwise.
421 */
422 function flrt_default_selector_page_link()
423 {
424 $sets = get_posts( array(
425 'post_type' => FLRT_FILTERS_SET_POST_TYPE,
426 'post_status' => 'publish',
427 'numberposts' => -1,
428 'orderby' => array( 'menu_order' => 'DESC', 'date' => 'ASC' ),
429 ) );
430
431 $woo = function_exists( 'wc_get_page_permalink' );
432
433 $candidates = array( 'product' => array(), 'post' => array(), 'other' => array() );
434 foreach ( $sets as $set ) {
435 // Sets keep their filtered post type in post_excerpt; empty means 'post'
436 $type = $set->post_excerpt ? $set->post_excerpt : 'post';
437 if ( $type === 'product' && $woo ) {
438 $candidates['product'][] = $set->ID;
439 } elseif ( $type === 'post' ) {
440 $candidates['post'][] = $set->ID;
441 } else {
442 // Without WooCommerce 'product' is just another CPT
443 $candidates['other'][] = $set->ID;
444 }
445 }
446
447 foreach ( array_merge( $candidates['product'], $candidates['post'], $candidates['other'] ) as $set_id ) {
448 $link = flrt_filter_set_front_link( $set_id );
449 if ( ! empty( $link ) ) {
450 return $link;
451 }
452 }
453
454 if ( $woo ) {
455 $link = wc_get_page_permalink( 'shop' );
456 if ( ! empty( $link ) ) {
457 return $link;
458 }
459 }
460
461 // get_post_type_archive_link('post') is false when the front page is
462 // static and no posts page is assigned
463 $link = get_post_type_archive_link( 'post' );
464
465 return $link ? $link : home_url( '/' );
466 }