PluginProbe
Polylang / 2.0.3
Polylang v2.0.3
3.8.10 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 All 234 releases
polylang / frontend / frontend-auto-translate.php

frontend-auto-translate.php in Polylang 2.0.3, at frontend/frontend-auto-translate.php

237 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * auto translates the posts and terms ids
5 * useful for example for themes querying a specific cat
6 *
7 * @since 1.1
8 */
9 class PLL_Frontend_Auto_Translate {
10 public $model, $curlang;
11
12 /**
13 * constructor
14 *
15 * @since 1.1
16 *
17 * @param object $polylang
18 */
19 public function __construct( &$polylang ) {
20 $this->model = &$polylang->model;
21 $this->curlang = &$polylang->curlang;
22
23 add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); // after main Polylang filter
24 add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
25 }
26
27 /**
28 * helper function to get the translated post in the current language
29 *
30 * since 1.8
31 *
32 * @param int $post_id
33 * @return int
34 */
35 protected function get_post( $post_id ) {
36 return $this->model->post->get( $post_id, $this->curlang );
37 }
38
39 /**
40 * helper function to get the translated term in the current language
41 *
42 * since 1.8
43 *
44 * @param int $term_id
45 * @return int
46 */
47 protected function get_term( $term_id ) {
48 return $this->model->term->get( $term_id, $this->curlang );
49 }
50
51 /**
52 * filters posts query to automatically translate included ids
53 *
54 * @since 1.1
55 *
56 * @param object $query WP_Query object
57 */
58 public function pre_get_posts( $query ) {
59 global $wpdb;
60 $qv = &$query->query_vars;
61
62 if ( $query->is_main_query() || ! empty( $qv['lang'] ) || ( ! empty( $qv['post_type'] ) && ! $this->model->is_translated_post_type( $qv['post_type'] ) ) ) {
63 return;
64 }
65
66 // /!\ always keep untranslated as is
67
68 // term ids separated by a comma
69 $arr = array();
70 if ( ! empty( $qv['cat'] ) ) {
71 foreach ( explode( ',', $qv['cat'] ) as $cat ) {
72 $tr = $this->get_term( abs( $cat ) );
73 $arr[] = $cat < 0 ? -$tr : $tr;
74 }
75
76 $qv['cat'] = implode( ',', $arr );
77 }
78
79 // category_name
80 $arr = array();
81 if ( ! empty( $qv['category_name'] ) ) {
82 foreach ( explode( ',', $qv['category_name'] ) as $slug ) {
83 $arr[] = ( ( $cat = wpcom_vip_get_category_by_slug( $slug ) ) && ( $tr_id = $this->get_term( $cat->term_id ) ) && ! is_wp_error( $tr = get_category( $tr_id ) ) ) ? $tr->slug : $slug;
84 }
85
86 $qv['category_name'] = implode( ',', $arr );
87 }
88
89 // array of term ids
90 foreach ( array( 'category__and', 'category__in', 'category__not_in', 'tag__and', 'tag__in', 'tag__not_in' ) as $key ) {
91 $arr = array();
92 if ( ! empty( $qv[ $key ] ) ) {
93 foreach ( $qv[ $key ] as $cat ) {
94 $arr[] = ( $tr = $this->get_term( $cat ) ) ? $tr : $cat;
95 }
96 $qv[ $key ] = $arr;
97 }
98 }
99
100 // tag
101 $arr = array();
102 if ( ! empty( $qv['tag'] ) ) {
103 $sep = strpos( $qv['tag'], ',' ) !== false ? ',' : '+'; // two possible separators for tag slugs
104 foreach ( explode( $sep, $qv['tag'] ) as $slug ) {
105 $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, 'post_tag' ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_tag( $tr_id ) ) ) ? $tr->slug : $slug;
106 }
107
108 $qv['tag'] = implode( $sep, $arr );
109 }
110
111 // tag_id can only take one id
112 if ( ! empty( $qv['tag_id'] ) && $tr_id = $this->get_term( $qv['tag_id'] ) ) {
113 $qv['tag_id'] = $tr_id;
114 }
115
116 // array of tag slugs
117 foreach ( array( 'tag_slug__and', 'tag_slug__in' ) as $key ) {
118 $arr = array();
119 if ( ! empty( $qv[ $key ] ) ) {
120 foreach ( $qv[ $key ] as $slug ) {
121 $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, 'post_tag' ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_tag( $tr_id ) ) ) ? $tr->slug : $slug;
122 }
123
124 $qv[ $key ] = $arr;
125 }
126 }
127
128 // custom taxonomies
129 // according to codex, this type of query is deprecated as of WP 3.1 but it does not appear in WP 3.5 source code
130 foreach ( array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) ) as $taxonomy ) {
131 $tax = get_taxonomy( $taxonomy );
132 $arr = array();
133 if ( ! empty( $qv[ $tax->query_var ] ) ) {
134 $sep = strpos( $qv[ $tax->query_var ], ',' ) !== false ? ',' : '+'; // two possible separators
135 foreach ( explode( $sep, $qv[ $tax->query_var ] ) as $slug ) {
136 $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, $taxonomy ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_term( $tr_id, $taxonomy ) ) ) ? $tr->slug : $slug;
137 }
138
139 $qv[ $tax->query_var ] = implode( $sep, $arr );
140 }
141 }
142
143 // tax_query since WP 3.1
144 if ( ! empty( $qv['tax_query'] ) && is_array( $qv['tax_query'] ) ) {
145 $qv['tax_query'] = $this->translate_tax_query_recursive( $qv['tax_query'] );
146 }
147
148 // p, page_id, post_parent can only take one id
149 foreach ( array( 'p', 'page_id', 'post_parent' ) as $key ) {
150 if ( ! empty( $qv[ $key ] ) && $tr_id = $this->get_post( $qv[ $key ] ) ) {
151 $qv[ $key ] = $tr_id;
152 }
153 }
154
155 // name, pagename can only take one slug
156 foreach ( array( 'name', 'pagename' ) as $key ) {
157 if ( ! empty( $qv[ $key ] ) ) {
158 // no function to get post by name except get_posts itself
159 $post_type = empty( $qv['post_type'] ) ? 'post' : $qv['post_type'];
160 $id = $wpdb->get_var( $wpdb->prepare( "SELECT ID from $wpdb->posts WHERE post_type=%s AND post_name=%s", $post_type, $qv[ $key ] ) );
161 $qv[ $key ] = ( $id && ( $tr_id = $this->get_post( $id ) ) && $tr = get_post( $tr_id ) ) ? $tr->post_name : $qv[ $key ];
162 }
163 }
164
165 // array of post ids
166 // post_parent__in & post_parent__not_in since WP 3.6
167 foreach ( array( 'post__in', 'post__not_in', 'post_parent__in', 'post_parent__not_in' ) as $key ) {
168 $arr = array();
169 if ( ! empty( $qv[ $key ] ) ) {
170 // post__in used by the 2 functions below
171 // useless to filter them as output is already in the right language and would result in performance loss
172 foreach ( debug_backtrace() as $trace ) {
173 if ( in_array( $trace['function'], array( 'wp_nav_menu', 'gallery_shortcode' ) ) ) {
174 return;
175 }
176 }
177
178 foreach ( $qv[ $key ] as $p ) {
179 $arr[] = ( $tr = $this->get_post( $p ) ) ? $tr : $p;
180 }
181
182 $qv[ $key ] = $arr;
183 }
184 }
185 }
186
187 /**
188 * filters terms query to automatically translate included ids
189 *
190 * @since 1.1.1
191 *
192 * @param array $args
193 * @param array $taxonomies
194 * @return array modified $args
195 */
196 public function get_terms_args( $args, $taxonomies ) {
197 if ( ! empty( $args['include'] ) && $this->model->is_translated_taxonomy( $taxonomies ) ) {
198 foreach ( wp_parse_id_list( $args['include'] ) as $id ) {
199 $arr[] = ( $tr = $this->get_term( $id ) ) ? $tr : $id;
200 }
201
202 $args['include'] = $arr;
203 }
204 return $args;
205 }
206
207 /**
208 * translates tax queries
209 * compatible with nested tax queries introduced in WP 4.1
210 *
211 * @since 1.7
212 *
213 * @param array $tax_queries
214 * @return array translated tax queries
215 */
216 protected function translate_tax_query_recursive( $tax_queries ) {
217 foreach ( $tax_queries as $key => $q ) {
218 if ( isset( $q['taxonomy'] ) && $this->model->is_translated_taxonomy( $q['taxonomy'] ) ) {
219 $arr = array();
220 $field = isset( $q['field'] ) && in_array( $q['field'], array( 'slug', 'name' ) ) ? $q['field'] : 'term_id';
221 foreach ( (array) $q['terms'] as $t ) {
222 $arr[] = ( ( $tag = wpcom_vip_get_term_by( $field, $t, $q['taxonomy'] ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_term( $tr_id, $q['taxonomy'] ) ) ) ? $tr->$field : $t;
223 }
224
225 $tax_queries[ $key ]['terms'] = $arr;
226 }
227
228 // nested queries
229 elseif ( is_array( $q ) ) {
230 $tax_queries[ $key ] = $this->translate_tax_query_recursive( $q );
231 }
232 }
233
234 return $tax_queries;
235 }
236 }
237