PluginProbe
Polylang / 3.3
Polylang v3.3
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 +72 -48 2.83.3 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|null
22 + */
23 + protected $pref_lang;
24 +
25 + /**
26 + * Current language.
27 + *
28 + * @var PLL_Language|null
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 int[]|string[] $terms An array of object term IDs or slugs.
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
@@ -117,9 +138,9 @@
117 138 if ( ! empty( $lang ) && is_array( $terms ) ) {
118 139 // Convert to term ids if we got tag names
119 140 $strings = array_filter( $terms, 'is_string' );
120 141 if ( ! empty( $strings ) ) {
121 - $_terms = get_terms( $taxonomy, array( 'name' => $strings, 'object_ids' => $object_id, 'fields' => 'ids' ) );
142 + $_terms = get_terms( array( 'taxonomy' => $taxonomy, 'name' => $strings, 'object_ids' => $object_id, 'fields' => 'ids' ) );
122 143 $terms = array_merge( array_diff( $terms, $strings ), $_terms );
123 144 }
124 145
125 146 $term_ids = array_combine( $terms, $terms );
@@ -165,29 +186,24 @@
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 + $parent_post_type = $post_parent > 0 ? get_post_type( $post_parent ) : null;
201 + // Dont break the hierarchy in case the post has no language
202 + if ( ! empty( $lang ) && ! empty( $parent_post_type ) && $this->model->is_translated_post_type( $parent_post_type ) ) {
203 + $post_parent = $this->model->post->get_translation( $post_parent, $lang );
189 204 }
205 +
190 206 return $post_parent;
191 207 }
192 208
193 209 /**
@@ -197,8 +213,9 @@
197 213 *
198 214 * @since 0.1
199 215 *
200 216 * @param int $post_id
217 + * @return void
201 218 */
202 219 public function delete_post( $post_id ) {
203 220 if ( ! wp_is_post_revision( $post_id ) ) {
204 221 $this->model->post->delete_translation( $post_id );
@@ -205,10 +222,9 @@
205 222 }
206 223 }
207 224
208 225 /**
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
226 + * Prevents WP deleting files when there are still media using them.
211 227 *
212 228 * @since 0.9
213 229 *
214 230 * @param string $file Path to the file to delete.
@@ -218,21 +234,22 @@
218 234 global $wpdb;
219 235
220 236 $uploadpath = wp_upload_dir();
221 237
238 + // Get the main attached file.
239 + $attached_file = substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) );
240 + $attached_file = preg_replace( '#-\d+x\d+\.([a-z]+)$#', '.$1', $attached_file );
241 +
222 242 $ids = $wpdb->get_col(
223 243 $wpdb->prepare(
224 244 "SELECT post_id FROM $wpdb->postmeta
225 245 WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
226 - substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) )
246 + $attached_file
227 247 )
228 248 );
229 249
230 250 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.
251 + return ''; // Prevent deleting the file.
235 252 }
236 253
237 254 return $file;
238 255 }
@@ -247,29 +264,36 @@
247 264 * @return int Attachment id of the translated media.
248 265 */
249 266 public function create_media_translation( $post_id, $lang ) {
250 267 if ( empty( $post_id ) ) {
251 - return $post_id;
268 + return 0;
252 269 }
253 270
254 - $post = get_post( $post_id );
271 + $post = get_post( $post_id, ARRAY_A );
255 272
256 273 if ( empty( $post ) ) {
257 - return $post;
274 + return 0;
258 275 }
259 276
260 277 $lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug.
261 278
279 + if ( empty( $lang ) ) {
280 + return 0;
281 + }
282 +
262 283 // Create a new attachment ( translate attachment parent if exists ).
263 284 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 ) );
285 + unset( $post['ID'] ); // Will force the creation.
286 + if ( ! empty( $post['post_parent'] ) ) {
287 + $post['post_parent'] = (int) $this->model->post->get_translation( $post['post_parent'], $lang->slug );
288 + }
289 + $post['tax_input'] = array( 'language' => array( $lang->slug ) ); // Assigns the language.
290 + $tr_id = wp_insert_attachment( wp_slash( $post ) );
268 291 remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
269 292
270 293 // Copy metadata.
271 - if ( $data = wp_get_attachment_metadata( $post_id, true ) ) { // Unfiltered.
294 + $data = wp_get_attachment_metadata( $post_id, true ); // Unfiltered.
295 + if ( is_array( $data ) ) {
272 296 wp_update_attachment_metadata( $tr_id, wp_slash( $data ) ); // Directly uses update_post_meta, so expects slashed.
273 297 }
274 298
275 299 // Copy attached file.