PluginProbe
Polylang / 2.5
Polylang v2.5
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 | modules/sync/sync-metas.php +38 -106 3.02.5 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -/**
3 - * @package Polylang
4 - */
5 2
6 3 /**
7 4 * Abstract class to manage the copy and synchronization of metas
8 5 *
@@ -8,35 +5,12 @@
8 5 *
9 6 * @since 2.3
10 7 */
11 8 abstract class PLL_Sync_Metas {
12 - /**
13 - * @var PLL_Model
14 - */
15 9 public $model;
10 + protected $meta_type, $prev_value, $to_copy;
16 11
17 12 /**
18 - * Meta type. Typically 'post' or 'term'.
19 - *
20 - * @var string
21 - */
22 - protected $meta_type;
23 -
24 - /**
25 - * Stores the previous values when updating a meta.
26 - *
27 - * @var array
28 - */
29 - protected $prev_value;
30 -
31 - /**
32 - * Stores the metas to synchronize before deleting them.
33 - *
34 - * @var array
35 - */
36 - protected $to_copy;
37 -
38 - /**
39 13 * Constructor
40 14 *
41 15 * @since 2.3
42 16 *
@@ -44,12 +18,8 @@
44 18 */
45 19 public function __construct( &$polylang ) {
46 20 $this->model = &$polylang->model;
47 21
48 - add_filter( "add_{$this->meta_type}_metadata", array( $this, 'can_synchronize_metadata' ), 1, 3 );
49 - add_filter( "update_{$this->meta_type}_metadata", array( $this, 'can_synchronize_metadata' ), 1, 3 );
50 - add_filter( "delete_{$this->meta_type}_metadata", array( $this, 'can_synchronize_metadata' ), 1, 3 );
51 -
52 22 $this->add_all_meta_actions();
53 23
54 24 add_action( "pll_save_{$this->meta_type}", array( $this, 'save_object' ), 10, 3 );
55 25 }
@@ -57,10 +27,8 @@
57 27 /**
58 28 * Removes "added_{$this->meta_type}_meta" action
59 29 *
60 30 * @since 2.3
61 - *
62 - * @return void
63 31 */
64 32 protected function remove_add_meta_action() {
65 33 remove_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
66 34 }
@@ -68,10 +36,8 @@
68 36 /**
69 37 * Removes all meta synchronization actions and filters
70 38 *
71 39 * @since 2.3
72 - *
73 - * @return void
74 40 */
75 41 protected function remove_all_meta_actions() {
76 42 $this->remove_add_meta_action();
77 43
@@ -85,10 +51,8 @@
85 51 /**
86 52 * Adds "added_{$this->meta_type}_meta" action
87 53 *
88 54 * @since 2.3
89 - *
90 - * @return void
91 55 */
92 56 protected function restore_add_meta_action() {
93 57 add_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
94 58 }
@@ -96,10 +60,8 @@
96 60 /**
97 61 * Adds meta synchronization actions and filters
98 62 *
99 63 * @since 2.3
100 - *
101 - * @return void
102 64 */
103 65 protected function add_all_meta_actions() {
104 66 $this->restore_add_meta_action();
105 67
@@ -137,61 +99,35 @@
137 99 return apply_filters( "pll_translate_{$this->meta_type}_meta", maybe_unserialize( $value ), $key, $lang, $from, $to );
138 100 }
139 101
140 102 /**
141 - * Get the custom fields to copy or synchronize.
103 + * Get the custom fields to copy or synchronize
142 104 *
143 105 * @since 2.3
144 106 *
145 - * @param int $from Id of the post from which we copy informations.
146 - * @param int $to Id of the post to which we paste informations.
147 - * @param string $lang Language slug.
148 - * @param bool $sync True if it is synchronization, false if it is a copy.
149 - * @return string[] List of meta keys.
107 + * @param int $from Id of the post from which we copy informations
108 + * @param int $to Id of the post to which we paste informations
109 + * @param string $lang Language slug
110 + * @param bool $sync True if it is synchronization, false if it is a copy
111 + * @return array List of meta keys
150 112 */
151 113 protected function get_metas_to_copy( $from, $to, $lang, $sync = false ) {
152 114 /**
153 - * Filters the custom fields to copy or synchronize.
115 + * Filter the custom fields to copy or synchronize
154 116 *
155 117 * @since 0.6
156 118 * @since 1.9.2 The `$from`, `$to`, `$lang` parameters were added.
157 119 *
158 - * @param string[] $keys List of custom fields names.
159 - * @param bool $sync True if it is synchronization, false if it is a copy.
160 - * @param int $from Id of the post from which we copy informations.
161 - * @param int $to Id of the post to which we paste informations.
162 - * @param string $lang Language slug.
120 + * @param array $keys List of custom fields names
121 + * @param bool $sync True if it is synchronization, false if it is a copy
122 + * @param int $from Id of the post from which we copy informations
123 + * @param int $to Id of the post to which we paste informations
124 + * @param string $lang Language slug
163 125 */
164 126 return array_unique( apply_filters( "pll_copy_{$this->meta_type}_metas", array(), $sync, $from, $to, $lang ) );
165 127 }
166 128
167 129 /**
168 - * Disallow modifying synchronized meta if the current user can not modify translations
169 - *
170 - * @since 2.6
171 - *
172 - * @param null|bool $check Whether to allow adding/updating/deleting metadata.
173 - * @param int $id Object ID.
174 - * @param string $meta_key Meta key.
175 - * @return null|bool
176 - */
177 - public function can_synchronize_metadata( $check, $id, $meta_key ) {
178 - if ( ! $this->model->{$this->meta_type}->current_user_can_synchronize( $id ) ) {
179 - $tr_ids = $this->model->{$this->meta_type}->get_translations( $id );
180 -
181 - foreach ( $tr_ids as $lang => $tr_id ) {
182 - if ( $tr_id != $id ) {
183 - $to_copy = $this->get_metas_to_copy( $id, $tr_id, $lang, true );
184 - if ( in_array( $meta_key, $to_copy ) ) {
185 - return false;
186 - }
187 - }
188 - }
189 - }
190 - return $check;
191 - }
192 -
193 - /**
194 130 * Synchronize added metas across translations
195 131 *
196 132 * @since 2.3
197 133 *
@@ -198,9 +134,8 @@
198 134 * @param int $mid Meta id.
199 135 * @param int $id Object ID.
200 136 * @param string $meta_key Meta key.
201 137 * @param mixed $meta_value Meta value. Must be serializable if non-scalar.
202 - * @return void
203 138 */
204 139 public function add_meta( $mid, $id, $meta_key, $meta_value ) {
205 140 static $avoid_recursion = false;
206 141
@@ -212,9 +147,9 @@
212 147 if ( $tr_id != $id ) {
213 148 $to_copy = $this->get_metas_to_copy( $id, $tr_id, $lang, true );
214 149 if ( in_array( $meta_key, $to_copy ) ) {
215 150 $meta_value = $this->maybe_translate_value( $meta_value, $meta_key, $id, $tr_id, $lang );
216 - add_metadata( $this->meta_type, $tr_id, wp_slash( $meta_key ), is_object( $meta_value ) ? $meta_value : wp_slash( $meta_value ) );
151 + add_metadata( $this->meta_type, $tr_id, $meta_key, $meta_value );
217 152 }
218 153 }
219 154 }
220 155
@@ -250,9 +185,8 @@
250 185 * @param int $mid Meta id.
251 186 * @param int $id Object ID.
252 187 * @param string $meta_key Meta key.
253 188 * @param mixed $meta_value Meta value. Must be serializable if non-scalar.
254 - * @return void
255 189 */
256 190 public function update_meta( $mid, $id, $meta_key, $meta_value ) {
257 191 static $avoid_recursion = false;
258 192
@@ -259,24 +193,24 @@
259 193 if ( ! $avoid_recursion ) {
260 194 $avoid_recursion = true;
261 195 $hash = md5( "$id|$meta_key|" . maybe_serialize( $meta_value ) );
262 196
263 - $prev_meta = get_metadata_by_mid( $this->meta_type, $mid );
197 + $tr_ids = $this->model->{$this->meta_type}->get_translations( $id );
264 198
265 - if ( $prev_meta ) {
266 - $this->remove_add_meta_action(); // We don't want to sync back the new metas
267 - $tr_ids = $this->model->{$this->meta_type}->get_translations( $id );
268 -
269 - foreach ( $tr_ids as $lang => $tr_id ) {
270 - if ( $tr_id != $id && in_array( $meta_key, $this->get_metas_to_copy( $id, $tr_id, $lang, true ) ) ) {
199 + foreach ( $tr_ids as $lang => $tr_id ) {
200 + if ( $tr_id != $id ) {
201 + $to_copy = $this->get_metas_to_copy( $id, $tr_id, $lang, true );
202 + if ( in_array( $meta_key, $to_copy ) ) {
203 + $meta_value = $this->maybe_translate_value( $meta_value, $meta_key, $id, $tr_id, $lang );
204 + $prev_meta = get_metadata_by_mid( $this->meta_type, $mid );
271 205 if ( empty( $this->prev_value[ $hash ] ) || $this->prev_value[ $hash ] === $prev_meta->meta_value ) {
272 206 $prev_value = $this->maybe_translate_value( $prev_meta->meta_value, $meta_key, $id, $tr_id, $lang );
273 - $meta_value = $this->maybe_translate_value( $meta_value, $meta_key, $id, $tr_id, $lang );
274 - update_metadata( $this->meta_type, $tr_id, wp_slash( $meta_key ), is_object( $meta_value ) ? $meta_value : wp_slash( $meta_value ), $prev_value );
207 + $this->remove_add_meta_action(); // We don't want to sync back the new metas
208 + update_metadata( $this->meta_type, $tr_id, $meta_key, $meta_value, $prev_value );
209 + $this->restore_add_meta_action();
275 210 }
276 211 }
277 212 }
278 - $this->restore_add_meta_action();
279 213 }
280 214
281 215 unset( $this->prev_value[ $hash ] );
282 216 $avoid_recursion = false;
@@ -283,15 +217,14 @@
283 217 }
284 218 }
285 219
286 220 /**
287 - * Store metas to synchronize before deleting them.
221 + * Store metas to synchronize before deleting them
288 222 *
289 223 * @since 2.3
290 224 *
291 - * @param int[] $mids Not used.
225 + * @param array $mids Not used
292 226 * @param int $id Object ID.
293 - * @return void
294 227 */
295 228 public function store_metas_to_sync( $mids, $id ) {
296 229 $tr_ids = $this->model->{$this->meta_type}->get_translations( $id );
297 230
@@ -300,17 +233,16 @@
300 233 }
301 234 }
302 235
303 236 /**
304 - * Synchronizes deleted meta across translations.
237 + * Synchronize deleted meta across translations
305 238 *
306 239 * @since 2.3
307 240 *
308 - * @param int[] $mids Not used.
241 + * @param array $mids Not used
309 242 * @param int $id Object ID.
310 243 * @param string $key Meta key.
311 244 * @param mixed $value Meta value.
312 - * @return void
313 245 */
314 246 public function delete_meta( $mids, $id, $key, $value ) {
315 247 static $avoid_recursion = false;
316 248
@@ -324,9 +256,9 @@
324 256 if ( in_array( $key, $this->to_copy[ $id ][ $tr_id ] ) ) {
325 257 if ( '' !== $value && null !== $value && false !== $value ) { // Same test as WP
326 258 $value = $this->maybe_translate_value( $value, $key, $id, $tr_id, $lang );
327 259 }
328 - delete_metadata( $this->meta_type, $tr_id, wp_slash( $key ), is_object( $value ) ? $value : wp_slash( $value ) );
260 + delete_metadata( $this->meta_type, $tr_id, $key, $value );
329 261 }
330 262 }
331 263 }
332 264 }
@@ -342,9 +274,8 @@
342 274 * @param int $from Id of the source object
343 275 * @param int $to Id of the target object
344 276 * @param string $lang Language code of the target object
345 277 * @param bool $sync Optional, defaults to true. True if it is synchronization, false if it is a copy
346 - * @return void
347 278 */
348 279 public function copy( $from, $to, $lang, $sync = false ) {
349 280 $this->remove_all_meta_actions();
350 281
@@ -358,9 +289,9 @@
358 289 foreach ( $to_copy as $key ) {
359 290 if ( empty( $metas[ $key ] ) ) {
360 291 if ( ! empty( $tr_metas[ $key ] ) ) {
361 292 // If the meta key is not present in the source object, delete all values
362 - delete_metadata( $this->meta_type, $to, wp_slash( $key ) );
293 + delete_metadata( $this->meta_type, $to, $key );
363 294 }
364 295 } else {
365 296 if ( ! empty( $tr_metas[ $key ] ) && 1 === count( $metas[ $key ] ) && 1 === count( $tr_metas[ $key ] ) ) {
366 297 // One custom field to update
@@ -366,20 +297,20 @@
366 297 // One custom field to update
367 298 $value = reset( $metas[ $key ] );
368 299 $value = maybe_unserialize( $value );
369 300 $to_value = $this->maybe_translate_value( $value, $key, $from, $to, $lang );
370 - update_metadata( $this->meta_type, $to, wp_slash( $key ), is_object( $to_value ) ? $to_value : wp_slash( $to_value ) );
301 + update_metadata( $this->meta_type, $to, $key, $to_value );
371 302 } else {
372 303 // Multiple custom fields, either in the source or the target
373 304 if ( ! empty( $tr_metas[ $key ] ) ) {
374 305 // The synchronization of multiple values custom fields is easier if we delete all metas first
375 - delete_metadata( $this->meta_type, $to, wp_slash( $key ) );
306 + delete_metadata( $this->meta_type, $to, $key );
376 307 }
377 308
378 309 foreach ( $metas[ $key ] as $value ) {
379 310 $value = maybe_unserialize( $value );
380 311 $to_value = $this->maybe_translate_value( $value, $key, $from, $to, $lang );
381 - add_metadata( $this->meta_type, $to, wp_slash( $key ), is_object( $to_value ) ? $to_value : wp_slash( $to_value ) );
312 + add_metadata( $this->meta_type, $to, $key, $to_value );
382 313 }
383 314 }
384 315 }
385 316 }
@@ -392,14 +323,15 @@
392 323 * that saving a post (or term) will synchronize them.
393 324 *
394 325 * @since 2.3
395 326 *
396 - * @param int $object_id Id of the object being saved.
397 - * @param object $obj Not used.
398 - * @param int[] $translations The list of translations object ids.
399 - * @return void
327 + * @param int $object_id Id of the object being asaved
328 + * @param object $obj Not used
329 + * @param array $translations The list of translations object ids
400 330 */
401 331 public function save_object( $object_id, $obj, $translations ) {
332 + $src_lang = array_search( $object_id, $translations );
333 +
402 334 foreach ( $translations as $tr_lang => $tr_id ) {
403 335 if ( $tr_id != $object_id ) {
404 336 $this->copy( $object_id, $tr_id, $tr_lang, true );
405 337 }