PluginProbe
Polylang / 2.5
Polylang v2.5
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / include / query.php

query.php in Polylang 2.5, at include/query.php

201 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * A class to manipulate the language query var in WP_Query
5 *
6 * @since 2.2
7 */
8 class PLL_Query {
9
10 static protected $excludes = array(
11 'p',
12 'post_parent',
13 'attachment',
14 'attachment_id',
15 'name',
16 'pagename',
17 'page_id',
18 'category_name',
19 'tag',
20 'tag_id',
21 'cat',
22 'category__in',
23 'category__and',
24 'post__in',
25 'post_name__in',
26 'tag__in',
27 'tag__and',
28 'tag_slug__in',
29 'tag_slug__and',
30 'post_parent__in',
31 );
32
33 /**
34 * Constructor
35 *
36 * @since 2.2
37 *
38 * @param array $query Reference to the WP_Query object
39 * @param object $model
40 */
41 public function __construct( &$query, &$model ) {
42 $this->query = &$query;
43 $this->model = &$model;
44 }
45
46 /**
47 * Check if translated taxonomy is queried
48 * Compatible with nested queries introduced in WP 4.1
49 *
50 * @see https://wordpress.org/support/topic/tax_query-bug
51 *
52 * @since 1.7
53 *
54 * @param array $tax_queries
55 * @return bool
56 */
57 protected function have_translated_taxonomy( $tax_queries ) {
58 if ( is_array( $tax_queries ) ) {
59 foreach ( $tax_queries as $tax_query ) {
60 if ( isset( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) && ! ( isset( $tax_query['operator'] ) && 'NOT IN' === $tax_query['operator'] ) ) {
61 return true;
62 }
63
64 // Nested queries
65 elseif ( is_array( $tax_query ) && $this->have_translated_taxonomy( $tax_query ) ) {
66 return true;
67 }
68 }
69 }
70
71 return false;
72 }
73
74 /**
75 * Get queried taxonomies
76 *
77 * @since 2.2
78 *
79 * @return array queried taxonomies
80 */
81 public function get_queried_taxonomies() {
82 return isset( $this->query->tax_query->queried_terms ) ? array_keys( wp_list_filter( $this->query->tax_query->queried_terms, array( 'operator' => 'NOT IN' ), 'NOT' ) ) : array();
83 }
84
85 /**
86 * Sets the language in query
87 * Optimized for ( needs ) WP 3.5+
88 *
89 * @since 2.2
90 *
91 * @param object $lang
92 */
93 public function set_language( $lang ) {
94 // Defining directly the tax_query ( rather than setting 'lang' avoids transforming the query by WP )
95 $lang_query = array(
96 'taxonomy' => 'language',
97 'field' => 'term_taxonomy_id', // Since WP 3.5
98 'terms' => $lang->term_taxonomy_id,
99 'operator' => 'IN',
100 );
101
102 $tax_query = &$this->query->query_vars['tax_query'];
103
104 if ( isset( $tax_query['relation'] ) && 'OR' === $tax_query['relation'] ) {
105 $tax_query = array(
106 $lang_query,
107 array( $tax_query ),
108 'relation' => 'AND',
109 );
110 } elseif ( is_array( $tax_query ) ) {
111 // The tax query is expected to be *always* an array, but it seems that 3rd parties fill it with a string
112 // Causing a fatal error if we don't check it.
113 // See https://wordpress.org/support/topic/fatal-error-2947/
114 $tax_query[] = $lang_query;
115 } elseif ( empty( $tax_query ) ) {
116 // Supposing the tax query has been wrongly filled with an empty string
117 $tax_query = array( $lang_query );
118 }
119 }
120
121 /**
122 * Add the language in query after it has checked that it won't conflict with other query vars
123 *
124 * @since 2.2
125 *
126 * @param object $lang Language
127 */
128 public function filter_query( $lang ) {
129 $qvars = &$this->query->query_vars;
130
131 if ( ! isset( $qvars['lang'] ) ) {
132 /**
133 * Filter the query vars which disable the language filter in a query
134 *
135 * @since 2.3.5
136 *
137 * @param array $excludes Query vars excluded from the language filter
138 * @param object $query WP Query
139 * @param object $lang Language
140 */
141 $excludes = apply_filters( 'pll_filter_query_excluded_query_vars', self::$excludes, $this->query, $lang );
142
143 // Do not filter the query if the language is already specified in another way
144 foreach ( $excludes as $k ) {
145 if ( ! empty( $qvars[ $k ] ) ) {
146 // Specific case for 'cat' as it can contain negative values
147 if ( 'cat' === $k ) {
148 foreach ( explode( ',', $qvars['cat'] ) as $cat ) {
149 if ( $cat > 0 ) {
150 return;
151 }
152 }
153 } else {
154 return;
155 }
156 }
157 }
158
159 $taxonomies = array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) );
160
161 foreach ( $taxonomies as $tax ) {
162 $tax = get_taxonomy( $tax );
163 if ( ! empty( $qvars[ $tax->query_var ] ) ) {
164 return;
165 }
166 }
167
168 if ( ! empty( $qvars['tax_query'] ) && $this->have_translated_taxonomy( $qvars['tax_query'] ) ) {
169 return;
170 }
171
172 // Filter queries according to the requested language
173 if ( ! empty( $lang ) ) {
174 $taxonomies = $this->get_queried_taxonomies();
175
176 if ( $taxonomies && ( empty( $qvars['post_type'] ) || 'any' === $qvars['post_type'] ) ) {
177 foreach ( $taxonomies as $taxonomy ) {
178 $tax_object = get_taxonomy( $taxonomy );
179 if ( $this->model->is_translated_post_type( $tax_object->object_type ) ) {
180 $this->set_language( $lang );
181 break;
182 }
183 }
184 } elseif ( empty( $qvars['post_type'] ) || $this->model->is_translated_post_type( $qvars['post_type'] ) ) {
185 $this->set_language( $lang );
186 }
187 }
188 } else {
189 // Do not filter untranslatable post types such as nav_menu_item
190 if ( isset( $qvars['post_type'] ) && ! $this->model->is_translated_post_type( $qvars['post_type'] ) && ( empty( $qvars['tax_query'] ) || ! $this->have_translated_taxonomy( $qvars['tax_query'] ) ) ) {
191 unset( $qvars['lang'] );
192 }
193
194 // Unset 'all' query var (mainly for admin language filter).
195 if ( isset( $qvars['lang'] ) && 'all' === $qvars['lang'] ) {
196 unset( $qvars['lang'] );
197 }
198 }
199 }
200 }
201