PluginProbe
Polylang / 2.9
Polylang v2.9
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
polylang / modules / sync / sync.php

sync.php in Polylang 2.9, at modules/sync/sync.php

234 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 /**
7 * Manages copy and synchronization of terms and post metas on front
8 *
9 * @since 2.4
10 */
11 class PLL_Sync {
12 public $taxonomies, $post_metas, $term_meta;
13
14 /**
15 * Constructor
16 *
17 * @since 1.2
18 *
19 * @param object $polylang
20 */
21 public function __construct( &$polylang ) {
22 $this->model = &$polylang->model;
23 $this->options = &$polylang->options;
24
25 $this->taxonomies = new PLL_Sync_Tax( $polylang );
26 $this->post_metas = new PLL_Sync_Post_Metas( $polylang );
27 $this->term_metas = new PLL_Sync_Term_Metas( $polylang );
28
29 add_filter( 'wp_insert_post_parent', array( $this, 'can_sync_post_parent' ), 10, 3 );
30 add_filter( 'wp_insert_post_data', array( $this, 'can_sync_post_data' ), 10, 2 );
31
32 add_action( 'pll_save_post', array( $this, 'pll_save_post' ), 10, 3 );
33 add_action( 'created_term', array( $this, 'sync_term_parent' ), 10, 3 );
34 add_action( 'edited_term', array( $this, 'sync_term_parent' ), 10, 3 );
35
36 add_action( 'pll_duplicate_term', array( $this->term_metas, 'copy' ), 10, 3 );
37
38 if ( $this->options['media_support'] ) {
39 add_action( 'pll_translate_media', array( $this->taxonomies, 'copy' ), 10, 3 );
40 add_action( 'pll_translate_media', array( $this->post_metas, 'copy' ), 10, 3 );
41 add_action( 'edit_attachment', array( $this, 'edit_attachment' ) );
42 }
43
44 add_filter( 'pre_update_option_sticky_posts', array( $this, 'sync_sticky_posts' ), 10, 2 );
45 }
46
47 /**
48 * Get post fields to synchornize
49 *
50 * @since 2.4
51 *
52 * @param object $post Post object
53 * @return array
54 */
55 protected function get_fields_to_sync( $post ) {
56 $postarr = array();
57
58 foreach ( array( 'comment_status', 'ping_status', 'menu_order' ) as $property ) {
59 if ( in_array( $property, $this->options['sync'] ) ) {
60 $postarr[ $property ] = $post->$property;
61 }
62 }
63
64 if ( in_array( 'post_date', $this->options['sync'] ) ) {
65 $postarr['post_date'] = $post->post_date;
66 $postarr['post_date_gmt'] = $post->post_date_gmt;
67 }
68
69 if ( in_array( 'post_parent', $this->options['sync'] ) ) {
70 $postarr['post_parent'] = wp_get_post_parent_id( $post->ID );
71 }
72
73 return $postarr;
74 }
75
76 /**
77 * Prevents synchronized post parent modification if the current user hasn't enough rights
78 *
79 * @since 2.6
80 *
81 * @param int $post_parent Post parent ID
82 * @param int $post_id Post ID, unused
83 * @param array $postarr Array of parsed post data
84 * @return int
85 */
86 public function can_sync_post_parent( $post_parent, $post_id, $postarr ) {
87 if ( ! empty( $postarr['ID'] ) && ! $this->model->post->current_user_can_synchronize( $postarr['ID'] ) ) {
88 $tr_ids = $this->model->post->get_translations( $postarr['ID'] );
89 foreach ( $tr_ids as $tr_id ) {
90 if ( $tr_id !== $postarr['ID'] && $post = get_post( $tr_id ) ) {
91 $post_parent = $post->post_parent;
92 break;
93 }
94 }
95 }
96 return $post_parent;
97 }
98
99 /**
100 * Prevents synchronized post data modification if the current user hasn't enough rights
101 *
102 * @since 2.6
103 *
104 * @param array $data An array of slashed post data.
105 * @param array $postarr An array of sanitized, but otherwise unmodified post data.
106 * @return array
107 */
108 public function can_sync_post_data( $data, $postarr ) {
109 if ( ! empty( $postarr['ID'] ) && ! $this->model->post->current_user_can_synchronize( $postarr['ID'] ) ) {
110 foreach ( $this->model->post->get_translations( $postarr['ID'] ) as $tr_id ) {
111 if ( $tr_id !== $postarr['ID'] && $post = get_post( $tr_id ) ) {
112 $to_sync = $this->get_fields_to_sync( $post );
113 $data = array_merge( $data, $to_sync );
114 break;
115 }
116 }
117 }
118 return $data;
119 }
120
121 /**
122 * Synchronizes post fields in translations
123 *
124 * @since 2.4
125 *
126 * @param int $post_id post id
127 * @param object $post post object
128 * @param array $translations post translations
129 */
130 public function pll_save_post( $post_id, $post, $translations ) {
131 global $wpdb;
132
133 if ( $this->model->post->current_user_can_synchronize( $post_id ) ) {
134 $postarr = $this->get_fields_to_sync( $post );
135
136 if ( ! empty( $postarr ) ) {
137 foreach ( $translations as $lang => $tr_id ) {
138 if ( ! $tr_id || $tr_id === $post_id ) {
139 continue;
140 }
141
142 $tr_arr = $postarr;
143 unset( $tr_arr['post_parent'] );
144
145 // Do not udpate the translation parent if the user set a parent with no translation.
146 if ( isset( $postarr['post_parent'] ) ) {
147 $post_parent = $postarr['post_parent'] ? $this->model->post->get_translation( $postarr['post_parent'], $lang ) : 0;
148 if ( ! ( $postarr['post_parent'] && ! $post_parent ) ) {
149 $tr_arr['post_parent'] = $post_parent;
150 }
151 }
152
153 // Update all the rows at once.
154 if ( ! empty( $tr_arr ) ) {
155 // Don't use wp_update_post to avoid infinite loop.
156 $wpdb->update( $wpdb->posts, $tr_arr, array( 'ID' => $tr_id ) );
157 clean_post_cache( $tr_id );
158 }
159 }
160 }
161 }
162 }
163
164 /**
165 * Synchronize term parent in translations
166 * Calling clean_term_cache *after* this is mandatory otherwise the $taxonomy_children option is not correctly updated
167 *
168 * @since 2.3
169 *
170 * @param int $term_id Term id.
171 * @param int $tt_id Term taxonomy id, not used.
172 * @param string $taxonomy Taxonomy name.
173 */
174 public function sync_term_parent( $term_id, $tt_id, $taxonomy ) {
175 global $wpdb;
176
177 if ( is_taxonomy_hierarchical( $taxonomy ) && $this->model->is_translated_taxonomy( $taxonomy ) ) {
178 $term = get_term( $term_id );
179 $translations = $this->model->term->get_translations( $term_id );
180
181 foreach ( $translations as $lang => $tr_id ) {
182 if ( ! empty( $tr_id ) && $tr_id !== $term_id ) {
183 $tr_parent = $this->model->term->get_translation( $term->parent, $lang );
184 $wpdb->update(
185 $wpdb->term_taxonomy,
186 array( 'parent' => isset( $tr_parent ) ? $tr_parent : 0 ),
187 array( 'term_taxonomy_id' => get_term( (int) $tr_id, $taxonomy )->term_taxonomy_id )
188 );
189
190 clean_term_cache( $tr_id, $taxonomy ); // OK since WP 3.9
191 }
192 }
193 }
194 }
195
196 /**
197 * Synchronizes terms and metas in translations for media
198 *
199 * @since 1.8
200 *
201 * @param int $post_id post id
202 */
203 public function edit_attachment( $post_id ) {
204 $this->pll_save_post( $post_id, get_post( $post_id ), $this->model->post->get_translations( $post_id ) );
205 }
206
207 /**
208 * Synchronize sticky posts
209 *
210 * @since 2.3
211 *
212 * @param array $value New option value
213 * @param array $old_value Old option value
214 * @return array
215 */
216 public function sync_sticky_posts( $value, $old_value ) {
217 if ( in_array( 'sticky_posts', $this->options['sync'] ) ) {
218 // Stick post
219 if ( $sticked = array_diff( $value, $old_value ) ) {
220 $translations = $this->model->post->get_translations( reset( $sticked ) );
221 $value = array_unique( array_merge( $value, array_values( $translations ) ) );
222 }
223
224 // Unstick post
225 if ( $unsticked = array_diff( $old_value, $value ) ) {
226 $translations = $this->model->post->get_translations( reset( $unsticked ) );
227 $value = array_unique( array_diff( $value, array_values( $translations ) ) );
228 }
229 }
230
231 return $value;
232 }
233 }
234