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

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

230 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 $orig_lang = array_search( $postarr['ID'], $tr_ids );
87 foreach ( $tr_ids as $tr_id ) {
88 if ( $tr_id !== $postarr['ID'] && $post = get_post( $tr_id ) ) {
89 $post_parent = $post->post_parent;
90 break;
91 }
92 }
93 }
94 return $post_parent;
95 }
96
97 /**
98 * Prevents synchronized post data modification if the current user hasn't enough rights
99 *
100 * @since 2.6
101 *
102 * @param array $data An array of slashed post data.
103 * @param array $postarr An array of sanitized, but otherwise unmodified post data.
104 * @return array
105 */
106 public function can_sync_post_data( $data, $postarr ) {
107 if ( ! empty( $postarr['ID'] ) && ! $this->model->post->current_user_can_synchronize( $postarr['ID'] ) ) {
108 foreach ( $this->model->post->get_translations( $postarr['ID'] ) as $tr_id ) {
109 if ( $tr_id !== $postarr['ID'] && $post = get_post( $tr_id ) ) {
110 $to_sync = $this->get_fields_to_sync( $post );
111 $data = array_merge( $data, $to_sync );
112 break;
113 }
114 }
115 }
116 return $data;
117 }
118
119 /**
120 * Synchronizes post fields in translations
121 *
122 * @since 2.4
123 *
124 * @param int $post_id post id
125 * @param object $post post object
126 * @param array $translations post translations
127 */
128 public function pll_save_post( $post_id, $post, $translations ) {
129 global $wpdb;
130
131 if ( $this->model->post->current_user_can_synchronize( $post_id ) ) {
132 $postarr = $this->get_fields_to_sync( $post );
133
134 if ( ! empty( $postarr ) ) {
135 foreach ( $translations as $lang => $tr_id ) {
136 if ( ! $tr_id || $tr_id === $post_id ) {
137 continue;
138 }
139
140 $tr_arr = $postarr;
141 unset( $tr_arr['post_parent'] );
142
143 // Do not udpate the translation parent if the user set a parent with no translation
144 if ( isset( $postarr['post_parent'] ) ) {
145 $post_parent = $postarr['post_parent'] ? $this->model->post->get_translation( $postarr['post_parent'], $lang ) : 0;
146 if ( ! ( $postarr['post_parent'] && ! $post_parent ) ) {
147 $tr_arr['post_parent'] = $post_parent;
148 }
149 }
150
151 // Update all the row at once
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 * Synchronize term parent in translations
162 * Calling clean_term_cache *after* this is mandatory otherwise the $taxonomy_children option is not correctly updated
163 *
164 * @since 2.3
165 *
166 * @param int $term_id Term id.
167 * @param int $tt_id Term taxonomy id, not used.
168 * @param string $taxonomy Taxonomy name.
169 */
170 public function sync_term_parent( $term_id, $tt_id, $taxonomy ) {
171 global $wpdb;
172
173 if ( is_taxonomy_hierarchical( $taxonomy ) && $this->model->is_translated_taxonomy( $taxonomy ) ) {
174 $term = get_term( $term_id );
175 $translations = $this->model->term->get_translations( $term_id );
176
177 foreach ( $translations as $lang => $tr_id ) {
178 if ( ! empty( $tr_id ) && $tr_id !== $term_id ) {
179 $tr_parent = $this->model->term->get_translation( $term->parent, $lang );
180 $wpdb->update(
181 $wpdb->term_taxonomy,
182 array( 'parent' => isset( $tr_parent ) ? $tr_parent : 0 ),
183 array( 'term_taxonomy_id' => get_term( (int) $tr_id, $taxonomy )->term_taxonomy_id )
184 );
185
186 clean_term_cache( $tr_id, $taxonomy ); // OK since WP 3.9
187 }
188 }
189 }
190 }
191
192 /**
193 * Synchronizes terms and metas in translations for media
194 *
195 * @since 1.8
196 *
197 * @param int $post_id post id
198 */
199 public function edit_attachment( $post_id ) {
200 $this->pll_save_post( $post_id, get_post( $post_id ), $this->model->post->get_translations( $post_id ) );
201 }
202
203 /**
204 * Synchronize sticky posts
205 *
206 * @since 2.3
207 *
208 * @param array $value New option value
209 * @param array $old_value Old option value
210 * @return array
211 */
212 public function sync_sticky_posts( $value, $old_value ) {
213 if ( in_array( 'sticky_posts', $this->options['sync'] ) ) {
214 // Stick post
215 if ( $sticked = array_diff( $value, $old_value ) ) {
216 $translations = $this->model->post->get_translations( reset( $sticked ) );
217 $value = array_unique( array_merge( $value, array_values( $translations ) ) );
218 }
219
220 // Unstick post
221 if ( $unsticked = array_diff( $old_value, $value ) ) {
222 $translations = $this->model->post->get_translations( reset( $unsticked ) );
223 $value = array_unique( array_diff( $value, array_values( $translations ) ) );
224 }
225 }
226
227 return $value;
228 }
229 }
230