PluginProbe
Filter Everything — WordPress & WooCommerce Filters / 1.2.4
Filter Everything — WordPress & WooCommerce Filters v1.2.4
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 / Entities / TaxonomyEntity.php

TaxonomyEntity.php in Filter Everything — WordPress & WooCommerce Filters 1.2.4, at src/Entities/TaxonomyEntity.php

385 lines 11.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 TaxonomyEntity implements Entity
10 {
11 public $items = [];
12
13 public $excludedTerms = [];
14
15 public $descendants = [];
16
17 private $entityName = '';
18
19 private $new_tax_query = [];
20
21 private $postTypes = [];
22
23 public function __construct( $taxName ){
24 $this->entityName = $taxName;
25 $this->getAllExistingTerms();
26 $this->passTermNames();
27 }
28
29 public function setPostTypes( $postTypes )
30 {
31 $this->postTypes = $postTypes;
32 }
33
34 public function setExcludedTerms( $excludedTerms )
35 {
36 $this->excludedTerms = (array) $excludedTerms;
37 }
38
39 public function getName()
40 {
41 return $this->entityName;
42 }
43
44 function excludeTerms( $terms )
45 {
46 $exclude = [];
47
48 if( ! empty( $this->excludedTerms ) ){
49 $exclude = $this->excludedTerms;
50 }
51
52 // Exclude taxonomy term if it already exists in wp_query
53 $wpManager = Container::instance()->getWpManager();
54 $wp_queried_object = $wpManager->getQueryVar( 'wp_queried_object' );
55
56 if( isset( $wp_queried_object['taxonomy'] ) && $wp_queried_object['taxonomy'] === $this->getName() ){
57 $exclude[] = $wp_queried_object['term_id'];
58 }
59
60 foreach( $terms as $index => $term ){
61 if( in_array( $term->term_id, $exclude ) ){
62 unset( $terms[$index] );
63 }
64 }
65
66 return $terms;
67 }
68
69 public function getTermTaxonomyPostsIds( $termTaxonomyIds )
70 {
71 global $wpdb;
72
73 $query[] = "SELECT DISTINCT {$wpdb->term_relationships}.term_taxonomy_id,{$wpdb->term_relationships}.object_id";
74 $query[] = "FROM {$wpdb->term_relationships}";
75 $query[] = "WHERE {$wpdb->term_relationships}.term_taxonomy_id IN ('" . implode("','", $termTaxonomyIds) . "')";
76
77 $query = implode(' ', $query);
78
79 $results = $wpdb->get_results($query, ARRAY_A);
80 $results = apply_filters( 'wpc_term_taxonomy_terms', $results, $this );
81
82 $ids = [];
83 foreach ($results as $key => $result) {
84 $ids[$result['term_taxonomy_id']][] = $result['object_id'];
85 }
86
87 $ids = apply_filters( 'wpc_term_taxonomy_post_ids', $ids, $this );
88
89 // Fix for counts for parent, when 'include_children=true'
90 // Add posts from children terms to their parents
91 // To make correct counts for their parents
92 if( ! empty( $this->descendants ) ){
93 $parents = array_keys( $this->descendants );
94
95 foreach ( $ids as $term_id => $post_ids_array ){
96 if( in_array( $term_id, $parents ) ){
97 foreach ( $this->descendants[$term_id] as $child_term_id ){
98 if( isset( $ids[$child_term_id] ) ){
99 $ids[$term_id] = array_unique( array_merge( $ids[$term_id], $ids[$child_term_id] ) );
100 }
101 }
102 }
103 }
104 }
105
106 return $ids;
107 }
108
109 public function populateTermsWithPostIds( $setId, $post_type )
110 {
111 $termTaxonomyIds = [];
112 $em = Container::instance()->getEntityManager();
113 $allWpQueriedPostIds = $em->getAllSetWpQueriedPostIds( $setId );
114
115 foreach ( $this->getAllExistingTerms() as $term ){
116 $termTaxonomyIds[] = $term->term_taxonomy_id;
117 }
118
119 $termPosts = $this->getTermTaxonomyPostsIds( $termTaxonomyIds );
120
121 foreach( $this->items as $index => $term ){
122 if( isset( $termPosts[$term->term_taxonomy_id] ) ){
123 $this->items[$index]->posts = array_intersect( $allWpQueriedPostIds, $termPosts[$term->term_taxonomy_id] );
124 }else{
125 $this->items[$index]->posts = [];
126 }
127 }
128
129 }
130
131 public function getTerms()
132 {
133 return $this->excludeTerms( $this->getAllExistingTerms() );
134 }
135
136 /**
137 * @param int $id term id
138 * @return false|object term object of false
139 */
140 public function getTerm( $id ){
141 if( ! $id ){
142 return false;
143 }
144
145 foreach ( $this->getAllExistingTerms() as $term ){
146 if( $id == $term->term_id ){
147 return $term;
148 }
149 }
150
151 return false;
152 }
153
154 public function getTermId( $termSlug )
155 {
156 foreach ( $this->getAllExistingTerms() as $term ){
157 if( $termSlug == $term->slug ){
158 return $term->term_id;
159 }
160 }
161
162 return false;
163 }
164
165 /**
166 * @return array list of term_id and names useful to create Select dropdown
167 */
168 public function getTermsForSelect( $optionGroup = false )
169 {
170 $toSelect = [];
171 foreach ( $this->getTerms() as $term ) {
172 if( $optionGroup ){
173 $key = $term->taxonomy.":".$term->term_id;
174 $toSelect[$key] = $term->name;
175 }else{
176 $toSelect[$term->term_id] = $term->name;
177 }
178
179 }
180
181 return $toSelect;
182 }
183
184 public function getTermsForSelect2()
185 {
186 $toSelect = [];
187 foreach ( $this->getTerms() as $term ) {
188 $toSelect[] = array( 'id' => $term->term_id, 'text' =>$term->name );
189 }
190 return $toSelect;
191 }
192
193 public function passTermNames()
194 {
195 foreach ($this->getAllExistingTerms() as $index => $term ) {
196 $this->items[$index]->name = apply_filters( 'wpc_filter_taxonomy_term_name', $term->name, $this->getName() );
197 }
198 }
199
200 function getAllExistingTerms( $force = false )
201 {
202
203 if( empty( $this->items ) || $force ){
204
205 $args = array(
206 'taxonomy' => $this->entityName,
207 'hide_empty' => false,
208 'order' => 'ASC'
209 );
210
211 /**
212 * Filter terms query $args to allow handle cases with some specific taxonomies
213 */
214 $args = apply_filters( 'wpc_filter_term_query_args', $args, 'taxonomy', $this->getName() );
215 $result = apply_filters( 'wpc_filter_get_taxonomy_terms', get_terms( $args ), $this->getName() );
216
217 $termsUpdated = [];
218 $children_terms = [];
219
220 if( ! empty( $result ) && ! is_wp_error( $result ) ) {
221
222 foreach ($result as $i => $termObject) {
223 $termObject->name = apply_filters('wpc_filter_' . $this->getName() . '_term_name', $termObject->name, $termObject);
224 $termsUpdated[$i] = $termObject;
225
226 if( ! empty( $termObject->parent ) ) {
227 $children_terms[$termObject->parent][] = $termObject->term_id;
228 }
229 }
230 // Solution for 'include_children=true' problem and parent counts
231 $this->descendants = flrt_find_all_descendants( $children_terms );
232
233 $this->items = $termsUpdated;
234 }
235
236 }
237
238 return $this->items;
239 }
240
241 private function getSqlLogicOperator( $filter ){
242 if( $filter['logic'] === 'and' ){
243 return 'AND';
244 } else {
245 return 'IN';
246 }
247 }
248
249 public function isTermAlreadyInQuery( $queried_value, $wp_query ){
250 $duplicate = [];
251
252 if ( ! empty( $wp_query->tax_query->queried_terms ) ) {
253 $native_query_terms = $wp_query->tax_query->queried_terms;
254 $queried_taxonomies = array_keys( $native_query_terms );
255
256 foreach ( $queried_taxonomies as $q_taxonomy ) {
257 if( $q_taxonomy === $queried_value['e_name'] ){
258 $query = $native_query_terms[$q_taxonomy];
259
260 if ( ! empty( $query['terms'] ) ) {
261 if ( 'term_id' == $query['field'] ) {
262 $term = get_term( reset( $query['terms'] ), $q_taxonomy );
263 } else {
264 $term = get_term_by( $query['field'], reset( $query['terms'] ), $q_taxonomy );
265 }
266
267 if( ! $term || is_wp_error( $term ) ){
268 return false;
269 }
270
271 foreach( $queried_value['values'] as $filter_slug ){
272 if( $filter_slug === $term->slug ){
273 $duplicate['taxonomy'] = $q_taxonomy;
274 $duplicate['term'] = $term->slug;
275 return $duplicate;
276 }
277 }
278 }
279 }
280 }
281 }
282
283 return false;
284 }
285
286 private function isTheSameTaxQuery( $tax_query_1, $tax_query_2 ){
287 $tax_query_1 = $this->normalizeTaxQueryArray($tax_query_1);
288 $tax_query_2 = $this->normalizeTaxQueryArray($tax_query_2);
289
290 $diff = array_diff( $tax_query_1, $tax_query_2 );
291
292 if ( empty( $diff ) ){
293 return true;
294 }
295
296 return false;
297 }
298
299 private function normalizeTaxQueryArray( $tax_query ){
300 $normalized_tax_query = [];
301
302 if( ! is_array( $tax_query ) || ! isset( $tax_query['taxonomy'] ) ){
303 return false;
304 }
305
306 if( is_array( $tax_query['terms'] ) ){
307 sort( $tax_query['terms'] );
308 }
309
310 $normalized_tax_query['taxonomy'] = $tax_query['taxonomy'];
311 $normalized_tax_query['field'] = $tax_query['field'];
312
313 if( is_array($tax_query['terms']) ){
314 $normalized_tax_query['terms'] = implode( '-', $tax_query['terms'] );
315 }else{
316 $normalized_tax_query['terms'] = $tax_query['terms'];
317 }
318
319 return $normalized_tax_query;
320 }
321
322 private function addTaxQueryArray( $tax_query_array ){
323 if( ! isset( $tax_query_array['taxonomy'] ) ){
324 return false;
325 }
326
327 $existing_tax_query = $this->new_tax_query;
328 foreach( $existing_tax_query as $index => $present_query ){
329 if( $this->isTheSameTaxQuery( $present_query, $tax_query_array ) ){
330 return false;
331 }
332 }
333
334 $this->new_tax_query[] = $tax_query_array;
335 }
336
337 /**
338 * @return mixed object WP_Query|string;
339 */
340 public function addTermsToWpQuery($queried_value, $wp_query ){
341
342 if( $term = $this->isTermAlreadyInQuery( $queried_value, $wp_query ) ){
343 // It is be better to return 404 result and process it in WpManager
344 /**
345 * @todo replace with with just false. Or better - show this only in debug mode.
346 */
347 return 'Term already in query';
348 }
349 /**
350 * @feature Include children should be optionally configured in Settings. Maybe.
351 */
352 $args = array(
353 'taxonomy' => $queried_value['e_name'],
354 'field' => 'slug',
355 'terms' => $queried_value['values'],
356 );
357
358 $args['operator'] = $this->getSqlLogicOperator( $queried_value );
359
360 if( isset( $wp_query->tax_query->queries ) && count( $wp_query->tax_query->queries ) ){
361 foreach($wp_query->tax_query->queries as $single_tax_query ){
362 $this->addTaxQueryArray( $single_tax_query );
363 }
364 }
365
366 $this->addTaxQueryArray( $args );
367
368 $already_existing_tax_query = $wp_query->get('tax_query');
369
370 if( is_array( $already_existing_tax_query ) ){
371 foreach( $already_existing_tax_query as $value ){
372 $this->addTaxQueryArray( $value );
373 }
374 }
375
376 if( count($this->new_tax_query) > 1 ){
377 $this->new_tax_query['relation'] = 'AND';
378 }
379
380 $wp_query->set('tax_query', $this->new_tax_query );
381 $this->new_tax_query = [];
382
383 return $wp_query;
384 }
385 }