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

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

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