PluginProbe
Filter Everything — WordPress & WooCommerce Filters / 1.6.1
Filter Everything — WordPress & WooCommerce Filters v1.6.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.6.1, at src/UrlManager.php

348 lines 10.7 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
112 if( isset( $post['flrt_ajax_link'] ) ){
113 $requestedUri = $post['flrt_ajax_link'];
114 }else{
115 $requestedUri = $homeUrl['scheme'].'://'.$homeUrl['host'];
116 if( isset( $homeUrl['port'] ) && $homeUrl['port'] ){
117 $requestedUri .= ":".$homeUrl['port'];
118 }
119 $requestedUri .= $_SERVER['REQUEST_URI'];
120 }
121
122 $pieces = parse_url( $requestedUri );
123 $fullPath = $pieces['scheme']."://".$pieces['host'];
124 if( isset( $pieces['port'] ) && $pieces['port'] ){
125 $fullPath .= ":".$pieces['port'];
126 }
127 $fullPath .= $pieces['path'];
128
129 if( isset( $pieces['query'] ) ){
130 parse_str( $pieces['query'], $query );
131 }
132
133 $formAction = preg_replace('%\/page/[0-9]+%', '', $fullPath);
134 $formAction = preg_replace('%\/comment\-page\-[0-9]+%', '', $formAction);
135 $formAction = preg_replace('%\/[0-9]+[\/]?$%m', '', $formAction);
136
137 $formAction = FLRT_PERMALINKS_ENABLED ? user_trailingslashit( $formAction ) : rtrim( $formAction, '/' ) . '/';
138
139 // Add GET parameters
140 if( $queryParams && ! empty( $query )) {
141 foreach ($query as $name => $value) {
142 $formAction = flrt_add_query_arg($name, $value, $formAction);
143 }
144 }
145
146 return $formAction;
147 }
148
149 private function setCorrectGetKeys( $queried_values )
150 {
151 $getKeys = [];
152 if( ! $queried_values || empty($queried_values) ){
153 return apply_filters( 'wpc_unnecessary_get_parameters', $getKeys );
154 }
155
156 foreach ( $queried_values as $slug => $filter ){
157 if( $filter['entity'] === 'post_meta_num' ){
158 $getKeys['max_'.$slug] = $filter;
159 $getKeys['min_'.$slug] = $filter;
160 }else{
161 $getKeys[$slug] = $filter;
162 }
163 }
164
165 return apply_filters( 'wpc_unnecessary_get_parameters', $getKeys );
166 }
167
168 public function getResetUrl()
169 {
170 if( ! $this->resetUrl ) {
171 $container = Container::instance();
172 $wpManager = $container->getWpManager();
173 $get = $container->getTheGet();
174
175 // For compatibility with some Nginx configurations
176 unset($get['q']);
177
178 $this->resetUrl = home_url( $wpManager->getQueryVar('wp_request') );
179 $requested = $wpManager->getQueryVar('queried_values', [] );
180 $pos = strpos($this->resetUrl, '/page');
181
182 if ($pos !== false) {
183 $this->resetUrl = substr($this->resetUrl, 0, $pos);
184 }
185
186 $this->resetUrl = preg_replace('%\/[0-9]+[\/]?$%m', '', $this->resetUrl);
187
188 $this->resetUrl = FLRT_PERMALINKS_ENABLED ? user_trailingslashit( $this->resetUrl ) : rtrim( $this->resetUrl, '/' ) . '/';
189
190 // Maybe add GET parameters
191 if( ! empty( $get ) ){
192
193 foreach ( $get as $name => $value ) {
194
195 if( ! in_array( $name, array_keys( $this->setCorrectGetKeys( $requested ) ) ) ){
196 $this->resetUrl = add_query_arg( $name, $value, $this->resetUrl );
197 }
198 }
199 }
200 }
201
202 return $this->resetUrl;
203 }
204
205 public function getValuesSeparator()
206 {
207 return $this->valuesSeparator;
208 }
209
210 public function getLogicParamName( $slug )
211 {
212 return $this->getParamName( $slug ).'_'.$this->logicParam;
213 }
214
215 public function getParamName( $slug )
216 {
217 return sanitize_title( $slug );
218 }
219
220 private function getSingleActualFilter($e_name )
221 {
222 $em = Container::instance()->getEntityManager();
223 $filter = $em->getFilterBy( 'e_name', $e_name, array( 'slug', 'e_name', 'logic' ) );
224 $filter['values'] = [];
225
226 unset( $em );
227
228 return $filter;
229 }
230
231 public function getFiltersUrl( $filters, $resetUrl = '' )
232 {
233 $url = $resetUrl ? $resetUrl : $this->getResetUrl();
234 $fse = Container::instance()->getFilterService();
235
236 if( ! empty( $filters ) ){
237
238 foreach( $filters as $filter ){
239
240 if( ! empty( $filter['values'] ) ){
241 $filter['values'] = $fse->sortTerms( $filter['values'] );
242
243 if( $filter['entity'] === 'post_meta_num' ){
244
245 foreach( $filter['values'] as $edge => $value ){
246 $paramName = $edge.'_'.$filter['slug'];
247 $url = flrt_add_query_arg( $this->getParamName( $paramName ) , $value, $url );
248 }
249
250 } else {
251 $url = flrt_add_query_arg( $this->getParamName( $filter['slug'] ) , implode( $this->getValuesSeparator(), $filter['values'] ), $url );
252 }
253
254 }
255 }
256 }
257
258 unset( $fse );
259
260 return apply_filters( 'wpc_filter_term_url', $url );
261 }
262
263 public function getTermUrl( $termSlug, $e_name /*, $sets = [] */ )
264 {
265 $em = Container::instance()->getEntityManager();
266
267 $filtersCombination = [];
268 $actualFilters = $em->getSetsRelatedFilters( /* $sets */ );
269
270 if( empty( $actualFilters ) ){
271 $actualFilters[] = $this->getSingleActualFilter( $e_name );
272 }
273
274 foreach($this->getEnamesOrder() as $entityName ){
275
276 if( $filter = $this->getSubArrayBy( 'e_name', $entityName, $actualFilters ) ) {
277
278 $queriedValues = $filter['values'];
279
280 if( $e_name === $entityName ){
281 // Add only single filter value for views with single selection
282 if( in_array( $filter['view'], array('dropdown', 'radio') ) ){
283
284 if( in_array( $termSlug, $queriedValues ) ){
285 $position = array_search( $termSlug, $queriedValues );
286 unset( $queriedValues[$position] );
287 }else{
288 $queriedValues = array( $termSlug );
289 }
290
291 } else {
292 // For Post Meta Num values have array index as termslug
293 if( $filter['entity'] === 'post_meta_num' ){
294
295 if( in_array( $termSlug, array_keys( $queriedValues ) ) ){
296 unset( $queriedValues[$termSlug] );
297 }else{
298 $queriedValues[] = $termSlug;
299 }
300
301 }else{
302
303 if( in_array( $termSlug, $queriedValues ) ){
304 $position = array_search( $termSlug, $queriedValues );
305 unset( $queriedValues[$position] );
306 }else{
307 $queriedValues[] = $termSlug;
308 }
309
310 }
311
312 }
313 }
314
315 $filter['values'] = $queriedValues;
316 $filtersCombination[] = $filter;
317 }
318 }
319
320 unset($em);
321
322 // URL already escaped
323 return $this->getFiltersUrl( $filtersCombination );
324 }
325
326 private function buildFilterSegment( $termSlugs, $filter ){
327 $segment = $filter['slug'] . $this->separator;
328 $fse = Container::instance()->getFilterService();
329
330 if( ! is_array( $termSlugs ) ){
331 return false;
332 }
333
334 /**
335 * @bug if filter is present in two sets logic gets incorrect
336 */
337
338 $termSlugs = array_map('urlencode', $termSlugs);
339
340 $termSlugs = $fse->sortTerms( $termSlugs );
341 $terms = implode( $fse->getLogicSeparator( $filter ), $termSlugs );
342 $segment .= $terms;
343
344 unset($fse);
345
346 return $segment;
347 }
348 }