PluginProbe
Polylang / 2.4
Polylang v2.4
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 | settings/table-string.php +34 -96 2.82.4 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -/**
3 - * @package Polylang
4 - */
5 2
6 3 if ( ! class_exists( 'WP_List_Table' ) ) {
7 4 require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; // since WP 3.1
8 5 }
@@ -33,18 +30,10 @@
33 30
34 31 $this->languages = $languages;
35 32 $this->strings = PLL_Admin_Strings::get_strings();
36 33 $this->groups = array_unique( wp_list_pluck( $this->strings, 'context' ) );
34 + $this->selected_group = empty( $_GET['group'] ) || ! in_array( $_GET['group'], $this->groups ) ? -1 : $_GET['group'];
37 35
38 - $this->selected_group = -1;
39 -
40 - if ( ! empty( $_GET['group'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
41 - $group = sanitize_text_field( wp_unslash( $_GET['group'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
42 - if ( in_array( $group, $this->groups ) ) {
43 - $this->selected_group = $group;
44 - }
45 - }
46 -
47 36 add_action( 'mlang_action_string-translation', array( $this, 'save_translations' ) );
48 37 }
49 38
50 39 /**
@@ -72,9 +61,9 @@
72 61 return sprintf(
73 62 '<label class="screen-reader-text" for="cb-select-%1$s">%2$s</label><input id="cb-select-%1$s" type="checkbox" name="strings[]" value="%1$s" %3$s />',
74 63 esc_attr( $item['row'] ),
75 64 /* translators: accessibility text, %s is a string potentially in any language */
76 - sprintf( __( 'Select %s', 'polylang' ), format_to_edit( $item['string'] ) ),
65 + sprintf( __( 'Select %s' ), format_to_edit( $item['string'] ) ),
77 66 empty( $item['icl'] ) ? 'disabled' : '' // Only strings registered with WPML API can be removed
78 67 );
79 68 }
80 69
@@ -161,31 +150,8 @@
161 150 return 'string';
162 151 }
163 152
164 153 /**
165 - * Search for a string in translations. Case insensitive.
166 - *
167 - * @since 2.6
168 - *
169 - * @param array $mos An array of PLL_MO objects
170 - * @param string $s Searched string
171 - * @return array Found strings
172 - */
173 - protected function search_in_translations( $mos, $s ) {
174 - $founds = array();
175 -
176 - foreach ( $mos as $mo ) {
177 - foreach ( wp_list_pluck( $mo->entries, 'translations' ) as $string => $translation ) {
178 - if ( false !== stripos( $translation[0], $s ) ) {
179 - $founds[] = $string;
180 - }
181 - }
182 - }
183 -
184 - return array_unique( $founds );
185 - }
186 -
187 - /**
188 154 * Sort items
189 155 *
190 156 * @since 0.6
191 157 *
@@ -193,17 +159,10 @@
193 159 * @param object $b The second object to compare
194 160 * @return int -1 or 1 if $a is considered to be respectively less than or greater than $b.
195 161 */
196 162 protected function usort_reorder( $a, $b ) {
197 - if ( ! empty( $_GET['orderby'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
198 - $orderby = sanitize_key( $_GET['orderby'] ); // phpcs:ignore WordPress.Security.NonceVerification
199 - if ( isset( $a[ $orderby ], $b[ $orderby ] ) ) {
200 - $result = strcmp( $a[ $orderby ], $b[ $orderby ] ); // Determine sort order
201 - return ( empty( $_GET['order'] ) || 'asc' === $_GET['order'] ) ? $result : -$result; // phpcs:ignore WordPress.Security.NonceVerification
202 - }
203 - }
204 -
205 - return 0;
163 + $result = strcmp( $a[ $_GET['orderby'] ], $b[ $_GET['orderby'] ] ); // determine sort order
164 + return ( empty( $_GET['order'] ) || 'asc' === $_GET['order'] ) ? $result : -$result; // send final sort direction to usort
206 165 }
207 166
208 167 /**
209 168 * Prepares the list of items for displaying
@@ -210,52 +169,42 @@
210 169 *
211 170 * @since 0.6
212 171 */
213 172 public function prepare_items() {
214 - // Is admin language filter active?
215 - if ( $lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true ) ) {
216 - $languages = wp_list_filter( $this->languages, array( 'slug' => $lg ) );
217 - } else {
218 - $languages = $this->languages;
219 - }
220 -
221 - // Load translations
222 - $mo = array();
223 - foreach ( $languages as $language ) {
224 - $mo[ $language->slug ] = new PLL_MO();
225 - $mo[ $language->slug ]->import_from_db( $language );
226 - }
227 -
228 173 $data = $this->strings;
229 174
230 - // Filter by selected group
231 - if ( -1 !== $this->selected_group ) {
232 - $data = wp_list_filter( $data, array( 'context' => $this->selected_group ) );
175 + // Filter for search string
176 + $s = empty( $_GET['s'] ) ? '' : wp_unslash( $_GET['s'] );
177 + foreach ( $data as $key => $row ) {
178 + if ( ( -1 !== $this->selected_group && $row['context'] !== $this->selected_group ) || ( ! empty( $s ) && stripos( $row['name'], $s ) === false && stripos( $row['string'], $s ) === false ) ) {
179 + unset( $data[ $key ] );
180 + }
233 181 }
234 182
235 - // Filter by searched string
236 - $s = empty( $_GET['s'] ) ? '' : wp_unslash( $_GET['s'] ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
183 + // Load translations
184 + foreach ( $this->languages as $language ) {
185 + // Filters by language if requested
186 + if ( ( $lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true ) ) && $language->slug !== $lg ) {
187 + continue;
188 + }
237 189
238 - if ( ! empty( $s ) ) {
239 - // Search in translations
240 - $in_translations = $this->search_in_translations( $mo, $s );
241 -
190 + $mo = new PLL_MO();
191 + $mo->import_from_db( $language );
242 192 foreach ( $data as $key => $row ) {
243 - if ( stripos( $row['name'], $s ) === false && stripos( $row['string'], $s ) === false && ! in_array( $row['string'], $in_translations ) ) {
244 - unset( $data[ $key ] );
245 - }
193 + $data[ $key ]['translations'][ $language->slug ] = $mo->translate( $row['string'] );
194 + $data[ $key ]['row'] = $key; // Store the row number for convenience
246 195 }
247 196 }
248 197
249 - // Sorting
250 - uasort( $data, array( $this, 'usort_reorder' ) );
251 -
252 - // Paging
253 198 $per_page = $this->get_items_per_page( 'pll_strings_per_page' );
254 199 $this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
255 200
201 + if ( ! empty( $_GET['orderby'] ) ) { // No sort by default
202 + usort( $data, array( $this, 'usort_reorder' ) );
203 + }
204 +
256 205 $total_items = count( $data );
257 - $this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page, true );
206 + $this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
258 207
259 208 $this->set_pagination_args(
260 209 array(
261 210 'total_items' => $total_items,
@@ -262,17 +211,8 @@
262 211 'per_page' => $per_page,
263 212 'total_pages' => ceil( $total_items / $per_page ),
264 213 )
265 214 );
266 -
267 - // Translate strings
268 - // Kept for the end as it is a slow process
269 - foreach ( $languages as $language ) {
270 - foreach ( $this->items as $key => $row ) {
271 - $this->items[ $key ]['translations'][ $language->slug ] = $mo[ $language->slug ]->translate( $row['string'] );
272 - $this->items[ $key ]['row'] = $key; // Store the row number for convenience
273 - }
274 - }
275 215 }
276 216
277 217 /**
278 218 * Get the list of possible bulk actions
@@ -293,9 +233,9 @@
293 233 *
294 234 * @return string|false The action name or False if no action was selected
295 235 */
296 236 public function current_action() {
297 - return empty( $_POST['submit'] ) ? parent::current_action() : false; // phpcs:ignore WordPress.Security.NonceVerification
237 + return empty( $_POST['submit'] ) ? parent::current_action() : false;
298 238 }
299 239
300 240 /**
301 241 * Displays the dropdown list to filter strings per group
@@ -317,9 +257,9 @@
317 257 );
318 258 echo '<select id="select-group" name="group">' . "\n";
319 259 printf(
320 260 '<option value="-1"%s>%s</option>' . "\n",
321 - selected( $this->group_selected, -1, false ),
261 + -1 === $this->group_selected ? ' selected="selected"' : '',
322 262 esc_html__( 'View all groups', 'polylang' )
323 263 );
324 264
325 265 foreach ( $this->groups as $group ) {
@@ -325,15 +265,15 @@
325 265 foreach ( $this->groups as $group ) {
326 266 printf(
327 267 '<option value="%s"%s>%s</option>' . "\n",
328 268 esc_attr( urlencode( $group ) ),
329 - selected( $this->selected_group, $group, false ),
269 + $this->selected_group === $group ? ' selected="selected"' : '',
330 270 esc_html( $group )
331 271 );
332 272 }
333 273 echo '</select>' . "\n";
334 274
335 - submit_button( __( 'Filter', 'polylang' ), 'button', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
275 + submit_button( __( 'Filter' ), 'button', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
336 276 echo '</div>';
337 277 }
338 278
339 279 /**
@@ -353,20 +293,18 @@
353 293
354 294 $mo = new PLL_MO();
355 295 $mo->import_from_db( $language );
356 296
357 - $translations = array_map( 'trim', wp_unslash( $_POST['translation'][ $language->slug ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
358 - foreach ( $translations as $key => $translation ) {
297 + foreach ( $_POST['translation'][ $language->slug ] as $key => $translation ) {
359 298 /**
360 299 * Filter the string translation before it is saved in DB
361 300 * Allows to sanitize strings registered with pll_register_string
362 301 *
363 302 * @since 1.6
364 - * @since 2.7 The translation passed to the filter is unslashed.
365 303 *
366 - * @param string $translation The string translation.
367 - * @param string $name The name as defined in pll_register_string.
368 - * @param string $context The context as defined in pll_register_string.
304 + * @param string $translation the string translation
305 + * @param string $name the name as defined in pll_register_string
306 + * @param string $context the context as defined in pll_register_string
369 307 */
370 308 $translation = apply_filters( 'pll_sanitize_string_translation', $translation, $this->strings[ $key ]['name'], $this->strings[ $key ]['context'] );
371 309 $mo->add_entry( $mo->make_entry( $this->strings[ $key ]['string'], $translation ) );
372 310 }
@@ -394,9 +332,9 @@
394 332 }
395 333
396 334 // Unregisters strings registered through WPML API
397 335 if ( $this->current_action() === 'delete' && ! empty( $_POST['strings'] ) && function_exists( 'icl_unregister_string' ) ) {
398 - foreach ( array_map( 'sanitize_key', $_POST['strings'] ) as $key ) {
336 + foreach ( $_POST['strings'] as $key ) {
399 337 icl_unregister_string( $this->strings[ $key ]['context'], $this->strings[ $key ]['name'] );
400 338 }
401 339 }
402 340