PluginProbe
Polylang / 2.1
Polylang v2.1
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/translated-object.php +29 -96 2.92.1 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -/**
3 - * @package Polylang
4 - */
5 2
6 3 /**
7 4 * Setups the objects languages and translations model
8 5 *
@@ -9,9 +6,9 @@
9 6 * @since 1.8
10 7 */
11 8 abstract class PLL_Translated_Object {
12 9 public $model;
13 - protected $object_type, $type, $tax_language, $tax_translations, $tax_tt;
10 + protected $object_type, $tax_language, $tax_translations, $tax_tt;
14 11
15 12 /**
16 13 * Constructor
17 14 *
@@ -40,18 +37,13 @@
40 37 * @param string $taxonomy Polylang taxonomy depending if we are looking for a post ( or term ) language ( or translation )
41 38 * @return bool|object the term associated to the object in the requested taxonomy if exists, false otherwise
42 39 */
43 40 public function get_object_term( $object_id, $taxonomy ) {
44 - if ( empty( $object_id ) || is_wp_error( $object_id ) ) {
41 + if ( empty( $object_id ) ) {
45 42 return false;
46 43 }
47 44
48 45 $object_id = (int) $object_id;
49 -
50 - if ( $object_id < 0 ) {
51 - return false;
52 - }
53 -
54 46 $term = get_object_term_cache( $object_id, $taxonomy );
55 47
56 48 if ( false === $term ) {
57 49 // query language and translations at the same time
@@ -57,9 +49,8 @@
57 49 // query language and translations at the same time
58 50 $taxonomies = array( $this->tax_language, $this->tax_translations );
59 51
60 52 // query terms
61 - $terms = array();
62 53 foreach ( wp_get_object_terms( $object_id, $taxonomies, array( 'update_term_meta_cache' => false ) ) as $t ) {
63 54 $terms[ $t->taxonomy ] = $t;
64 55 if ( $t->taxonomy == $taxonomy ) {
65 56 $term = $t;
@@ -79,19 +70,16 @@
79 70 return empty( $term ) ? false : $term;
80 71 }
81 72
82 73 /**
83 - * Tells whether a translation term must be updated
74 + * Tells wether to store a translation term
84 75 *
85 - * @since 2.3
76 + * @since 1.8
86 77 *
87 - * @param array $id Post id or term id
88 - * @param array $translations An associative array of translations with language code as key and translation id as value
78 + * @param array $translations an associative array of translations with language code as key and translation id as value
89 79 */
90 - protected function should_update_translation_group( $id, $translations ) {
91 - // Don't do anything if no translations have been added to the group
92 - $old_translations = $this->get_translations( $id ); // Includes at least $id itself
93 - return count( array_diff_assoc( $translations, $old_translations ) ) > 0;
80 + protected function keep_translation_group( $translations ) {
81 + return count( $translations ) > 1;
94 82 }
95 83
96 84 /**
97 85 * Saves translations for posts or terms
@@ -97,10 +85,10 @@
97 85 * Saves translations for posts or terms
98 86 *
99 87 * @since 0.5
100 88 *
101 - * @param int $id Post id or term id
102 - * @param array $translations An associative array of translations with language code as key and translation id as value
89 + * @param int $id post id or term id
90 + * @param array $translations an associative array of translations with language code as key and translation id as value
103 91 */
104 92 public function save_translations( $id, $translations ) {
105 93 $id = (int) $id;
106 94
@@ -116,23 +104,24 @@
116 104 foreach ( array_diff_assoc( $old_translations, $translations ) as $object_id ) {
117 105 $this->delete_translation( $object_id );
118 106 }
119 107
120 - // Check id we need to create or update the translation group
121 - if ( $this->should_update_translation_group( $id, $translations ) ) {
108 + // don't create a translation group for untranslated posts as it is useless
109 + // but we need one for terms to allow relationships remap when importing from a WXR file
110 + if ( $this->keep_translation_group( $translations ) ) {
122 111 $terms = wp_get_object_terms( $translations, $this->tax_translations );
123 112 $term = reset( $terms );
124 113
125 114 // create a new term if necessary
126 115 if ( empty( $term ) ) {
127 - wp_insert_term( $group = uniqid( 'pll_' ), $this->tax_translations, array( 'description' => maybe_serialize( $translations ) ) );
116 + wp_insert_term( $group = uniqid( 'pll_' ), $this->tax_translations, array( 'description' => serialize( $translations ) ) );
128 117 }
129 118 else {
130 119 // take care not to overwrite extra data stored in description field, if any
131 - $d = maybe_unserialize( $term->description );
120 + $d = unserialize( $term->description );
132 121 $d = is_array( $d ) ? array_diff_key( $d, $old_translations ) : array(); // remove old translations
133 122 $d = array_merge( $d, $translations ); // add new one
134 - wp_update_term( $group = (int) $term->term_id, $this->tax_translations, array( 'description' => maybe_serialize( $d ) ) );
123 + wp_update_term( $group = (int) $term->term_id, $this->tax_translations, array( 'description' => serialize( $d ) ) );
135 124 }
136 125
137 126 // link all translations to the new term
138 127 foreach ( $translations as $p ) {
@@ -161,19 +150,18 @@
161 150 $id = (int) $id;
162 151 $term = $this->get_object_term( $id, $this->tax_translations );
163 152
164 153 if ( ! empty( $term ) ) {
165 - $d = maybe_unserialize( $term->description );
166 - if ( is_array( $d ) ) {
167 - $slug = array_search( $id, $this->get_translations( $id ) ); // In case some plugin stores the same value with different key.
168 - unset( $d[ $slug ] );
169 - }
154 + $d = unserialize( $term->description );
155 + $slug = array_search( $id, $this->get_translations( $id ) ); // in case some plugin stores the same value with different key
156 + unset( $d[ $slug ] );
170 157
171 158 if ( empty( $d ) ) {
172 159 wp_delete_term( (int) $term->term_id, $this->tax_translations );
173 - } else {
174 - wp_update_term( (int) $term->term_id, $this->tax_translations, array( 'description' => maybe_serialize( $d ) ) );
175 160 }
161 + else {
162 + wp_update_term( (int) $term->term_id, $this->tax_translations, array( 'description' => serialize( $d ) ) );
163 + }
176 164 }
177 165 }
178 166
179 167 /**
@@ -185,11 +173,11 @@
185 173 * @return array an associative array of translations with language code as key and translation id as value
186 174 */
187 175 public function get_translations( $id ) {
188 176 $term = $this->get_object_term( $id, $this->tax_translations );
189 - $translations = empty( $term ) ? array() : maybe_unserialize( $term->description );
177 + $translations = empty( $term ) ? array() : unserialize( $term->description );
190 178
191 - // make sure we return only translations ( thus we allow plugins to store other information in the array )
179 + // make sure we return only translations ( thus we allow plugins to store other informations in the array )
192 180 if ( is_array( $translations ) ) {
193 181 $translations = array_intersect_key( $translations, array_flip( $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) );
194 182 }
195 183
@@ -229,9 +217,8 @@
229 217 * @param int|string|object $lang language ( term_id or slug or object )
230 218 * @return bool|int the translation post id or term id if exists, otherwise the post id or term id, false if the post has no language
231 219 */
232 220 public function get( $id, $lang ) {
233 - $id = (int) $id;
234 221 $obj_lang = $this->get_language( $id ); // FIXME is this necessary?
235 222 if ( ! $lang || ! $obj_lang ) {
236 223 return false;
237 224 }
@@ -244,26 +231,26 @@
244 231 * A where clause to add to sql queries when filtering by language is needed directly in query
245 232 *
246 233 * @since 1.2
247 234 *
248 - * @param object|array|string $lang a PLL_Language object or a comma separated list of language slug or an array of language slugs
235 + * @param object|array|string $lang a PLL_Language object or a comma separated list of languag slug or an array of language slugs
249 236 * @return string where clause
250 237 */
251 238 public function where_clause( $lang ) {
239 + global $wpdb;
252 240 $tt_id = $this->tax_tt;
253 241
254 242 // $lang is an object
255 243 // generally the case if the query is coming from Polylang
256 244 if ( is_object( $lang ) ) {
257 - return ' AND pll_tr.term_taxonomy_id = ' . absint( $lang->$tt_id );
245 + return $wpdb->prepare( ' AND pll_tr.term_taxonomy_id = %d', $lang->$tt_id );
258 246 }
259 247
260 248 // $lang is a comma separated list of slugs ( or an array of slugs )
261 249 // generally the case is the query is coming from outside with 'lang' parameter
262 - $slugs = is_array( $lang ) ? $lang : explode( ',', $lang );
263 - $languages = array();
250 + $slugs = is_array( $lang ) ? $lang : explode( ',', $lang );
264 251 foreach ( $slugs as $slug ) {
265 - $languages[] = absint( $this->model->get_language( $slug )->$tt_id );
252 + $languages[] = (int) $this->model->get_language( $slug )->$tt_id;
266 253 }
267 254
268 255 return ' AND pll_tr.term_taxonomy_id IN ( ' . implode( ',', $languages ) . ' )';
269 256 }
@@ -279,61 +266,7 @@
279 266 */
280 267 public function get_objects_in_language( $lang ) {
281 268 global $wpdb;
282 269 $tt_id = $this->tax_tt;
283 -
284 - $last_changed = wp_cache_get_last_changed( 'terms' );
285 - $cache_key = "polylang:get_objects_in_language:{$lang->$tt_id}:{$last_changed}";
286 - $cache = wp_cache_get( $cache_key, 'terms' );
287 -
288 - if ( false === $cache ) {
289 - $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $lang->$tt_id ) );
290 - wp_cache_set( $cache_key, $object_ids, 'terms' );
291 - } else {
292 - $object_ids = (array) $cache;
293 - }
294 -
295 - if ( ! $object_ids ) {
296 - return array();
297 - }
298 -
299 - return $object_ids;
300 - }
301 -
302 - /**
303 - * Check if a user can synchronize translations
304 - *
305 - * @since 2.6
306 - *
307 - * @param int $id Object id
308 - * @return bool
309 - */
310 - public function current_user_can_synchronize( $id ) {
311 - /**
312 - * Filters whether a synchronization capability check should take place
313 - *
314 - * @since 2.6
315 - *
316 - * @param $check null to enable the capability check,
317 - * true to always allow the synchronization,
318 - * false to always disallow the synchronization.
319 - * Defaults to true.
320 - * @param $id The synchronization source object id
321 - */
322 - $check = apply_filters( "pll_pre_current_user_can_synchronize_{$this->type}", true, $id );
323 - if ( null !== $check ) {
324 - return $check;
325 - }
326 -
327 - if ( ! current_user_can( "edit_{$this->type}", $id ) ) {
328 - return false;
329 - }
330 -
331 - foreach ( $this->get_translations( $id ) as $tr_id ) {
332 - if ( $tr_id !== $id && ! current_user_can( "edit_{$this->type}", $tr_id ) ) {
333 - return false;
334 - }
335 - }
336 -
337 - return true;
270 + return $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $lang->$tt_id ) );
338 271 }
339 272 }