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