PluginProbe
Polylang / 2.2
Polylang v2.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
← All changes | include/query.php +50 -79 3.02.2 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -/**
3 - * @package Polylang
4 - */
5 2
6 3 /**
7 4 * A class to manipulate the language query var in WP_Query
8 5 *
@@ -8,17 +5,31 @@
8 5 *
9 6 * @since 2.2
10 7 */
11 8 class PLL_Query {
12 - /**
13 - * @var PLL_Model
14 - */
15 - public $model;
16 9
17 - /**
18 - * @var WP_Query
19 - */
20 - public $query;
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 + 'cat',
21 + 'tag_id',
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 + );
21 32
22 33 /**
23 34 * Constructor
24 35 *
@@ -23,10 +34,10 @@
23 34 * Constructor
24 35 *
25 36 * @since 2.2
26 37 *
27 - * @param WP_Query $query Reference to the WP_Query object.
28 - * @param PLL_Model $model Instance of PLL_Model.
38 + * @param array $query Reference to the WP_Query object
39 + * @param object $model
29 40 */
30 41 public function __construct( &$query, &$model ) {
31 42 $this->query = &$query;
32 43 $this->model = &$model;
@@ -32,35 +43,10 @@
32 43 $this->model = &$model;
33 44 }
34 45
35 46 /**
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 47 * Check if translated taxonomy is queried
61 48 * Compatible with nested queries introduced in WP 4.1
62 - *
63 49 * @see https://wordpress.org/support/topic/tax_query-bug
64 50 *
65 51 * @since 1.7
66 52 *
@@ -67,18 +53,16 @@
67 53 * @param array $tax_queries
68 54 * @return bool
69 55 */
70 56 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 - }
57 + foreach ( $tax_queries as $tax_query ) {
58 + if ( isset( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) && ! ( isset( $tax_query['operator'] ) && 'NOT IN' === $tax_query['operator'] ) ) {
59 + return true;
60 + }
76 61
77 - // Nested queries
78 - elseif ( is_array( $tax_query ) && $this->have_translated_taxonomy( $tax_query ) ) {
79 - return true;
80 - }
62 + // Nested queries
63 + elseif ( is_array( $tax_query ) && $this->have_translated_taxonomy( $tax_query ) ) {
64 + return true;
81 65 }
82 66 }
83 67
84 68 return false;
@@ -95,66 +79,53 @@
95 79 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 80 }
97 81
98 82 /**
99 - * Sets the language in query.
100 - * Optimized for (and requires) WP 3.5+.
83 + * Sets the language in query
84 + * Optimized for ( needs ) WP 3.5+
101 85 *
102 86 * @since 2.2
103 87 *
104 - * @param PLL_Language $lang Language object.
105 - * @return void
88 + * @param object $lang
106 89 */
107 90 public function set_language( $lang ) {
108 91 // Defining directly the tax_query ( rather than setting 'lang' avoids transforming the query by WP )
109 - $lang_query = array(
92 + $this->query->query_vars['tax_query'][] = array(
110 93 'taxonomy' => 'language',
111 94 'field' => 'term_taxonomy_id', // Since WP 3.5
112 95 'terms' => $lang->term_taxonomy_id,
113 96 'operator' => 'IN',
114 97 );
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 98 }
134 99
135 100 /**
136 - * Adds the language in the query after it has checked that it won't conflict with other query vars.
101 + * Add the language in query after it has checked that it won't conflict with other query vars
137 102 *
138 103 * @since 2.2
139 104 *
140 - * @param PLL_Language $lang Language.
141 - * @return void
105 + * @param object $lang Language
142 106 */
143 107 public function filter_query( $lang ) {
144 108 $qvars = &$this->query->query_vars;
145 109
146 - if ( ! $this->is_already_filtered( $qvars ) ) {
110 + // Do not filter the query if the language is already specified in another way
111 + if ( ! isset( $qvars['lang'] ) ) {
112 + foreach ( self::$excludes as $k ) {
113 + if ( ! empty( $qvars[ $k ] ) ) {
114 + return;
115 + }
116 + }
117 +
147 118 $taxonomies = array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) );
148 119
149 120 foreach ( $taxonomies as $tax ) {
150 - $tax_object = get_taxonomy( $tax );
151 - if ( ! empty( $tax_object ) && ! empty( $qvars[ $tax_object->query_var ] ) ) {
121 + $tax = get_taxonomy( $tax );
122 + if ( ! empty( $qvars[ $tax->query_var ] ) ) {
152 123 return;
153 124 }
154 125 }
155 126
156 - if ( ! empty( $qvars['tax_query'] ) && $this->have_translated_taxonomy( $qvars['tax_query'] ) ) {
127 + if ( ! empty( $qvars['tax_query'] ) && is_array( $qvars['tax_query'] ) && $this->have_translated_taxonomy( $qvars['tax_query'] ) ) {
157 128 return;
158 129 }
159 130
160 131 // Filter queries according to the requested language
@@ -163,9 +134,9 @@
163 134
164 135 if ( $taxonomies && ( empty( $qvars['post_type'] ) || 'any' === $qvars['post_type'] ) ) {
165 136 foreach ( $taxonomies as $taxonomy ) {
166 137 $tax_object = get_taxonomy( $taxonomy );
167 - if ( ! empty( $tax_object ) && $this->model->is_translated_post_type( $tax_object->object_type ) ) {
138 + if ( $this->model->is_translated_post_type( $tax_object->object_type ) ) {
168 139 $this->set_language( $lang );
169 140 break;
170 141 }
171 142 }
@@ -174,9 +145,9 @@
174 145 }
175 146 }
176 147 } else {
177 148 // 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'] ) ) ) {
149 + if ( isset( $qvars['post_type'] ) && ! $this->model->is_translated_post_type( $qvars['post_type'] ) ) {
179 150 unset( $qvars['lang'] );
180 151 }
181 152
182 153 // Unset 'all' query var (mainly for admin language filter).