PluginProbe
Polylang / 3.6
Polylang v3.6
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 / admin-sync.php

admin-sync.php in Polylang 3.6, at modules/sync/admin-sync.php

234 lines 7.7 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
8 *
9 * @since 1.2
10 */
11 class PLL_Admin_Sync extends PLL_Sync {
12
13 /**
14 * Constructor
15 *
16 * @since 1.2
17 *
18 * @param object $polylang The Polylang object.
19 */
20 public function __construct( &$polylang ) {
21 parent::__construct( $polylang );
22
23 add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 3 );
24 add_filter( 'wp_insert_post_data', array( $this, 'wp_insert_post_data' ) );
25 add_filter( 'use_block_editor_for_post', array( $this, 'new_post_translation' ), 5000 ); // After content duplication.
26 }
27
28 /**
29 * Translate post parent if exists when using "Add new" ( translation )
30 *
31 * @since 0.6
32 *
33 * @param int $post_parent Post parent ID
34 * @param int $post_id Post ID, unused
35 * @param array $postarr Array of parsed post data
36 * @return int
37 */
38 public function wp_insert_post_parent( $post_parent, $post_id, $postarr ) {
39 if ( isset( $_GET['from_post'], $_GET['new_lang'], $_GET['post_type'] ) ) {
40 check_admin_referer( 'new-post-translation' );
41 // Make sure not to impact media translations created at the same time
42 if ( $_GET['post_type'] === $postarr['post_type'] && ( $id = wp_get_post_parent_id( (int) $_GET['from_post'] ) ) && $parent = $this->model->post->get_translation( $id, sanitize_key( $_GET['new_lang'] ) ) ) {
43 $post_parent = $parent;
44 }
45 }
46 return $post_parent;
47 }
48
49 /**
50 * Copy menu order, comment, ping status and optionally the date when creating a new translation
51 *
52 * @since 2.5
53 *
54 * @param array $data An array of slashed post data.
55 * @return array
56 */
57 public function wp_insert_post_data( $data ) {
58 if ( isset( $GLOBALS['pagenow'], $_GET['from_post'], $_GET['new_lang'] ) && 'post-new.php' === $GLOBALS['pagenow'] && $this->model->is_translated_post_type( $data['post_type'] ) ) {
59 check_admin_referer( 'new-post-translation' );
60
61 $from_post_id = (int) $_GET['from_post'];
62 $from_post = get_post( $from_post_id );
63
64 if ( $from_post instanceof WP_Post ) {
65 foreach ( array( 'menu_order', 'comment_status', 'ping_status' ) as $property ) {
66 $data[ $property ] = $from_post->$property;
67 }
68
69 // Copy the date only if the synchronization is activated
70 if ( in_array( 'post_date', $this->options['sync'] ) ) {
71 $data['post_date'] = $from_post->post_date;
72 $data['post_date_gmt'] = $from_post->post_date_gmt;
73 }
74 }
75 }
76
77 return $data;
78 }
79
80 /**
81 * Copy post metas, and taxonomies when using "Add new" ( translation )
82 *
83 * @since 2.5
84 * @since 3.1 Use of use_block_editor_for_post filter instead of rest_api_init which is triggered too early in WP 5.8.
85 *
86 * @param bool $is_block_editor Whether the post can be edited or not.
87 * @return bool
88 */
89 public function new_post_translation( $is_block_editor ) {
90 global $post;
91 static $done = array();
92
93 if ( ! empty( $post ) && isset( $GLOBALS['pagenow'], $_GET['from_post'], $_GET['new_lang'] ) && 'post-new.php' === $GLOBALS['pagenow'] && $this->model->is_translated_post_type( $post->post_type ) ) {
94 check_admin_referer( 'new-post-translation' );
95
96 // Capability check already done in post-new.php
97 $from_post_id = (int) $_GET['from_post'];
98 $lang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) );
99
100 if ( ! $from_post_id || ! $lang || ! empty( $done[ $from_post_id ] ) ) {
101 return $is_block_editor;
102 }
103
104 $done[ $from_post_id ] = true; // Avoid a second duplication in the block editor. Using an array only to allow multiple phpunit tests.
105
106 $this->taxonomies->copy( $from_post_id, $post->ID, $lang->slug );
107 $this->post_metas->copy( $from_post_id, $post->ID, $lang->slug );
108
109 if ( is_sticky( $from_post_id ) ) {
110 stick_post( $post->ID );
111 }
112 }
113
114 return $is_block_editor;
115 }
116
117 /**
118 * Get post fields to synchronize.
119 *
120 * @since 2.4
121 *
122 * @param WP_Post $post Post object.
123 * @return array Fields to synchronize.
124 */
125 protected function get_fields_to_sync( $post ) {
126 global $wpdb;
127
128 $postarr = parent::get_fields_to_sync( $post );
129
130 // For new drafts, save the date now otherwise it is overridden by WP. Thanks to JoryHogeveen. See #32.
131 if ( in_array( 'post_date', $this->options['sync'] ) && isset( $GLOBALS['pagenow'], $_GET['from_post'], $_GET['new_lang'] ) && 'post-new.php' === $GLOBALS['pagenow'] ) {
132 check_admin_referer( 'new-post-translation' );
133
134 unset( $postarr['post_date'] );
135 unset( $postarr['post_date_gmt'] );
136
137 $original = get_post( (int) $_GET['from_post'] );
138
139 if ( $original instanceof WP_Post ) {
140 $wpdb->update(
141 $wpdb->posts,
142 array(
143 'post_date' => $original->post_date,
144 'post_date_gmt' => $original->post_date_gmt,
145 ),
146 array( 'ID' => $post->ID )
147 );
148 }
149 }
150
151 if ( isset( $GLOBALS['post_type'] ) ) {
152 $post_type = $GLOBALS['post_type'];
153 } elseif ( isset( $_REQUEST['post_type'] ) ) {
154 $post_type = sanitize_key( $_REQUEST['post_type'] ); // 2nd case for quick edit
155 }
156
157 // Make sure not to impact media translations when creating them at the same time as post
158 if ( in_array( 'post_parent', $this->options['sync'] ) && ( ! isset( $post_type ) || $post_type !== $post->post_type ) ) {
159 unset( $postarr['post_parent'] );
160 }
161
162 return $postarr;
163 }
164
165 /**
166 * Synchronizes post fields in translations.
167 *
168 * @since 1.2
169 *
170 * @param int $post_id Post id.
171 * @param WP_Post $post Post object.
172 * @param int[] $translations Post translations.
173 */
174 public function pll_save_post( $post_id, $post, $translations ) {
175 parent::pll_save_post( $post_id, $post, $translations );
176
177 // Sticky posts
178 if ( in_array( 'sticky_posts', $this->options['sync'] ) ) {
179 $stickies = get_option( 'sticky_posts' );
180 if ( isset( $_REQUEST['sticky'] ) && 'sticky' === $_REQUEST['sticky'] ) { // phpcs:ignore WordPress.Security.NonceVerification
181 $stickies = array_merge( $stickies, array_values( $translations ) );
182 } else {
183 $stickies = array_diff( $stickies, array_values( $translations ) );
184 }
185 update_option( 'sticky_posts', array_unique( $stickies ) );
186 }
187 }
188
189 /**
190 * Some backward compatibility with Polylang < 2.3
191 * allows to call PLL()->sync->copy_post_metas() and PLL()->sync->copy_taxonomies()
192 * used for example in Polylang for WooCommerce
193 * the compatibility is however only partial as the 4th argument $sync is lost
194 *
195 * @since 2.3
196 *
197 * @param string $func Function name
198 * @param array $args Function arguments
199 * @return mixed|void
200 */
201 public function __call( $func, $args ) {
202 $obj = substr( $func, 5 );
203
204 if ( is_object( $this->$obj ) && method_exists( $this->$obj, 'copy' ) ) {
205 if ( WP_DEBUG ) {
206 $debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
207 $i = 1 + empty( $debug[1]['line'] ); // The file and line are in $debug[2] if the function was called using call_user_func
208
209 trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
210 sprintf(
211 '%1$s was called incorrectly in %3$s on line %4$s: the call to PLL()->sync->%1$s() has been deprecated in Polylang 2.3, use PLL()->sync->%2$s->copy() instead.' . "\nError handler",
212 esc_html( $func ),
213 esc_html( $obj ),
214 esc_html( $debug[ $i ]['file'] ),
215 absint( $debug[ $i ]['line'] )
216 )
217 );
218 }
219 return call_user_func_array( array( $this->$obj, 'copy' ), $args );
220 }
221
222 $debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
223 trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
224 sprintf(
225 'Call to undefined function PLL()->sync->%1$s() in %2$s on line %3$s' . "\nError handler",
226 esc_html( $func ),
227 esc_html( $debug[0]['file'] ),
228 absint( $debug[0]['line'] )
229 ),
230 E_USER_ERROR
231 );
232 }
233 }
234