PluginProbe
Filter Everything — WordPress & WooCommerce Filters / 1.5.1
Filter Everything — WordPress & WooCommerce Filters v1.5.1
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
filter-everything / src / UrlManager.php

UrlManager.php in Filter Everything — WordPress & WooCommerce Filters 1.5.1, at src/UrlManager.php

335 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FilterEverything\Filter;
4
5 if ( ! defined('WPINC') ) {
6 wp_die();
7 }
8
9 class UrlManager
10 {
11 private $separator;
12
13 private $order;
14
15 private $resetUrl;
16
17 private $logicParam = 'logic'; // Should be an option
18
19 private $valuesSeparator = FLRT_QUERY_TERMS_SEPARATOR; // Should be an option
20
21 public function __construct()
22 {
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;
27
28 if( $this->permalinksOn ){
29 add_filter( 'wpc_filter_term_url', array( $this, 'processPermalink' ) );
30 }
31
32 unset( $fse );
33 }
34
35 public function processPermalink( $url )
36 {
37 $em = Container::instance()->getEntityManager();
38 $parts = explode('?', $url);
39
40 if (count($parts) !== 2) {
41 return $url;
42 }
43
44 list($path, $get) = $parts;
45
46 $query = [];
47 $parts = [];
48
49 parse_str( $get, $query );
50
51 foreach( $this->getEnamesOrder() as $entityName ){
52
53 $filter = $em->getFilterBy( 'e_name', $entityName, array( 'slug', 'e_name', 'logic', 'in_path' ) );
54
55 if( ! $filter || empty( $filter ) || ( $filter['in_path'] !== 'yes' ) ){
56 continue;
57 }
58
59 if( isset( $query[ $filter['slug'] ] ) ){
60
61 $termSlugs = $em->safeExplodeFilterValues( $query[ $filter['slug'] ], $filter['slug'], $this->getValuesSeparator() );
62 $termSlugs = $em->safeImplodeFilterValues( $termSlugs, $this->getValuesSeparator() );
63
64 $parts[] = $this->buildFilterSegment( $termSlugs, $filter );
65 }
66
67 unset( $query[ $filter['slug'] ] );
68 unset( $query[ $this->getLogicParamName( $filter['slug'] ) ] );
69 }
70
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 );
88 }
89
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;
100 }
101 }
102
103 return false;
104 }
105
106 public function getFormActionUrl( $queryParams = false )
107 {
108 $query = [];
109 $homeUrl = parse_url(home_url());
110 $post = Container::instance()->getThePost();
111 $requestedUri = isset( $post['flrt_ajax_link'] ) ? $post['flrt_ajax_link'] : $homeUrl['scheme'].'://'.$homeUrl['host'] . $_SERVER['REQUEST_URI'];
112
113 $pieces = parse_url( $requestedUri );
114 $fullPath = $pieces['scheme']."://".$pieces['host'].$pieces['path'];
115
116 if( isset( $pieces['query'] ) ){
117 parse_str( $pieces['query'], $query );
118 }
119
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);
123
124 $formAction = FLRT_PERMALINKS_ENABLED ? user_trailingslashit( $formAction ) : rtrim( $formAction, '/' ) . '/';
125
126 // Add GET parameters
127 if( $queryParams && ! empty( $query )) {
128 foreach ($query as $name => $value) {
129 $formAction = flrt_add_query_arg($name, $value, $formAction);
130 }
131 }
132
133 return $formAction;
134 }
135
136 private function setCorrectGetKeys( $queried_values )
137 {
138 $getKeys = [];
139 if( ! $queried_values || empty($queried_values) ){
140 return apply_filters( 'wpc_unnecessary_get_parameters', $getKeys );
141 }
142
143 foreach ( $queried_values as $slug => $filter ){
144 if( $filter['entity'] === 'post_meta_num' ){
145 $getKeys['max_'.$slug] = $filter;
146 $getKeys['min_'.$slug] = $filter;
147 }else{
148 $getKeys[$slug] = $filter;
149 }
150 }
151
152 return apply_filters( 'wpc_unnecessary_get_parameters', $getKeys );
153 }
154
155 public function getResetUrl()
156 {
157 if( ! $this->resetUrl ) {
158 $container = Container::instance();
159 $wpManager = $container->getWpManager();
160 $get = $container->getTheGet();
161
162 // For compatibility with some Nginx configurations
163 unset($get['q']);
164
165 $this->resetUrl = home_url( $wpManager->getQueryVar('wp_request') );
166 $requested = $wpManager->getQueryVar('queried_values', [] );
167 $pos = strpos($this->resetUrl, '/page');
168
169 if ($pos !== false) {
170 $this->resetUrl = substr($this->resetUrl, 0, $pos);
171 }
172
173 $this->resetUrl = preg_replace('%\/[0-9]+[\/]?$%m', '', $this->resetUrl);
174
175 $this->resetUrl = FLRT_PERMALINKS_ENABLED ? user_trailingslashit( $this->resetUrl ) : rtrim( $this->resetUrl, '/' ) . '/';
176
177 // Maybe add GET parameters
178 if( ! empty( $get ) ){
179
180 foreach ( $get as $name => $value ) {
181
182 if( ! in_array( $name, array_keys( $this->setCorrectGetKeys( $requested ) ) ) ){
183 $this->resetUrl = add_query_arg( $name, $value, $this->resetUrl );
184 }
185 }
186 }
187 }
188
189 return $this->resetUrl;
190 }
191
192 public function getValuesSeparator()
193 {
194 return $this->valuesSeparator;
195 }
196
197 public function getLogicParamName( $slug )
198 {
199 return $this->getParamName( $slug ).'_'.$this->logicParam;
200 }
201
202 public function getParamName( $slug )
203 {
204 return sanitize_title( $slug );
205 }
206
207 private function getSingleActualFilter($e_name )
208 {
209 $em = Container::instance()->getEntityManager();
210 $filter = $em->getFilterBy( 'e_name', $e_name, array( 'slug', 'e_name', 'logic' ) );
211 $filter['values'] = [];
212
213 unset( $em );
214
215 return $filter;
216 }
217
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 private function buildFilterSegment( $termSlugs, $filter ){
314 $segment = $filter['slug'] . $this->separator;
315 $fse = Container::instance()->getFilterService();
316
317 if( ! is_array( $termSlugs ) ){
318 return false;
319 }
320
321 /**
322 * @bug if filter is present in two sets logic gets incorrect
323 */
324
325 $termSlugs = array_map('urlencode', $termSlugs);
326
327 $termSlugs = $fse->sortTerms( $termSlugs );
328 $terms = implode( $fse->getLogicSeparator( $filter ), $termSlugs );
329 $segment .= $terms;
330
331 unset($fse);
332
333 return $segment;
334 }
335 }