PluginProbe
Polylang / 3.0.2
Polylang v3.0.2
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 3.0.2, at include/query.php

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