PluginProbe
Polylang / 3.1
Polylang v3.1
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 +58 -31 2.83.1 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 *
@@ -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
@@ -197,8 +218,9 @@
197 218 *
198 219 * @since 0.1
199 220 *
200 221 * @param int $post_id
222 + * @return void
201 223 */
202 224 public function delete_post( $post_id ) {
203 225 if ( ! wp_is_post_revision( $post_id ) ) {
204 226 $this->model->post->delete_translation( $post_id );
@@ -205,10 +227,9 @@
205 227 }
206 228 }
207 229
208 230 /**
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
231 + * Prevents WP deleting files when there are still media using them.
211 232 *
212 233 * @since 0.9
213 234 *
214 235 * @param string $file Path to the file to delete.
@@ -218,21 +239,22 @@
218 239 global $wpdb;
219 240
220 241 $uploadpath = wp_upload_dir();
221 242
243 + // Get the main attached file.
244 + $attached_file = substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) );
245 + $attached_file = preg_replace( '#-\d+x\d+\.([a-z]+)$#', '.$1', $attached_file );
246 +
222 247 $ids = $wpdb->get_col(
223 248 $wpdb->prepare(
224 249 "SELECT post_id FROM $wpdb->postmeta
225 250 WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
226 - substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) )
251 + $attached_file
227 252 )
228 253 );
229 254
230 255 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.
256 + return ''; // Prevent deleting the file.
235 257 }
236 258
237 259 return $file;
238 260 }
@@ -247,29 +269,34 @@
247 269 * @return int Attachment id of the translated media.
248 270 */
249 271 public function create_media_translation( $post_id, $lang ) {
250 272 if ( empty( $post_id ) ) {
251 - return $post_id;
273 + return 0;
252 274 }
253 275
254 - $post = get_post( $post_id );
276 + $post = get_post( $post_id, ARRAY_A );
255 277
256 278 if ( empty( $post ) ) {
257 - return $post;
279 + return 0;
258 280 }
259 281
260 282 $lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug.
261 283
284 + if ( empty( $lang ) ) {
285 + return 0;
286 + }
287 +
262 288 // Create a new attachment ( translate attachment parent if exists ).
263 289 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 ) );
290 + unset( $post['ID'] ); // Will force the creation.
291 + $post['post_parent'] = ( $post['post_parent'] && $tr_parent = $this->model->post->get_translation( $post['post_parent'], $lang->slug ) ) ? $tr_parent : 0;
292 + $post['tax_input'] = array( 'language' => array( $lang->slug ) ); // Assigns the language.
293 + $tr_id = wp_insert_attachment( wp_slash( $post ) );
268 294 remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
269 295
270 296 // Copy metadata.
271 - if ( $data = wp_get_attachment_metadata( $post_id, true ) ) { // Unfiltered.
297 + $data = wp_get_attachment_metadata( $post_id, true ); // Unfiltered.
298 + if ( is_array( $data ) ) {
272 299 wp_update_attachment_metadata( $tr_id, wp_slash( $data ) ); // Directly uses update_post_meta, so expects slashed.
273 300 }
274 301
275 302 // Copy attached file.