6 class WPML_Term_Query_Filter {
8 /** @var WPML_Term_Translation $term_translation */
9 private $term_translation;
11 /** @var WPML_Debug_BackTrace $debug_backtrace */
12 private $debug_backtrace;
14 /** @var wpdb $wpdb */
17 /** @var IWPML_Taxonomy_State $taxonomy_state */
18 private $taxonomy_state;
20 /** @var string $current_language */
21 private $current_language;
23 /** @var string $default_language */
24 private $default_language;
26 /** @var bool $lock */
30 * WPML_Term_query_Filter constructor.
32 * @param WPML_Term_Translation $term_translation
33 * @param WPML_Debug_BackTrace $debug_backtrace
35 * @param IWPML_Taxonomy_State $taxonomy_state
37 public function __construct(
38 WPML_Term_Translation $term_translation,
39 WPML_Debug_BackTrace $debug_backtrace,
41 IWPML_Taxonomy_State $taxonomy_state
43 $this->term_translation = $term_translation;
44 $this->debug_backtrace = $debug_backtrace;
46 $this->taxonomy_state = $taxonomy_state;
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;
58 * @param array $taxonomies
62 public function get_terms_args_filter( $args, $taxonomies ) {
67 if ( 0 === count( array_filter( (array) $taxonomies, array( $this->taxonomy_state, 'is_translated_taxonomy' ) ) ) ) {
73 if ( isset( $args['cache_domain'] ) ) {
74 $args['cache_domain'] .= '_' . $this->current_language;
77 $isOrderByEqualTo = Relation::propEq( 'orderby', Fns::__, $args );
79 $params = array( 'include', 'exclude', 'exclude_tree' );
80 foreach ( $params as $param ) {
81 $adjusted_ids = $this->adjust_taxonomies_terms_ids( $args[ $param ], $isOrderByEqualTo( $param ) );
83 if ( ! empty( $adjusted_ids ) ) {
84 $args[ $param ] = $adjusted_ids;
88 $params = array( 'child_of', 'parent' );
89 foreach ( $params as $param ) {
90 if ( ! isset( $args[ $param ] ) ) {
94 $adjusted_ids = $this->adjust_taxonomies_terms_ids( $args[ $param ], $isOrderByEqualTo( $param ) );
96 if ( ! empty( $adjusted_ids ) ) {
97 $args[ $param ] = array_pop( $adjusted_ids );
101 if ( ! empty( $args['slug'] ) ) {
102 $args = $this->adjust_taxonomies_terms_slugs( $args, $taxonomies );
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;
115 * @param string|array $terms_ids
116 * @param bool $orderByTermId
120 private function adjust_taxonomies_terms_ids( $terms_ids, $orderByTermId ) {
121 $terms_ids = array_filter( array_unique( $this->explode_and_trim( $terms_ids ) ) );
123 if ( empty( $terms_ids ) ) {
127 $terms = $this->get_terms( $terms_ids, $orderByTermId );
128 $translated_ids = array();
130 foreach ( $terms as $term ) {
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 );
137 $translated_ids[] = $translated_id;
139 $translated_ids[] = $term->term_id;
143 return array_filter( $translated_ids );
148 * @param array $taxonomies
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 ];
158 $duplicateSlugTranslations = [];
159 $translated_slugs = [];
160 foreach ( $terms_slugs as $terms_slug ) {
161 $term = $this->guess_term( $terms_slug, $taxonomies );
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;
170 $terms_slug = $translated_term->slug;
173 $translated_slugs[] = $terms_slug;
176 if ( count( $duplicateSlugTranslations ) === 1 ) {
177 $args['include'] = $duplicateSlugTranslations;
180 $args['slug'] = array_filter( $translated_slugs );
188 * @param bool $orderByTermId
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})
197 $sql .= $orderByTermId ? "ORDER BY FIELD(term_id, {$safeIds})" : '';
198 return $this->wpdb->get_results( $sql );
202 * @param string $slug
203 * @param array $taxonomies
205 * @return null|WP_Term
207 private function guess_term( $slug, array $taxonomies ) {
208 foreach ( $taxonomies as $taxonomy ) {
209 $term = get_term_by( 'slug', $slug, $taxonomy );
220 * @param string|array $source
224 private function explode_and_trim( $source ) {
225 if ( ! is_array( $source ) ) {
226 $source = array_map( 'trim', explode( ',', $source ) );