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