PluginProbe
Polylang / 2.5
Polylang v2.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
← All changes | admin/admin-classic-editor.php +64 -95 2.7.42.5 View file →
@@ -29,11 +29,8 @@
29 29 add_action( 'wp_ajax_pll_posts_not_translated', array( $this, 'ajax_posts_not_translated' ) );
30 30
31 31 // Filters the pages by language in the parent dropdown list in the page attributes metabox
32 32 add_filter( 'page_attributes_dropdown_pages_args', array( $this, 'page_attributes_dropdown_pages_args' ), 10, 2 );
33 -
34 - // Notice
35 - add_action( 'edit_form_top', array( $this, 'edit_form_top' ) );
36 33 }
37 34
38 35 /**
39 36 * Adds the Language box in the 'Edit Post' and 'Edit Page' panels ( as well as in custom post types panels )
@@ -44,19 +41,9 @@
44 41 * @param object $post Current post
45 42 */
46 43 public function add_meta_boxes( $post_type, $post ) {
47 44 if ( $this->model->is_translated_post_type( $post_type ) ) {
48 - add_meta_box(
49 - 'ml_box',
50 - __( 'Languages', 'polylang' ),
51 - array( $this, 'post_language' ),
52 - $post_type,
53 - 'side',
54 - 'high',
55 - array(
56 - '__back_compat_meta_box' => pll_use_block_editor_plugin(),
57 - )
58 - );
45 + add_meta_box( 'ml_box', __( 'Languages', 'polylang' ), array( $this, 'post_language' ), $post_type, 'side', 'high' );
59 46 }
60 47 }
61 48
62 49 /**
@@ -65,32 +52,17 @@
65 52 * @since 0.1
66 53 */
67 54 public function post_language() {
68 55 global $post_ID;
56 + $post_id = $post_ID;
69 57 $post_type = get_post_type( $post_ID );
70 58
71 - // phpcs:ignore WordPress.Security.NonceVerification, WordPressVIPMinimum.Variables.VariableAnalysis.UnusedVariable
72 - $from_post_id = isset( $_GET['from_post'] ) ? (int) $_GET['from_post'] : 0;
73 -
74 59 $lang = ( $lg = $this->model->post->get_language( $post_ID ) ) ? $lg :
75 - ( isset( $_GET['new_lang'] ) ? $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification
60 + ( isset( $_GET['new_lang'] ) ? $this->model->get_language( $_GET['new_lang'] ) :
76 61 $this->pref_lang );
77 62
78 63 $dropdown = new PLL_Walker_Dropdown();
79 64
80 - $id = ( 'attachment' === $post_type ) ? sprintf( 'attachments[%d][language]', (int) $post_ID ) : 'post_lang_choice';
81 -
82 - $dropdown_html = $dropdown->walk(
83 - $this->model->get_languages_list(),
84 - -1,
85 - array(
86 - 'name' => $id,
87 - 'class' => 'post_lang_choice tags-input',
88 - 'selected' => $lang ? $lang->slug : '',
89 - 'flag' => true,
90 - )
91 - );
92 -
93 65 wp_nonce_field( 'pll_language', '_pll_nonce' );
94 66
95 67 // NOTE: the class "tags-input" allows to include the field in the autosave $_POST ( see autosave.js )
96 68 printf(
@@ -97,11 +69,19 @@
97 69 '<p><strong>%1$s</strong></p>
98 70 <label class="screen-reader-text" for="%2$s">%1$s</label>
99 71 <div id="select-%3$s-language">%4$s</div>',
100 72 esc_html__( 'Language', 'polylang' ),
101 - esc_attr( $id ),
102 - ( 'attachment' === $post_type ? 'media' : 'post' ),
103 - $dropdown_html // phpcs:ignore WordPress.Security.EscapeOutput
73 + $id = ( 'attachment' === $post_type ) ? sprintf( 'attachments[%d][language]', $post_ID ) : 'post_lang_choice',
74 + 'attachment' === $post_type ? 'media' : 'post',
75 + $dropdown->walk(
76 + $this->model->get_languages_list(),
77 + array(
78 + 'name' => $id,
79 + 'class' => 'post_lang_choice tags-input',
80 + 'selected' => $lang ? $lang->slug : '',
81 + 'flag' => true,
82 + )
83 + )
104 84 );
105 85
106 86 /**
107 87 * Fires before displaying the list of translations in the Languages metabox for posts
@@ -124,21 +104,13 @@
124 104 */
125 105 public function post_lang_choice() {
126 106 check_ajax_referer( 'pll_language', '_pll_nonce' );
127 107
128 - if ( ! isset( $_POST['post_id'], $_POST['lang'], $_POST['post_type'] ) ) {
129 - wp_die( 0 );
130 - }
131 -
132 108 global $post_ID; // Obliged to use the global variable for wp_popular_terms_checklist
133 - $post_ID = (int) $_POST['post_id'];
134 - $lang = $this->model->get_language( sanitize_key( $_POST['lang'] ) );
135 - $post_type = sanitize_key( $_POST['post_type'] );
109 + $post_id = $post_ID = (int) $_POST['post_id'];
110 + $lang = $this->model->get_language( $_POST['lang'] );
136 111
137 - if ( ! post_type_exists( $post_type ) ) {
138 - wp_die( 0 );
139 - }
140 -
112 + $post_type = $_POST['post_type'];
141 113 $post_type_object = get_post_type_object( $post_type );
142 114 if ( ! current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
143 115 wp_die( -1 );
144 116 }
@@ -157,12 +129,11 @@
157 129 $x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
158 130 ob_end_clean();
159 131
160 132 // Categories
161 - if ( isset( $_POST['taxonomies'] ) ) { // Not set for pages
162 - $supplemental = array();
163 -
164 - foreach ( array_map( 'sanitize_key', $_POST['taxonomies'] ) as $taxname ) {
133 + if ( isset( $_POST['taxonomies'] ) ) {
134 + // Not set for pages
135 + foreach ( $_POST['taxonomies'] as $taxname ) {
165 136 $taxonomy = get_taxonomy( $taxname );
166 137
167 138 ob_start();
168 139 $popular_ids = wp_popular_terms_checklist( $taxonomy->name );
@@ -200,9 +171,9 @@
200 171 'post_type' => $post->post_type,
201 172 'exclude_tree' => $post->ID,
202 173 'selected' => $post->post_parent,
203 174 'name' => 'parent_id',
204 - 'show_option_none' => __( '(no parent)', 'polylang' ),
175 + 'show_option_none' => __( '(no parent)' ),
205 176 'sort_column' => 'menu_order, post_title',
206 177 'echo' => 0,
207 178 );
208 179
@@ -208,9 +179,9 @@
208 179
209 180 /** This filter is documented in wp-admin/includes/meta-boxes.php */
210 181 $dropdown_args = apply_filters( 'page_attributes_dropdown_pages_args', $dropdown_args, $post ); // Since WP 3.3
211 182
212 - $x->Add( array( 'what' => 'pages', 'data' => wp_dropdown_pages( $dropdown_args ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput
183 + $x->Add( array( 'what' => 'pages', 'data' => wp_dropdown_pages( $dropdown_args ) ) );
213 184 }
214 185
215 186 // Flag
216 187 $x->Add( array( 'what' => 'flag', 'data' => empty( $lang->flag ) ? esc_html( $lang->slug ) : $lang->flag ) );
@@ -228,34 +199,55 @@
228 199 */
229 200 public function ajax_posts_not_translated() {
230 201 check_ajax_referer( 'pll_language', '_pll_nonce' );
231 202
232 - if ( ! isset( $_GET['post_type'], $_GET['post_language'], $_GET['translation_language'], $_GET['term'], $_GET['pll_post_id'] ) ) {
233 - wp_die( 0 );
203 + if ( ! post_type_exists( $_GET['post_type'] ) ) {
204 + die( 0 );
234 205 }
235 206
236 - $post_type = sanitize_key( $_GET['post_type'] );
207 + $post_language = $this->model->get_language( $_GET['post_language'] );
208 + $translation_language = $this->model->get_language( $_GET['translation_language'] );
237 209
238 - if ( ! post_type_exists( $post_type ) ) {
239 - wp_die( 0 );
240 - }
210 + // Don't order by title: see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
211 + $args = array(
212 + 's' => wp_unslash( $_GET['term'] ),
213 + 'suppress_filters' => 0, // To make the post_fields filter work
214 + 'lang' => 0, // Avoid admin language filter
215 + 'numberposts' => 20, // Limit to 20 posts
216 + 'post_status' => 'any',
217 + 'post_type' => $_GET['post_type'],
218 + 'tax_query' => array(
219 + array(
220 + 'taxonomy' => 'language',
221 + 'field' => 'term_taxonomy_id', // WP 3.5+
222 + 'terms' => $translation_language->term_taxonomy_id,
223 + ),
224 + ),
225 + );
241 226
242 - $term = wp_unslash( $_GET['term'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
227 + /**
228 + * Filter the query args when auto suggesting untranslated posts in the Languages metabox
229 + * This should help plugins to fix some edge cases
230 + *
231 + * @see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
232 + *
233 + * @since 1.7
234 + *
235 + * @param array $args WP_Query arguments
236 + */
237 + $args = apply_filters( 'pll_ajax_posts_not_translated_args', $args );
238 + $posts = get_posts( $args );
243 239
244 - $post_language = $this->model->get_language( sanitize_key( $_GET['post_language'] ) );
245 - $translation_language = $this->model->get_language( sanitize_key( $_GET['translation_language'] ) );
246 -
247 240 $return = array();
248 241
249 - $untranslated_posts = $this->model->post->get_untranslated( $post_type, $post_language, $translation_language, $term );
250 -
251 - // format output
252 - foreach ( $untranslated_posts as $post ) {
253 - $return[] = array(
254 - 'id' => $post->ID,
255 - 'value' => $post->post_title,
256 - 'link' => $this->links->edit_post_translation_link( $post->ID ),
257 - );
242 + foreach ( $posts as $key => $post ) {
243 + if ( ! $this->model->post->get_translation( $post->ID, $post_language ) ) {
244 + $return[] = array(
245 + 'id' => $post->ID,
246 + 'value' => $post->post_title,
247 + 'link' => $this->links->edit_post_translation_link( $post->ID ),
248 + );
249 + }
258 250 }
259 251
260 252 // Add current translation in list
261 253 if ( $post_id = $this->model->post->get_translation( (int) $_GET['pll_post_id'], $translation_language ) ) {
@@ -269,9 +261,9 @@
269 261 )
270 262 );
271 263 }
272 264
273 - wp_die( wp_json_encode( $return ) );
265 + wp_die( json_encode( $return ) );
274 266 }
275 267
276 268 /**
277 269 * Filters the pages by language in the parent dropdown list in the page attributes metabox
@@ -282,35 +274,12 @@
282 274 * @param object $post
283 275 * @return array Modified arguments
284 276 */
285 277 public function page_attributes_dropdown_pages_args( $dropdown_args, $post ) {
286 - $dropdown_args['lang'] = isset( $_POST['lang'] ) ? $this->model->get_language( sanitize_key( $_POST['lang'] ) ) : $this->model->post->get_language( $post->ID ); // phpcs:ignore WordPress.Security.NonceVerification
278 + $dropdown_args['lang'] = isset( $_POST['lang'] ) ? $this->model->get_language( $_POST['lang'] ) : $this->model->post->get_language( $post->ID ); // ajax or not ?
287 279 if ( ! $dropdown_args['lang'] ) {
288 280 $dropdown_args['lang'] = $this->pref_lang;
289 281 }
290 282
291 283 return $dropdown_args;
292 - }
293 -
294 - /**
295 - * Displays a notice if the user has not sufficient rights to overwrite synchronized taxonomies and metas
296 - *
297 - * @since 2.6
298 - *
299 - * @param object $post Post currently being edited
300 - */
301 - public function edit_form_top( $post ) {
302 - if ( ! $this->model->post->current_user_can_synchronize( $post->ID ) ) {
303 - ?>
304 - <div class="pll-notice notice notice-warning">
305 - <p>
306 - <?php
307 - esc_html_e( 'Some taxonomies or metadata may be synchronized with existing translations that you are not allowed to modify.', 'polylang' );
308 - echo ' ';
309 - esc_html_e( 'If you attempt to modify them anyway, your changes will not be saved.', 'polylang' );
310 - ?>
311 - </p>
312 - </div>
313 - <?php
314 - }
315 284 }
316 285 }