PluginProbe
Polylang / 2.3.8
Polylang v2.3.8
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.3.8, at include/query.php

200 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 * @see https://wordpress.org/support/topic/tax_query-bug
50 *
51 * @since 1.7
52 *
53 * @param array $tax_queries
54 * @return bool
55 */
56 protected function have_translated_taxonomy( $tax_queries ) {
57 if ( is_array( $tax_queries ) ) {
58 foreach ( $tax_queries as $tax_query ) {
59 if ( isset( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) && ! ( isset( $tax_query['operator'] ) && 'NOT IN' === $tax_query['operator'] ) ) {
60 return true;
61 }
62
63 // Nested queries
64 elseif ( is_array( $tax_query ) && $this->have_translated_taxonomy( $tax_query ) ) {
65 return true;
66 }
67 }
68 }
69
70 return false;
71 }
72
73 /**
74 * Get queried taxonomies
75 *
76 * @since 2.2
77 *
78 * @return array queried taxonomies
79 */
80 public function get_queried_taxonomies() {
81 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();
82 }
83
84 /**
85 * Sets the language in query
86 * Optimized for ( needs ) WP 3.5+
87 *
88 * @since 2.2
89 *
90 * @param object $lang
91 */
92 public function set_language( $lang ) {
93 // Defining directly the tax_query ( rather than setting 'lang' avoids transforming the query by WP )
94 $lang_query = array(
95 'taxonomy' => 'language',
96 'field' => 'term_taxonomy_id', // Since WP 3.5
97 'terms' => $lang->term_taxonomy_id,
98 'operator' => 'IN',
99 );
100
101 $tax_query = &$this->query->query_vars['tax_query'];
102
103 if ( isset( $tax_query['relation'] ) && 'OR' === $tax_query['relation'] ) {
104 $tax_query = array(
105 $lang_query,
106 array( $tax_query ),
107 'relation' => 'AND',
108 );
109 } elseif ( is_array( $tax_query ) ) {
110 // The tax query is expected to be *always* an array, but it seems that 3rd parties fill it with a string
111 // Causing a fatal error if we don't check it.
112 // See https://wordpress.org/support/topic/fatal-error-2947/
113 $tax_query[] = $lang_query;
114 } elseif ( empty( $tax_query ) ) {
115 // Supposing the tax query has been wrongly filled with an empty string
116 $tax_query = array( $lang_query );
117 }
118 }
119
120 /**
121 * Add the language in query after it has checked that it won't conflict with other query vars
122 *
123 * @since 2.2
124 *
125 * @param object $lang Language
126 */
127 public function filter_query( $lang ) {
128 $qvars = &$this->query->query_vars;
129
130 if ( ! isset( $qvars['lang'] ) ) {
131 /**
132 * Filter the query vars which disable the language filter in a query
133 *
134 * @since 2.3.5
135 *
136 * @param array $excludes Query vars excluded from the language filter
137 * @param object $query WP Query
138 * @param object $lang Language
139 */
140 $excludes = apply_filters( 'pll_filter_query_excluded_query_vars', self::$excludes, $this->query, $lang );
141
142 // Do not filter the query if the language is already specified in another way
143 foreach ( $excludes as $k ) {
144 if ( ! empty( $qvars[ $k ] ) ) {
145 // Specific case for 'cat' as it can contain negative values
146 if ( 'cat' === $k ) {
147 foreach ( explode( ',', $qvars['cat'] ) as $cat ) {
148 if ( $cat > 0 ) {
149 return;
150 }
151 }
152 } else {
153 return;
154 }
155 }
156 }
157
158 $taxonomies = array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) );
159
160 foreach ( $taxonomies as $tax ) {
161 $tax = get_taxonomy( $tax );
162 if ( ! empty( $qvars[ $tax->query_var ] ) ) {
163 return;
164 }
165 }
166
167 if ( ! empty( $qvars['tax_query'] ) && $this->have_translated_taxonomy( $qvars['tax_query'] ) ) {
168 return;
169 }
170
171 // Filter queries according to the requested language
172 if ( ! empty( $lang ) ) {
173 $taxonomies = $this->get_queried_taxonomies();
174
175 if ( $taxonomies && ( empty( $qvars['post_type'] ) || 'any' === $qvars['post_type'] ) ) {
176 foreach ( $taxonomies as $taxonomy ) {
177 $tax_object = get_taxonomy( $taxonomy );
178 if ( $this->model->is_translated_post_type( $tax_object->object_type ) ) {
179 $this->set_language( $lang );
180 break;
181 }
182 }
183 } elseif ( empty( $qvars['post_type'] ) || $this->model->is_translated_post_type( $qvars['post_type'] ) ) {
184 $this->set_language( $lang );
185 }
186 }
187 } else {
188 // Do not filter untranslatable post types such as nav_menu_item
189 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'] ) ) ) {
190 unset( $qvars['lang'] );
191 }
192
193 // Unset 'all' query var (mainly for admin language filter).
194 if ( isset( $qvars['lang'] ) && 'all' === $qvars['lang'] ) {
195 unset( $qvars['lang'] );
196 }
197 }
198 }
199 }
200