PluginProbe
Polylang / 3.7.7
Polylang v3.7.7
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 +86 -51 2.93.7.7 View file →
@@ -8,17 +8,40 @@
8 8 *
9 9 * @since 2.3
10 10 */
11 11 abstract class PLL_Sync_Metas {
12 + /**
13 + * @var PLL_Model
14 + */
12 15 public $model;
13 - protected $meta_type, $prev_value, $to_copy;
14 16
15 17 /**
16 - * Constructor
18 + * Meta type. Typically 'post' or 'term'.
17 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 = array();
30 +
31 + /**
32 + * Stores the metas to synchronize before deleting them.
33 + *
34 + * @var array
35 + */
36 + protected $to_copy = array();
37 +
38 + /**
39 + * Constructor.
40 + *
18 41 * @since 2.3
19 42 *
20 - * @param object $polylang
43 + * @param object $polylang The Polylang object.
21 44 */
22 45 public function __construct( &$polylang ) {
23 46 $this->model = &$polylang->model;
24 47
@@ -34,11 +57,13 @@
34 57 /**
35 58 * Removes "added_{$this->meta_type}_meta" action
36 59 *
37 60 * @since 2.3
61 + *
62 + * @return void
38 63 */
39 64 protected function remove_add_meta_action() {
40 - remove_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
65 + remove_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ) );
41 66 }
42 67
43 68 /**
44 69 * Removes all meta synchronization actions and filters
@@ -43,17 +68,19 @@
43 68 /**
44 69 * Removes all meta synchronization actions and filters
45 70 *
46 71 * @since 2.3
72 + *
73 + * @return void
47 74 */
48 - protected function remove_all_meta_actions() {
75 + public function remove_all_meta_actions() {
49 76 $this->remove_add_meta_action();
50 77
51 - remove_filter( "update_{$this->meta_type}_metadata", array( $this, 'update_metadata' ), 999, 5 );
52 - remove_action( "update_{$this->meta_type}_meta", array( $this, 'update_meta' ), 10, 4 );
78 + remove_filter( "update_{$this->meta_type}_metadata", array( $this, 'update_metadata' ), 999 );
79 + remove_action( "update_{$this->meta_type}_meta", array( $this, 'update_meta' ) );
53 80
54 - remove_action( "delete_{$this->meta_type}_meta", array( $this, 'store_metas_to_sync' ), 10, 2 );
55 - remove_action( "deleted_{$this->meta_type}_meta", array( $this, 'delete_meta' ), 10, 4 );
81 + remove_action( "delete_{$this->meta_type}_meta", array( $this, 'store_metas_to_sync' ) );
82 + remove_action( "deleted_{$this->meta_type}_meta", array( $this, 'delete_meta' ) );
56 83 }
57 84
58 85 /**
59 86 * Adds "added_{$this->meta_type}_meta" action
@@ -58,8 +85,10 @@
58 85 /**
59 86 * Adds "added_{$this->meta_type}_meta" action
60 87 *
61 88 * @since 2.3
89 + *
90 + * @return void
62 91 */
63 92 protected function restore_add_meta_action() {
64 93 add_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
65 94 }
@@ -67,10 +96,12 @@
67 96 /**
68 97 * Adds meta synchronization actions and filters
69 98 *
70 99 * @since 2.3
100 + *
101 + * @return void
71 102 */
72 - protected function add_all_meta_actions() {
103 + public function add_all_meta_actions() {
73 104 $this->restore_add_meta_action();
74 105
75 106 add_filter( "update_{$this->meta_type}_metadata", array( $this, 'update_metadata' ), 999, 5 ); // Very late in case a filter prevents the meta to be updated
76 107 add_action( "update_{$this->meta_type}_meta", array( $this, 'update_meta' ), 10, 4 );
@@ -102,34 +133,34 @@
102 133 * @param string $lang Language of target
103 134 * @param int $from Id of the source
104 135 * @param int $to Id of the target
105 136 */
106 - return apply_filters( "pll_translate_{$this->meta_type}_meta", maybe_unserialize( $value ), $key, $lang, $from, $to );
137 + return apply_filters( "pll_translate_{$this->meta_type}_meta", $value, $key, $lang, $from, $to );
107 138 }
108 139
109 140 /**
110 - * Get the custom fields to copy or synchronize
141 + * Get the custom fields to copy or synchronize.
111 142 *
112 143 * @since 2.3
113 144 *
114 - * @param int $from Id of the post from which we copy informations
115 - * @param int $to Id of the post to which we paste informations
116 - * @param string $lang Language slug
117 - * @param bool $sync True if it is synchronization, false if it is a copy
118 - * @return array List of meta keys
145 + * @param int $from Id of the post from which we copy information.
146 + * @param int $to Id of the post to which we paste information.
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.
119 150 */
120 151 protected function get_metas_to_copy( $from, $to, $lang, $sync = false ) {
121 152 /**
122 - * Filter the custom fields to copy or synchronize
153 + * Filters the custom fields to copy or synchronize.
123 154 *
124 155 * @since 0.6
125 156 * @since 1.9.2 The `$from`, `$to`, `$lang` parameters were added.
126 157 *
127 - * @param array $keys List of custom fields names
128 - * @param bool $sync True if it is synchronization, false if it is a copy
129 - * @param int $from Id of the post from which we copy informations
130 - * @param int $to Id of the post to which we paste informations
131 - * @param string $lang Language slug
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 information.
161 + * @param int $to Id of the post to which we paste information.
162 + * @param string $lang Language slug.
132 163 */
133 164 return array_unique( apply_filters( "pll_copy_{$this->meta_type}_metas", array(), $sync, $from, $to, $lang ) );
134 165 }
135 166
@@ -167,8 +198,9 @@
167 198 * @param int $mid Meta id.
168 199 * @param int $id Object ID.
169 200 * @param string $meta_key Meta key.
170 201 * @param mixed $meta_value Meta value. Must be serializable if non-scalar.
202 + * @return void
171 203 */
172 204 public function add_meta( $mid, $id, $meta_key, $meta_value ) {
173 205 static $avoid_recursion = false;
174 206
@@ -218,11 +250,13 @@
218 250 * @param int $mid Meta id.
219 251 * @param int $id Object ID.
220 252 * @param string $meta_key Meta key.
221 253 * @param mixed $meta_value Meta value. Must be serializable if non-scalar.
254 + * @return void
222 255 */
223 256 public function update_meta( $mid, $id, $meta_key, $meta_value ) {
224 257 static $avoid_recursion = false;
258 + $id = (int) $id;
225 259
226 260 if ( ! $avoid_recursion ) {
227 261 $avoid_recursion = true;
228 262 $hash = md5( "$id|$meta_key|" . maybe_serialize( $meta_value ) );
@@ -250,14 +284,15 @@
250 284 }
251 285 }
252 286
253 287 /**
254 - * Store metas to synchronize before deleting them
288 + * Store metas to synchronize before deleting them.
255 289 *
256 290 * @since 2.3
257 291 *
258 - * @param array $mids Not used
292 + * @param int[] $mids Not used.
259 293 * @param int $id Object ID.
294 + * @return void
260 295 */
261 296 public function store_metas_to_sync( $mids, $id ) {
262 297 $tr_ids = $this->model->{$this->meta_type}->get_translations( $id );
263 298
@@ -266,16 +301,17 @@
266 301 }
267 302 }
268 303
269 304 /**
270 - * Synchronize deleted meta across translations
305 + * Synchronizes deleted meta across translations.
271 306 *
272 307 * @since 2.3
273 308 *
274 - * @param array $mids Not used
309 + * @param int[] $mids Not used.
275 310 * @param int $id Object ID.
276 311 * @param string $key Meta key.
277 312 * @param mixed $value Meta value.
313 + * @return void
278 314 */
279 315 public function delete_meta( $mids, $id, $key, $value ) {
280 316 static $avoid_recursion = false;
281 317
@@ -307,18 +343,18 @@
307 343 * @param int $from Id of the source object
308 344 * @param int $to Id of the target object
309 345 * @param string $lang Language code of the target object
310 346 * @param bool $sync Optional, defaults to true. True if it is synchronization, false if it is a copy
347 + * @return void
311 348 */
312 349 public function copy( $from, $to, $lang, $sync = false ) {
313 350 $this->remove_all_meta_actions();
314 351
315 - remove_action( "delete_{$this->meta_type}_meta", array( $this, 'store_metas_to_sync' ), 10, 2 );
316 - remove_action( "deleted_{$this->meta_type}_meta", array( $this, 'delete_meta' ), 10, 4 );
317 -
318 - $to_copy = $this->get_metas_to_copy( $from, $to, $lang, $sync );
319 - $metas = get_metadata( $this->meta_type, $from );
352 + $to_copy = $this->get_metas_to_copy( $from, $to, $lang, $sync );
353 + $metas = get_metadata( $this->meta_type, $from );
354 + $metas = is_array( $metas ) ? $metas : array();
320 355 $tr_metas = get_metadata( $this->meta_type, $to );
356 + $tr_metas = is_array( $tr_metas ) ? $tr_metas : array();
321 357
322 358 foreach ( $to_copy as $key ) {
323 359 if ( empty( $metas[ $key ] ) ) {
324 360 if ( ! empty( $tr_metas[ $key ] ) ) {
@@ -324,27 +360,25 @@
324 360 if ( ! empty( $tr_metas[ $key ] ) ) {
325 361 // If the meta key is not present in the source object, delete all values
326 362 delete_metadata( $this->meta_type, $to, wp_slash( $key ) );
327 363 }
364 + } elseif ( ! empty( $tr_metas[ $key ] ) && 1 === count( $metas[ $key ] ) && 1 === count( $tr_metas[ $key ] ) ) {
365 + // One custom field to update
366 + $value = reset( $metas[ $key ] );
367 + $value = maybe_unserialize( $value );
368 + $to_value = $this->maybe_translate_value( $value, $key, $from, $to, $lang );
369 + update_metadata( $this->meta_type, $to, wp_slash( $key ), is_object( $to_value ) ? $to_value : wp_slash( $to_value ) );
328 370 } else {
329 - if ( ! empty( $tr_metas[ $key ] ) && 1 === count( $metas[ $key ] ) && 1 === count( $tr_metas[ $key ] ) ) {
330 - // One custom field to update
331 - $value = reset( $metas[ $key ] );
371 + // Multiple custom fields, either in the source or the target
372 + if ( ! empty( $tr_metas[ $key ] ) ) {
373 + // The synchronization of multiple values custom fields is easier if we delete all metas first
374 + delete_metadata( $this->meta_type, $to, wp_slash( $key ) );
375 + }
376 +
377 + foreach ( $metas[ $key ] as $value ) {
332 378 $value = maybe_unserialize( $value );
333 379 $to_value = $this->maybe_translate_value( $value, $key, $from, $to, $lang );
334 - update_metadata( $this->meta_type, $to, wp_slash( $key ), is_object( $to_value ) ? $to_value : wp_slash( $to_value ) );
335 - } else {
336 - // Multiple custom fields, either in the source or the target
337 - if ( ! empty( $tr_metas[ $key ] ) ) {
338 - // The synchronization of multiple values custom fields is easier if we delete all metas first
339 - delete_metadata( $this->meta_type, $to, wp_slash( $key ) );
340 - }
341 -
342 - foreach ( $metas[ $key ] as $value ) {
343 - $value = maybe_unserialize( $value );
344 - $to_value = $this->maybe_translate_value( $value, $key, $from, $to, $lang );
345 - add_metadata( $this->meta_type, $to, wp_slash( $key ), is_object( $to_value ) ? $to_value : wp_slash( $to_value ) );
346 - }
380 + add_metadata( $this->meta_type, $to, wp_slash( $key ), is_object( $to_value ) ? $to_value : wp_slash( $to_value ) );
347 381 }
348 382 }
349 383 }
350 384
@@ -356,11 +390,12 @@
356 390 * that saving a post (or term) will synchronize them.
357 391 *
358 392 * @since 2.3
359 393 *
360 - * @param int $object_id Id of the object being asaved
361 - * @param object $obj Not used
362 - * @param array $translations The list of translations object ids
394 + * @param int $object_id Id of the object being saved.
395 + * @param object $obj Not used.
396 + * @param int[] $translations The list of translations object ids.
397 + * @return void
363 398 */
364 399 public function save_object( $object_id, $obj, $translations ) {
365 400 foreach ( $translations as $tr_lang => $tr_id ) {
366 401 if ( $tr_id != $object_id ) {