]> _ Git - physioassist-wordpress.git/blob
bf401f8098cfa9253896f974e85de6281bab9bf9
[physioassist-wordpress.git] /
1 <?php
2
3 use \WPML\FP\Relation;
4 use \WPML\FP\Fns;
5
6 class WPML_Term_Query_Filter {
7
8         /** @var WPML_Term_Translation $term_translation */
9         private $term_translation;
10
11         /** @var WPML_Debug_BackTrace $debug_backtrace */
12         private $debug_backtrace;
13
14         /** @var wpdb $wpdb */
15         private $wpdb;
16
17         /** @var IWPML_Taxonomy_State $taxonomy_state */
18         private $taxonomy_state;
19
20         /** @var string $current_language */
21         private $current_language;
22
23         /** @var string $default_language */
24         private $default_language;
25
26         /** @var bool $lock */
27         private $lock;
28
29         /**
30          * WPML_Term_query_Filter constructor.
31          *
32          * @param WPML_Term_Translation $term_translation
33          * @param WPML_Debug_BackTrace  $debug_backtrace
34          * @param wpdb                  $wpdb
35          * @param IWPML_Taxonomy_State  $taxonomy_state
36          */
37         public function __construct(
38                 WPML_Term_Translation $term_translation,
39                 WPML_Debug_BackTrace $debug_backtrace,
40                 wpdb $wpdb,
41                 IWPML_Taxonomy_State $taxonomy_state
42         ) {
43                 $this->term_translation = $term_translation;
44                 $this->debug_backtrace  = $debug_backtrace;
45                 $this->wpdb             = $wpdb;
46                 $this->taxonomy_state   = $taxonomy_state;
47         }
48
49         /** @param string $current_language */
50         /** @param string $default_language */
51         public function set_lang( $current_language, $default_language ) {
52                 $this->current_language = $current_language;
53                 $this->default_language = $default_language;
54         }
55
56         /**
57          * @param array $args
58          * @param array $taxonomies
59          *
60          * @return array
61          */
62         public function get_terms_args_filter( $args, $taxonomies ) {
63                 if ( $this->lock ) {
64                         return $args;
65                 }
66
67                 if ( 0 === count( array_filter( (array) $taxonomies, array( $this->taxonomy_state, 'is_translated_taxonomy' ) ) ) ) {
68                         return $args;
69                 }
70
71                 $this->lock = true;
72
73                 if ( isset( $args['cache_domain'] ) ) {
74                         $args['cache_domain'] .= '_' . $this->current_language;
75                 }
76
77                 $isOrderByEqualTo = Relation::propEq( 'orderby', Fns::__, $args );
78
79                 $params = array( 'include', 'exclude', 'exclude_tree' );
80                 foreach ( $params as $param ) {
81                         $adjusted_ids = $this->adjust_taxonomies_terms_ids( $args[ $param ], $isOrderByEqualTo( $param ) );
82
83                         if ( ! empty( $adjusted_ids ) ) {
84                                 $args[ $param ] = $adjusted_ids;
85                         }
86                 }
87
88                 $params = array( 'child_of', 'parent' );
89                 foreach ( $params as $param ) {
90                         if ( ! isset( $args[ $param ] ) ) {
91                                 continue;
92                         }
93
94                         $adjusted_ids = $this->adjust_taxonomies_terms_ids( $args[ $param ], $isOrderByEqualTo( $param ) );
95
96                         if ( ! empty( $adjusted_ids ) ) {
97                                 $args[ $param ] = array_pop( $adjusted_ids );
98                         }
99                 }
100
101                 if ( ! empty( $args['slug'] ) ) {
102                         $args = $this->adjust_taxonomies_terms_slugs( $args, $taxonomies );
103                 }
104
105                 // special case for when term hierarchy is cached in wp_options
106                 if ( $this->debug_backtrace->is_function_in_call_stack( '_get_term_hierarchy' ) ) {
107                         $args['_icl_show_all_langs'] = true;
108                 }
109
110                 $this->lock = false;
111                 return $args;
112         }
113
114         /**
115          * @param string|array $terms_ids
116          * @param bool         $orderByTermId
117          *
118          * @return array
119          */
120         private function adjust_taxonomies_terms_ids( $terms_ids, $orderByTermId ) {
121                 $terms_ids = array_filter( array_unique( $this->explode_and_trim( $terms_ids ) ) );
122
123                 if ( empty( $terms_ids ) ) {
124                         return $terms_ids;
125                 }
126
127                 $terms          = $this->get_terms( $terms_ids, $orderByTermId );
128                 $translated_ids = array();
129
130                 foreach ( $terms as $term ) {
131
132                         if ( $this->taxonomy_state->is_translated_taxonomy( $term->taxonomy ) ) {
133                                 $translated_id = $this->term_translation->term_id_in( $term->term_id, $this->current_language );
134                                 if ( ! $translated_id && ! is_admin() && $this->taxonomy_state->is_display_as_translated_taxonomy( $term->taxonomy ) ) {
135                                         $translated_id = $this->term_translation->term_id_in( $term->term_id, $this->default_language );
136                                 }
137                                 $translated_ids[] = $translated_id;
138                         } else {
139                                 $translated_ids[] = $term->term_id;
140                         }
141                 }
142
143                 return array_filter( $translated_ids );
144         }
145
146         /**
147          * @param array $args
148          * @param array $taxonomies
149          *
150          * @return array
151          */
152         private function adjust_taxonomies_terms_slugs( $args, array $taxonomies ) {
153                 $terms_slugs = $args['slug'];
154                 if ( is_string( $terms_slugs ) ) {
155                         $terms_slugs = [ $terms_slugs ];
156                 }
157
158                 $duplicateSlugTranslations = [];
159                 $translated_slugs          = [];
160                 foreach ( $terms_slugs as $terms_slug ) {
161                         $term = $this->guess_term( $terms_slug, $taxonomies );
162
163                         if ( $term ) {
164                                 $translated_id   = $this->term_translation->term_id_in( $term->term_id, $this->current_language );
165                                 $translated_term = get_term( $translated_id, $term->taxonomy );
166                                 if ( $translated_term instanceof WP_Term ) {
167                                         if ( $terms_slug === $translated_term->slug ) {
168                                                 $duplicateSlugTranslations[] = $translated_id;
169                                         }
170                                         $terms_slug = $translated_term->slug;
171                                 }
172                         }
173                         $translated_slugs[] = $terms_slug;
174                 }
175
176                 if ( count( $duplicateSlugTranslations ) === 1 ) {
177                         $args['include'] = $duplicateSlugTranslations;
178                         $args['slug']    = '';
179                 } else {
180                         $args['slug'] = array_filter( $translated_slugs );
181                 }
182
183                 return $args;
184         }
185
186         /**
187          * @param array $ids
188          * @param bool  $orderByTermId
189          *
190          * @return stdClass[]
191          */
192         private function get_terms( $ids, $orderByTermId ) {
193                 $safeIds = wpml_prepare_in( $ids, '%d' );
194                 $sql     = "SELECT taxonomy, term_id FROM {$this->wpdb->term_taxonomy}
195                                  WHERE term_id IN ({$safeIds})
196                                  ";
197                 $sql    .= $orderByTermId ? "ORDER BY FIELD(term_id, {$safeIds})" : '';
198                 return $this->wpdb->get_results( $sql );
199         }
200
201         /**
202          * @param string $slug
203          * @param array  $taxonomies
204          *
205          * @return null|WP_Term
206          */
207         private function guess_term( $slug, array $taxonomies ) {
208                 foreach ( $taxonomies as $taxonomy ) {
209                         $term = get_term_by( 'slug', $slug, $taxonomy );
210
211                         if ( $term ) {
212                                 return $term;
213                         }
214                 }
215
216                 return null;
217         }
218
219         /**
220          * @param string|array $source
221          *
222          * @return array
223          */
224         private function explode_and_trim( $source ) {
225                 if ( ! is_array( $source ) ) {
226                         $source = array_map( 'trim', explode( ',', $source ) );
227                 }
228
229                 return $source;
230         }
231
232 }