PluginProbe
Polylang / 3.1.4
Polylang v3.1.4
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 | include/crud-posts.php +67 -47 2.83.1.4 View file →
@@ -3,16 +3,34 @@
3 3 * @package Polylang
4 4 */
5 5
6 6 /**
7 - * Adds actions and filters related to languages when creating, updating or deleting posts
8 - * Actions a filters used when reaing posts are handled separately
7 + * Adds actions and filters related to languages when creating, updating or deleting posts.
8 + * Actions and filters triggered when reading posts are handled separately.
9 9 *
10 10 * @since 2.4
11 11 */
12 12 class PLL_CRUD_Posts {
13 + /**
14 + * @var PLL_Model
15 + */
16 + protected $model;
13 17
14 18 /**
19 + * Preferred language to assign to a new post.
20 + *
21 + * @var PLL_Language
22 + */
23 + protected $pref_lang;
24 +
25 + /**
26 + * Current language.
27 + *
28 + * @var PLL_Language
29 + */
30 + protected $curlang;
31 +
32 + /**
15 33 * Constructor
16 34 *
17 35 * @since 2.4
18 36 *
@@ -24,9 +42,9 @@
24 42 $this->curlang = &$polylang->curlang;
25 43
26 44 add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
27 45 add_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 4 );
28 - add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 4 );
46 + add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 2 );
29 47 add_action( 'before_delete_post', array( $this, 'delete_post' ) );
30 48
31 49 // Specific for media
32 50 if ( $polylang->options['media_support'] ) {
@@ -41,8 +59,9 @@
41 59 *
42 60 * @since 1.5
43 61 *
44 62 * @param int $post_id
63 + * @return void
45 64 */
46 65 public function set_default_language( $post_id ) {
47 66 if ( ! $this->model->post->get_language( $post_id ) ) {
48 67 if ( ! empty( $_GET['new_lang'] ) && $lang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
@@ -63,18 +82,19 @@
63 82 }
64 83 }
65 84
66 85 /**
67 - * Called when a post ( or page ) is saved, published or updated
86 + * Called when a post ( or page ) is saved, published or updated.
68 87 *
69 88 * @since 0.1
70 - * @since 2.3 Does not save the language and translations anymore, unless the post has no language yet
89 + * @since 2.3 Does not save the language and translations anymore, unless the post has no language yet.
71 90 *
72 - * @param int $post_id
73 - * @param object $post
91 + * @param int $post_id Post id of the post being saved.
92 + * @param WP_Post $post The post being saved.
93 + * @return void
74 94 */
75 95 public function save_post( $post_id, $post ) {
76 - // Does nothing except on post types which are filterable
96 + // Does nothing except on post types which are filterable.
77 97 if ( $this->model->is_translated_post_type( $post->post_type ) ) {
78 98 if ( $id = wp_is_post_revision( $post_id ) ) {
79 99 $post_id = $id;
80 100 }
@@ -85,15 +105,15 @@
85 105 $this->set_default_language( $post_id );
86 106 }
87 107
88 108 /**
89 - * Fires after the post language and translations are saved
109 + * Fires after the post language and translations are saved.
90 110 *
91 111 * @since 1.2
92 112 *
93 - * @param int $post_id Post id
94 - * @param object $post Post object
95 - * @param array $translations The list of translations post ids
113 + * @param int $post_id Post id.
114 + * @param WP_Post $post Post object.
115 + * @param int[] $translations The list of translations post ids.
96 116 */
97 117 do_action( 'pll_save_post', $post_id, $post, $this->model->post->get_translations( $post_id ) );
98 118 }
99 119 }
@@ -98,16 +118,17 @@
98 118 }
99 119 }
100 120
101 121 /**
102 - * Make sure saved terms are in the right language (especially tags with same name in different languages)
122 + * Makes sure that saved terms are in the right language (especially tags with same name in different languages).
103 123 *
104 124 * @since 2.3
105 125 *
106 - * @param int $object_id Object ID.
107 - * @param array $terms An array of object terms.
108 - * @param array $tt_ids An array of term taxonomy IDs.
109 - * @param string $taxonomy Taxonomy slug.
126 + * @param int $object_id Object ID.
127 + * @param WP_Term[] $terms An array of object terms.
128 + * @param int[] $tt_ids An array of term taxonomy IDs.
129 + * @param string $taxonomy Taxonomy slug.
130 + * @return void
110 131 */
111 132 public function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy ) {
112 133 static $avoid_recursion;
113 134
@@ -165,28 +186,21 @@
165 186 }
166 187 }
167 188
168 189 /**
169 - * Make sure that the post parent is in the correct language when using bulk edit
190 + * Make sure that the post parent is in the correct language.
170 191 *
171 192 * @since 1.8
172 193 *
173 - * @param int $post_parent Post parent ID.
174 - * @param int $post_id Post ID.
175 - * @param array $new_postarr Array of parsed post data.
176 - * @param array $postarr Array of sanitized, but otherwise unmodified post data.
194 + * @param int $post_parent Post parent ID.
195 + * @param int $post_id Post ID.
177 196 * @return int
178 197 */
179 - public function wp_insert_post_parent( $post_parent, $post_id, $new_postarr, $postarr ) {
180 - if ( isset( $postarr['bulk_edit'], $postarr['inline_lang_choice'] ) ) {
181 - check_admin_referer( 'bulk-posts' );
182 - $lang = -1 == $postarr['inline_lang_choice'] ?
183 - $this->model->post->get_language( $post_id ) :
184 - $this->model->get_language( $postarr['inline_lang_choice'] );
185 - // Dont break the hierarchy in case the post has no language
186 - if ( ! empty( $lang ) ) {
187 - $post_parent = $this->model->post->get_translation( $post_parent, $lang );
188 - }
198 + public function wp_insert_post_parent( $post_parent, $post_id ) {
199 + $lang = $this->model->post->get_language( $post_id );
200 + // Dont break the hierarchy in case the post has no language
201 + if ( ! empty( $lang ) ) {
202 + $post_parent = $this->model->post->get_translation( $post_parent, $lang );
189 203 }
190 204 return $post_parent;
191 205 }
192 206
@@ -197,8 +211,9 @@
197 211 *
198 212 * @since 0.1
199 213 *
200 214 * @param int $post_id
215 + * @return void
201 216 */
202 217 public function delete_post( $post_id ) {
203 218 if ( ! wp_is_post_revision( $post_id ) ) {
204 219 $this->model->post->delete_translation( $post_id );
@@ -205,10 +220,9 @@
205 220 }
206 221 }
207 222
208 223 /**
209 - * Prevents WP deleting files when there are still media using them
210 - * Thanks to Bruno "Aesqe" Babic and its plugin file gallery in which I took all the ideas for this function
224 + * Prevents WP deleting files when there are still media using them.
211 225 *
212 226 * @since 0.9
213 227 *
214 228 * @param string $file Path to the file to delete.
@@ -218,21 +232,22 @@
218 232 global $wpdb;
219 233
220 234 $uploadpath = wp_upload_dir();
221 235
236 + // Get the main attached file.
237 + $attached_file = substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) );
238 + $attached_file = preg_replace( '#-\d+x\d+\.([a-z]+)$#', '.$1', $attached_file );
239 +
222 240 $ids = $wpdb->get_col(
223 241 $wpdb->prepare(
224 242 "SELECT post_id FROM $wpdb->postmeta
225 243 WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
226 - substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) )
244 + $attached_file
227 245 )
228 246 );
229 247
230 248 if ( ! empty( $ids ) ) {
231 - // Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before ).
232 - require_once ABSPATH . 'wp-admin/includes/image.php'; // In case the file is deleted outside admin.
233 - wp_update_attachment_metadata( $ids[0], wp_slash( wp_generate_attachment_metadata( $ids[0], $file ) ) ); // Directly uses update_post_meta, so expects slashed.
234 - return ''; // Prevent deleting the main file.
249 + return ''; // Prevent deleting the file.
235 250 }
236 251
237 252 return $file;
238 253 }
@@ -247,29 +262,34 @@
247 262 * @return int Attachment id of the translated media.
248 263 */
249 264 public function create_media_translation( $post_id, $lang ) {
250 265 if ( empty( $post_id ) ) {
251 - return $post_id;
266 + return 0;
252 267 }
253 268
254 - $post = get_post( $post_id );
269 + $post = get_post( $post_id, ARRAY_A );
255 270
256 271 if ( empty( $post ) ) {
257 - return $post;
272 + return 0;
258 273 }
259 274
260 275 $lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug.
261 276
277 + if ( empty( $lang ) ) {
278 + return 0;
279 + }
280 +
262 281 // Create a new attachment ( translate attachment parent if exists ).
263 282 add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload.
264 - $post->ID = null; // Will force the creation
265 - $post->post_parent = ( $post->post_parent && $tr_parent = $this->model->post->get_translation( $post->post_parent, $lang->slug ) ) ? $tr_parent : 0;
266 - $post->tax_input = array( 'language' => array( $lang->slug ) ); // Assigns the language.
267 - $tr_id = wp_insert_attachment( wp_slash( (array) $post ) );
283 + unset( $post['ID'] ); // Will force the creation.
284 + $post['post_parent'] = ( $post['post_parent'] && $tr_parent = $this->model->post->get_translation( $post['post_parent'], $lang->slug ) ) ? $tr_parent : 0;
285 + $post['tax_input'] = array( 'language' => array( $lang->slug ) ); // Assigns the language.
286 + $tr_id = wp_insert_attachment( wp_slash( $post ) );
268 287 remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
269 288
270 289 // Copy metadata.
271 - if ( $data = wp_get_attachment_metadata( $post_id, true ) ) { // Unfiltered.
290 + $data = wp_get_attachment_metadata( $post_id, true ); // Unfiltered.
291 + if ( is_array( $data ) ) {
272 292 wp_update_attachment_metadata( $tr_id, wp_slash( $data ) ); // Directly uses update_post_meta, so expects slashed.
273 293 }
274 294
275 295 // Copy attached file.