PluginProbe
Filter Everything — WordPress & WooCommerce Filters / 1.9.7
Filter Everything — WordPress & WooCommerce Filters v1.9.7
1.9.7 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 All 52 releases
← All changes | src/UrlManager.php +190 -189 1.5.11.9.7 View file →
@@ -1,10 +1,10 @@
1 1 <?php
2 2
3 3 namespace FilterEverything\Filter;
4 4
5 -if ( ! defined('WPINC') ) {
6 - wp_die();
5 +if ( ! defined('ABSPATH') ) {
6 + exit;
7 7 }
8 8
9 9 class UrlManager
10 10 {
@@ -9,10 +9,18 @@
9 9 class UrlManager
10 10 {
11 11 private $separator;
12 12
13 - private $order;
13 + private $em;
14 14
15 + private $wpManager;
16 +
17 + private $entityAndEnamesOrder;
18 +
19 + private $actualFilters;
20 +
21 + private $enameActualFilters;
22 +
15 23 private $resetUrl;
16 24
17 25 private $logicParam = 'logic'; // Should be an option
18 26
@@ -19,115 +27,194 @@
19 27 private $valuesSeparator = FLRT_QUERY_TERMS_SEPARATOR; // Should be an option
20 28
21 29 public function __construct()
22 30 {
23 - $this->separator = FLRT_PREFIX_SEPARATOR;
24 - $fse = Container::instance()->getFilterService();
25 - $this->order = $fse->getFiltersOrder();
26 - $this->permalinksOn = defined('FLRT_PERMALINKS_ENABLED') ? FLRT_PERMALINKS_ENABLED : false;
31 + $this->separator = FLRT_PREFIX_SEPARATOR;
32 + $fse = Container::instance()->getFilterService();
33 + $this->em = Container::instance()->getEntityManager();
34 + $this->wpManager = Container::instance()->getWpManager();
35 + $this->entityAndEnamesOrder = $fse->getFiltersOrder();
36 + $this->actualFilters = $this->em->getSetsRelatedFilters();
27 37
28 - if( $this->permalinksOn ){
29 - add_filter( 'wpc_filter_term_url', array( $this, 'processPermalink' ) );
38 + // E_name actual filters
39 + foreach ( $this->actualFilters as $actualFilter ) {
40 + $this->enameActualFilters[ $actualFilter['entity'].'#'.$actualFilter['e_name'] ] = $actualFilter;
30 41 }
31 42
32 43 unset( $fse );
33 44 }
34 45
35 - public function processPermalink( $url )
46 + public function getTermUrl( $termSlug = '', $e_name = '', $entity = '', $resetUrl = '', $exclude = [] )
36 47 {
37 - $em = Container::instance()->getEntityManager();
38 - $parts = explode('?', $url);
48 + $fse = Container::instance()->getFilterService();
49 + $e_nameActualFilters = $this->enameActualFilters;
50 + $url = $baseUrl = $resetUrl ? $resetUrl : $this->getResetUrl();
51 + $parts = [];
52 + $entity_and_e_name = $entity.'#'.$e_name;
39 53
40 - if (count($parts) !== 2) {
41 - return $url;
54 + if ( empty( $e_nameActualFilters ) ) {
55 + $the_filter = $this->getSingleActualFilter( $e_name );
56 + if( isset( $the_filter['entity'] ) && isset( $the_filter['e_name'] ) ) {
57 + $entity_and_e_name = $the_filter['entity'].'#'.$the_filter['e_name'];
58 + $e_nameActualFilters[$entity_and_e_name] = $the_filter;
59 + }
42 60 }
43 61
44 - list($path, $get) = $parts;
62 + foreach( $this->entityAndEnamesOrder as $entityAndEName ) {
45 63
46 - $query = [];
47 - $parts = [];
64 + if ( isset( $e_nameActualFilters[$entityAndEName] ) ) {
48 65
49 - parse_str( $get, $query );
66 + $filter = $e_nameActualFilters[$entityAndEName];
50 67
51 - foreach( $this->getEnamesOrder() as $entityName ){
68 + if ( empty( $filter['values'] ) && $entity_and_e_name !== $entityAndEName ) {
69 + continue;
70 + }
52 71
53 - $filter = $em->getFilterBy( 'e_name', $entityName, array( 'slug', 'e_name', 'logic', 'in_path' ) );
72 + if( $entity_and_e_name === $entityAndEName ){
73 + $queriedValues = $filter['values'];
74 + // Add only single filter value for views with single selection
75 + if( in_array( $filter['view'], array('dropdown', 'radio') ) ){
76 + if( in_array( $termSlug, $queriedValues ) ){
77 + $position = array_search( $termSlug, $queriedValues );
78 + unset( $queriedValues[$position] );
79 + }else{
80 + $queriedValues = array( $termSlug );
81 + }
82 + } else {
83 + // For Post Meta Num values have array index as termslug
84 + if ( in_array( $filter['entity'], [ 'post_meta_num', 'tax_numeric', 'post_date', 'post_meta_date' ] ) ) {
85 + if ( in_array( $termSlug, array_keys( $queriedValues ) ) ) {
86 + unset( $queriedValues[$termSlug] );
87 + } else {
88 + $queriedValues[] = $termSlug;
89 + }
90 + } else if ( in_array( $filter['view'], array('rating') ) ) {
91 + if(isset($filter['selected_and_above']) && $filter['selected_and_above'] === 'yes'){
92 + if(isset($exclude['rating_slug'])){
93 + foreach ($queriedValues as $key => $value){
94 + unset( $queriedValues[$key] );
95 + }
96 + }
54 97
55 - if( ! $filter || empty( $filter ) || ( $filter['in_path'] !== 'yes' ) ){
56 - continue;
57 - }
98 + if(!isset($exclude['rating_slug'])){
99 + $pieces = explode("-", $termSlug);
100 + $rating = isset( $pieces[1] ) ? $pieces[1] : 0;
101 + $i = 5;
102 + while ($i >= 1) {
103 + $new_termSlug = 'rated-' . $i;
104 + if(in_array( $new_termSlug, $queriedValues )){
105 + $position = array_search( $new_termSlug, $queriedValues );
106 + unset( $queriedValues[$position] );
107 + }
58 108
59 - if( isset( $query[ $filter['slug'] ] ) ){
109 + if($i >= $rating){
110 + $queriedValues[] = $new_termSlug;
111 + }
112 + $i--;
113 + }
114 + }
115 + } else if(in_array( $termSlug, $queriedValues ) && isset($filter['selected_and_above']) && $filter['selected_and_above'] === 'no'){
116 + $position = array_search( $termSlug, $queriedValues );
117 + unset( $queriedValues[$position] );
118 + }else{
119 + $queriedValues = array( $termSlug );
120 + }
121 + } else {
122 + if ( in_array( $termSlug, $queriedValues ) ) {
123 + $position = array_search( $termSlug, $queriedValues );
124 + unset( $queriedValues[$position] );
125 + } else {
126 + $queriedValues[] = $termSlug;
127 + }
128 + }
129 + }
130 + $filter['values'] = $queriedValues;
131 + }
60 132
61 - $termSlugs = $em->safeExplodeFilterValues( $query[ $filter['slug'] ], $filter['slug'], $this->getValuesSeparator() );
62 - $termSlugs = $em->safeImplodeFilterValues( $termSlugs, $this->getValuesSeparator() );
133 + foreach ($filter['values'] as $val_id => $term_slug){
134 + if(!empty($exclude[$term_slug]) && $exclude[$term_slug] === true){
135 + unset($filter['values'][$val_id]);
136 + }
137 + }
63 138
64 - $parts[] = $this->buildFilterSegment( $termSlugs, $filter );
139 + if( ! empty( $filter['values'] ) ) {
140 + $filter['values'] = $fse->sortTerms( $filter['values'] );
141 +
142 + if ( in_array( $filter['entity'], ['post_meta_num', 'tax_numeric'] ) ) {
143 + foreach ($filter['values'] as $edge => $value) {
144 + $paramName = $edge . '_' . $filter['slug'];
145 + $url = flrt_add_query_arg($this->getParamName($paramName), $value, $url);
146 + }
147 + } elseif ( in_array($filter['entity'], ['post_date', 'post_meta_date'] ) ) {
148 + foreach ($filter['values'] as $edge => $date_value) {
149 + $paramName = $filter['slug'] . '_' . $edge;
150 + $date_value = str_replace(' ', FLRT_DATE_TIME_SEPARATOR, $date_value);
151 + $url = flrt_add_query_arg($this->getParamName($paramName), $date_value, $url);
152 + }
153 + } else {
154 + if ( defined('FLRT_PERMALINKS_ENABLED') && FLRT_PERMALINKS_ENABLED ) {
155 + $parts[] = $this->buildFilterSegment( $filter['values'], $filter );
156 + } else {
157 + $url = flrt_add_query_arg( $this->getParamName($filter['slug'] ), implode($this->getValuesSeparator(), $filter['values']), $url);
158 + }
159 + }
160 + }
161 +
65 162 }
66 -
67 - unset( $query[ $filter['slug'] ] );
68 - unset( $query[ $this->getLogicParamName( $filter['slug'] ) ] );
69 163 }
70 164
71 - $path = trailingslashit( $path ) . implode('/', $parts );
72 - $path = user_trailingslashit( $path );
73 -
74 - $url = flrt_add_query_arg( $query, $path );
75 -
76 - unset($em);
77 -
78 - return $url;
79 - }
80 -
81 - private function getEnamesOrder()
82 - {
83 - $e_namesOrder = [];
84 - $fse = Container::instance()->getFilterService();
85 -
86 - foreach( $this->order as $entityName ){
87 - $e_namesOrder[] = $fse->getEntityEname( $entityName );
165 + // Assembly permalinks
166 + if ( defined('FLRT_PERMALINKS_ENABLED') && FLRT_PERMALINKS_ENABLED ) {
167 + $pieces = explode('?', $baseUrl);
168 + $path = $pieces[0];
169 + $path = trailingslashit( $path ) . implode('/', $parts );
170 + $path = user_trailingslashit( $path );
171 + $url = str_replace( $pieces[0], $path, $url );
88 172 }
89 173
90 - unset( $fse );
91 -
92 - return $e_namesOrder;
93 - }
94 -
95 - public function getSubArrayBy( $byKey, $value, &$array )
96 - {
97 - foreach ( $array as $index => $subArray ) {
98 - if( isset( $subArray[ $byKey ] ) && $subArray[ $byKey ] === $value ){
99 - return $subArray;
174 + if ( ! isset( $exclude['srch'] ) ){
175 + $search = isset( $_GET['srch'] ) ? filter_input( INPUT_GET, 'srch', FILTER_SANITIZE_SPECIAL_CHARS ) : false;
176 + if ( $search ){
177 + $url = flrt_add_query_arg( 'srch' , $search, $url );
100 178 }
101 179 }
102 180
103 - return false;
181 + return apply_filters( 'wpc_filter_term_url', $url );
104 182 }
105 183
106 - public function getFormActionUrl( $queryParams = false )
184 + public function getFormActionOrFullPageUrl( $fullPageUrl = false )
107 185 {
108 186 $query = [];
109 187 $homeUrl = parse_url(home_url());
110 188 $post = Container::instance()->getThePost();
111 - $requestedUri = isset( $post['flrt_ajax_link'] ) ? $post['flrt_ajax_link'] : $homeUrl['scheme'].'://'.$homeUrl['host'] . $_SERVER['REQUEST_URI'];
112 189
190 + if( isset( $post['flrt_ajax_link'] ) ){
191 + $requestedUri = $post['flrt_ajax_link'];
192 + }else{
193 + $requestedUri = $homeUrl['scheme'].'://'.$homeUrl['host'];
194 + if( isset( $homeUrl['port'] ) && $homeUrl['port'] ){
195 + $requestedUri .= ":".$homeUrl['port'];
196 + }
197 + $requestedUri .= $_SERVER['REQUEST_URI'];
198 + }
199 +
113 200 $pieces = parse_url( $requestedUri );
114 - $fullPath = $pieces['scheme']."://".$pieces['host'].$pieces['path'];
201 + $fullPath = $pieces['scheme']."://".$pieces['host'];
202 + if( isset( $pieces['port'] ) && $pieces['port'] ){
203 + $fullPath .= ":".$pieces['port'];
204 + }
205 + $fullPath .= $pieces['path'];
115 206
116 207 if( isset( $pieces['query'] ) ){
117 208 parse_str( $pieces['query'], $query );
118 209 }
119 210
120 - $formAction = preg_replace('%\/page/[0-9]+%', '', $fullPath);
121 - $formAction = preg_replace('%\/comment\-page\-[0-9]+%', '', $formAction);
122 - $formAction = preg_replace('%\/[0-9]+[\/]?$%m', '', $formAction);
211 + $formAction = $this->removePaginationBase( $fullPath );
123 212
124 - $formAction = FLRT_PERMALINKS_ENABLED ? user_trailingslashit( $formAction ) : rtrim( $formAction, '/' ) . '/';
125 -
126 213 // Add GET parameters
127 - if( $queryParams && ! empty( $query )) {
214 + if( $fullPageUrl && ! empty( $query ) ) {
128 215 foreach ($query as $name => $value) {
129 - $formAction = flrt_add_query_arg($name, $value, $formAction);
216 + $formAction = flrt_add_query_arg( $name, $value, $formAction );
130 217 }
131 218 }
132 219
133 220 return $formAction;
@@ -140,11 +227,14 @@
140 227 return apply_filters( 'wpc_unnecessary_get_parameters', $getKeys );
141 228 }
142 229
143 230 foreach ( $queried_values as $slug => $filter ){
144 - if( $filter['entity'] === 'post_meta_num' ){
145 - $getKeys['max_'.$slug] = $filter;
146 - $getKeys['min_'.$slug] = $filter;
231 + if( in_array( $filter['entity'], [ 'post_meta_num', 'tax_numeric' ] ) ) {
232 + $getKeys['max_' . $slug] = $filter;
233 + $getKeys['min_' . $slug] = $filter;
234 + } else if( in_array( $filter['entity'], [ 'post_date', 'post_meta_date'] ) ) {
235 + $getKeys[$slug .'_from'] = $filter;
236 + $getKeys[$slug . '_to'] = $filter;
147 237 }else{
148 238 $getKeys[$slug] = $filter;
149 239 }
150 240 }
@@ -155,32 +245,25 @@
155 245 public function getResetUrl()
156 246 {
157 247 if( ! $this->resetUrl ) {
158 248 $container = Container::instance();
159 - $wpManager = $container->getWpManager();
160 249 $get = $container->getTheGet();
161 250
162 251 // For compatibility with some Nginx configurations
163 252 unset($get['q']);
164 253
165 - $this->resetUrl = home_url( $wpManager->getQueryVar('wp_request') );
166 - $requested = $wpManager->getQueryVar('queried_values', [] );
167 - $pos = strpos($this->resetUrl, '/page');
254 + $this->resetUrl = home_url( $this->wpManager->getQueryVar('wp_request', '') );
255 + $requested = $this->wpManager->getQueryVar('queried_values', [] );
168 256
169 - if ($pos !== false) {
170 - $this->resetUrl = substr($this->resetUrl, 0, $pos);
171 - }
257 + $this->resetUrl = $this->removePaginationBase( $this->resetUrl );
172 258
173 - $this->resetUrl = preg_replace('%\/[0-9]+[\/]?$%m', '', $this->resetUrl);
259 + // Maybe add GET parameters
260 + $exclude_params = array_keys( $this->setCorrectGetKeys( $requested ) );
261 + $exclude_params[] = 'srch';
174 262
175 - $this->resetUrl = FLRT_PERMALINKS_ENABLED ? user_trailingslashit( $this->resetUrl ) : rtrim( $this->resetUrl, '/' ) . '/';
176 -
177 - // Maybe add GET parameters
178 263 if( ! empty( $get ) ){
179 -
180 264 foreach ( $get as $name => $value ) {
181 -
182 - if( ! in_array( $name, array_keys( $this->setCorrectGetKeys( $requested ) ) ) ){
265 + if( ! in_array( $name, $exclude_params ) ){
183 266 $this->resetUrl = add_query_arg( $name, $value, $this->resetUrl );
184 267 }
185 268 }
186 269 }
@@ -188,8 +271,27 @@
188 271
189 272 return $this->resetUrl;
190 273 }
191 274
275 + /**
276 + * Removes '/page/n' from URL
277 + * @param $url
278 + * @return string
279 + */
280 + public function removePaginationBase( $url = '' )
281 + {
282 + global $wp_rewrite;
283 +
284 + $pagination_base = str_replace( "-", "\-", $wp_rewrite->pagination_base );
285 + $comments_pagination_base = str_replace( "-", "\-", $wp_rewrite->comments_pagination_base );
286 +
287 + $url = preg_replace('%\/'.$pagination_base.'/[0-9]+%', '', $url );
288 + $url = preg_replace('%\/'.$comments_pagination_base.'\-[0-9]+%', '', $url );
289 + $url = preg_replace('%\/[0-9]+[\/]?$%m', '', $url );
290 +
291 + return apply_filters( 'wpc_remove_pagination_base', $url );
292 + }
293 +
192 294 public function getValuesSeparator()
193 295 {
194 296 return $this->valuesSeparator;
195 297 }
@@ -203,114 +305,15 @@
203 305 {
204 306 return sanitize_title( $slug );
205 307 }
206 308
207 - private function getSingleActualFilter($e_name )
309 + private function getSingleActualFilter( $e_name )
208 310 {
209 - $em = Container::instance()->getEntityManager();
210 - $filter = $em->getFilterBy( 'e_name', $e_name, array( 'slug', 'e_name', 'logic' ) );
311 + $filter = $this->em->getFilterByEname( $e_name );
211 312 $filter['values'] = [];
212 -
213 - unset( $em );
214 -
215 313 return $filter;
216 314 }
217 315
218 - public function getFiltersUrl( $filters, $resetUrl = '' )
219 - {
220 - $url = $resetUrl ? $resetUrl : $this->getResetUrl();
221 - $fse = Container::instance()->getFilterService();
222 -
223 - if( ! empty( $filters ) ){
224 -
225 - foreach( $filters as $filter ){
226 -
227 - if( ! empty( $filter['values'] ) ){
228 - $filter['values'] = $fse->sortTerms( $filter['values'] );
229 -
230 - if( $filter['entity'] === 'post_meta_num' ){
231 -
232 - foreach( $filter['values'] as $edge => $value ){
233 - $paramName = $edge.'_'.$filter['slug'];
234 - $url = flrt_add_query_arg( $this->getParamName( $paramName ) , $value, $url );
235 - }
236 -
237 - } else {
238 - $url = flrt_add_query_arg( $this->getParamName( $filter['slug'] ) , implode( $this->getValuesSeparator(), $filter['values'] ), $url );
239 - }
240 -
241 - }
242 - }
243 - }
244 -
245 - unset( $fse );
246 -
247 - return apply_filters( 'wpc_filter_term_url', $url );
248 - }
249 -
250 - public function getTermUrl( $termSlug, $e_name /*, $sets = [] */ )
251 - {
252 - $em = Container::instance()->getEntityManager();
253 -
254 - $filtersCombination = [];
255 - $actualFilters = $em->getSetsRelatedFilters( /* $sets */ );
256 -
257 - if( empty( $actualFilters ) ){
258 - $actualFilters[] = $this->getSingleActualFilter( $e_name );
259 - }
260 -
261 - foreach($this->getEnamesOrder() as $entityName ){
262 -
263 - if( $filter = $this->getSubArrayBy( 'e_name', $entityName, $actualFilters ) ) {
264 -
265 - $queriedValues = $filter['values'];
266 -
267 - if( $e_name === $entityName ){
268 - // Add only single filter value for views with single selection
269 - if( in_array( $filter['view'], array('dropdown', 'radio') ) ){
270 -
271 - if( in_array( $termSlug, $queriedValues ) ){
272 - $position = array_search( $termSlug, $queriedValues );
273 - unset( $queriedValues[$position] );
274 - }else{
275 - $queriedValues = array( $termSlug );
276 - }
277 -
278 - } else {
279 - // For Post Meta Num values have array index as termslug
280 - if( $filter['entity'] === 'post_meta_num' ){
281 -
282 - if( in_array( $termSlug, array_keys( $queriedValues ) ) ){
283 - unset( $queriedValues[$termSlug] );
284 - }else{
285 - $queriedValues[] = $termSlug;
286 - }
287 -
288 - }else{
289 -
290 - if( in_array( $termSlug, $queriedValues ) ){
291 - $position = array_search( $termSlug, $queriedValues );
292 - unset( $queriedValues[$position] );
293 - }else{
294 - $queriedValues[] = $termSlug;
295 - }
296 -
297 - }
298 -
299 - }
300 - }
301 -
302 - $filter['values'] = $queriedValues;
303 - $filtersCombination[] = $filter;
304 - }
305 - }
306 -
307 - unset($em);
308 -
309 - // URL already escaped
310 - return $this->getFiltersUrl( $filtersCombination );
311 - }
312 -
313 316 private function buildFilterSegment( $termSlugs, $filter ){
314 317 $segment = $filter['slug'] . $this->separator;
315 318 $fse = Container::instance()->getFilterService();
316 319
@@ -321,12 +324,10 @@
321 324 /**
322 325 * @bug if filter is present in two sets logic gets incorrect
323 326 */
324 327
325 - $termSlugs = array_map('urlencode', $termSlugs);
326 -
327 328 $termSlugs = $fse->sortTerms( $termSlugs );
328 - $terms = implode( $fse->getLogicSeparator( $filter ), $termSlugs );
329 + $terms = implode( $fse->getLogicSeparator( $filter['logic'] ), $termSlugs );
329 330 $segment .= $terms;
330 331
331 332 unset($fse);
332 333