PluginProbe
Polylang / 2.1
Polylang v2.1
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 +58 -123 2.72.1 View file →
@@ -1,8 +1,8 @@
1 1 <?php
2 2
3 3 if ( ! class_exists( 'WP_List_Table' ) ) {
4 - require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; // since WP 3.1
4 + require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); // since WP 3.1
5 5 }
6 6
7 7 /**
8 8 * A class to create the strings translations table
@@ -19,29 +19,19 @@
19 19 * @since 0.6
20 20 *
21 21 * @param array $languages list of languages
22 22 */
23 - public function __construct( $languages ) {
24 - parent::__construct(
25 - array(
26 - 'plural' => 'Strings translations', // Do not translate ( used for css class )
27 - 'ajax' => false,
28 - )
29 - );
23 + function __construct( $languages ) {
24 + parent::__construct( array(
25 + 'plural' => 'Strings translations', // Do not translate ( used for css class )
26 + 'ajax' => false,
27 + ) );
30 28
31 29 $this->languages = $languages;
32 30 $this->strings = PLL_Admin_Strings::get_strings();
33 31 $this->groups = array_unique( wp_list_pluck( $this->strings, 'context' ) );
32 + $this->selected_group = empty( $_GET['group'] ) || ! in_array( $_GET['group'], $this->groups ) ? -1 : $_GET['group'];
34 33
35 - $this->selected_group = -1;
36 -
37 - if ( ! empty( $_GET['group'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
38 - $group = sanitize_text_field( wp_unslash( $_GET['group'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
39 - if ( in_array( $group, $this->groups ) ) {
40 - $this->selected_group = $group;
41 - }
42 - }
43 -
44 34 add_action( 'mlang_action_string-translation', array( $this, 'save_translations' ) );
45 35 }
46 36
47 37 /**
@@ -52,9 +42,9 @@
52 42 * @param array $item
53 43 * @param string $column_name
54 44 * @return string
55 45 */
56 - public function column_default( $item, $column_name ) {
46 + function column_default( $item, $column_name ) {
57 47 return $item[ $column_name ];
58 48 }
59 49
60 50 /**
@@ -64,14 +54,14 @@
64 54 *
65 55 * @param array $item
66 56 * @return string
67 57 */
68 - public function column_cb( $item ) {
58 + function column_cb( $item ) {
69 59 return sprintf(
70 60 '<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 />',
71 61 esc_attr( $item['row'] ),
72 62 /* translators: accessibility text, %s is a string potentially in any language */
73 - sprintf( __( 'Select %s', 'polylang' ), format_to_edit( $item['string'] ) ),
63 + sprintf( __( 'Select %s' ), format_to_edit( $item['string'] ) ),
74 64 empty( $item['icl'] ) ? 'disabled' : '' // Only strings registered with WPML API can be removed
75 65 );
76 66 }
77 67
@@ -82,9 +72,9 @@
82 72 *
83 73 * @param array $item
84 74 * @return string
85 75 */
86 - public function column_string( $item ) {
76 + function column_string( $item ) {
87 77 return format_to_edit( $item['string'] ); // Don't interpret special chars for the string column
88 78 }
89 79
90 80 /**
@@ -94,9 +84,9 @@
94 84 *
95 85 * @param array $item
96 86 * @return string
97 87 */
98 - public function column_translations( $item ) {
88 + function column_translations( $item ) {
99 89 $languages = array_combine( wp_list_pluck( $this->languages, 'slug' ), wp_list_pluck( $this->languages, 'name' ) );
100 90 $out = '';
101 91
102 92 foreach ( $item['translations'] as $key => $translation ) {
@@ -102,15 +92,13 @@
102 92 foreach ( $item['translations'] as $key => $translation ) {
103 93 $input_type = $item['multiline'] ?
104 94 '<textarea name="translation[%1$s][%2$s]" id="%1$s-%2$s">%4$s</textarea>' :
105 95 '<input type="text" name="translation[%1$s][%2$s]" id="%1$s-%2$s" value="%4$s" />';
106 - $out .= sprintf(
107 - '<div class="translation"><label for="%1$s-%2$s">%3$s</label>' . $input_type . '</div>' . "\n",
96 + $out .= sprintf( '<div class="translation"><label for="%1$s-%2$s">%3$s</label>'.$input_type.'</div>'."\n",
108 97 esc_attr( $key ),
109 98 esc_attr( $item['row'] ),
110 99 esc_html( $languages[ $key ] ),
111 - format_to_edit( $translation ) // Don't interpret special chars
112 - );
100 + format_to_edit( $translation ) ); // Don't interpret special chars
113 101 }
114 102
115 103 return $out;
116 104 }
@@ -121,9 +109,9 @@
121 109 * @since 0.6
122 110 *
123 111 * @return array the list of column titles
124 112 */
125 - public function get_columns() {
113 + function get_columns() {
126 114 return array(
127 115 'cb' => '<input type="checkbox" />', // Checkbox
128 116 'string' => esc_html__( 'String', 'polylang' ),
129 117 'name' => esc_html__( 'Name', 'polylang' ),
@@ -138,9 +126,9 @@
138 126 * @since 0.6
139 127 *
140 128 * @return array
141 129 */
142 - public function get_sortable_columns() {
130 + function get_sortable_columns() {
143 131 return array(
144 132 'string' => array( 'string', false ),
145 133 'name' => array( 'name', false ),
146 134 'context' => array( 'context', false ),
@@ -158,31 +146,8 @@
158 146 return 'string';
159 147 }
160 148
161 149 /**
162 - * Search for a string in translations. Case insensitive.
163 - *
164 - * @since 2.6
165 - *
166 - * @param array $mos An array of PLL_MO objects
167 - * @param string $s Searched string
168 - * @return array Found strings
169 - */
170 - protected function search_in_translations( $mos, $s ) {
171 - $founds = array();
172 -
173 - foreach ( $mos as $mo ) {
174 - foreach ( wp_list_pluck( $mo->entries, 'translations' ) as $string => $translation ) {
175 - if ( false !== stripos( $translation[0], $s ) ) {
176 - $founds[] = $string;
177 - }
178 - }
179 - }
180 -
181 - return array_unique( $founds );
182 - }
183 -
184 - /**
185 150 * Sort items
186 151 *
187 152 * @since 0.6
188 153 *
@@ -190,17 +155,10 @@
190 155 * @param object $b The second object to compare
191 156 * @return int -1 or 1 if $a is considered to be respectively less than or greater than $b.
192 157 */
193 158 protected function usort_reorder( $a, $b ) {
194 - if ( ! empty( $_GET['orderby'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
195 - $orderby = sanitize_key( $_GET['orderby'] ); // phpcs:ignore WordPress.Security.NonceVerification
196 - if ( isset( $a[ $orderby ], $b[ $orderby ] ) ) {
197 - $result = strcmp( $a[ $orderby ], $b[ $orderby ] ); // Determine sort order
198 - return ( empty( $_GET['order'] ) || 'asc' === $_GET['order'] ) ? $result : -$result; // phpcs:ignore WordPress.Security.NonceVerification
199 - }
200 - }
201 -
202 - return 0;
159 + $result = strcmp( $a[ $_GET['orderby'] ], $b[ $_GET['orderby'] ] ); // determine sort order
160 + return ( empty( $_GET['order'] ) || 'asc' === $_GET['order'] ) ? $result : -$result; // send final sort direction to usort
203 161 }
204 162
205 163 /**
206 164 * Prepares the list of items for displaying
@@ -206,70 +164,49 @@
206 164 * Prepares the list of items for displaying
207 165 *
208 166 * @since 0.6
209 167 */
210 - public function prepare_items() {
211 - // Is admin language filter active?
212 - if ( $lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true ) ) {
213 - $languages = wp_list_filter( $this->languages, array( 'slug' => $lg ) );
214 - } else {
215 - $languages = $this->languages;
216 - }
217 -
218 - // Load translations
219 - $mo = array();
220 - foreach ( $languages as $language ) {
221 - $mo[ $language->slug ] = new PLL_MO();
222 - $mo[ $language->slug ]->import_from_db( $language );
223 - }
224 -
168 + function prepare_items() {
225 169 $data = $this->strings;
226 170
227 - // Filter by selected group
228 - if ( -1 !== $this->selected_group ) {
229 - $data = wp_list_filter( $data, array( 'context' => $this->selected_group ) );
171 + // Filter for search string
172 + $s = empty( $_GET['s'] ) ? '' : wp_unslash( $_GET['s'] );
173 + foreach ( $data as $key => $row ) {
174 + if ( ( -1 !== $this->selected_group && $row['context'] !== $this->selected_group ) || ( ! empty( $s ) && stripos( $row['name'], $s ) === false && stripos( $row['string'], $s ) === false ) ) {
175 + unset( $data[ $key ] );
176 + }
230 177 }
231 178
232 - // Filter by searched string
233 - $s = empty( $_GET['s'] ) ? '' : wp_unslash( $_GET['s'] ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
179 + // Load translations
180 + foreach ( $this->languages as $language ) {
181 + // Filters by language if requested
182 + if ( ( $lg = get_user_meta( get_current_user_id(), 'pll_filter_content', true ) ) && $language->slug !== $lg ) {
183 + continue;
184 + }
234 185
235 - if ( ! empty( $s ) ) {
236 - // Search in translations
237 - $in_translations = $this->search_in_translations( $mo, $s );
238 -
186 + $mo = new PLL_MO();
187 + $mo->import_from_db( $language );
239 188 foreach ( $data as $key => $row ) {
240 - if ( stripos( $row['name'], $s ) === false && stripos( $row['string'], $s ) === false && ! in_array( $row['string'], $in_translations ) ) {
241 - unset( $data[ $key ] );
242 - }
189 + $data[ $key ]['translations'][ $language->slug ] = $mo->translate( $row['string'] );
190 + $data[ $key ]['row'] = $key; // Store the row number for convenience
243 191 }
244 192 }
245 193
246 - // Sorting
247 - uasort( $data, array( $this, 'usort_reorder' ) );
248 -
249 - // Paging
250 194 $per_page = $this->get_items_per_page( 'pll_strings_per_page' );
251 195 $this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
252 196
197 + if ( ! empty( $_GET['orderby'] ) ) { // No sort by default
198 + usort( $data, array( $this, 'usort_reorder' ) );
199 + }
200 +
253 201 $total_items = count( $data );
254 - $this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page, true );
202 + $this->items = array_slice( $data, ( $this->get_pagenum() - 1 ) * $per_page, $per_page );
255 203
256 - $this->set_pagination_args(
257 - array(
258 - 'total_items' => $total_items,
259 - 'per_page' => $per_page,
260 - 'total_pages' => ceil( $total_items / $per_page ),
261 - )
262 - );
263 -
264 - // Translate strings
265 - // Kept for the end as it is a slow process
266 - foreach ( $languages as $language ) {
267 - foreach ( $this->items as $key => $row ) {
268 - $this->items[ $key ]['translations'][ $language->slug ] = $mo[ $language->slug ]->translate( $row['string'] );
269 - $this->items[ $key ]['row'] = $key; // Store the row number for convenience
270 - }
271 - }
204 + $this->set_pagination_args( array(
205 + 'total_items' => $total_items,
206 + 'per_page' => $per_page,
207 + 'total_pages' => ceil( $total_items / $per_page ),
208 + ) );
272 209 }
273 210
274 211 /**
275 212 * Get the list of possible bulk actions
@@ -277,10 +214,10 @@
277 214 * @since 1.1
278 215 *
279 216 * @return array
280 217 */
281 - public function get_bulk_actions() {
282 - return array( 'delete' => __( 'Delete', 'polylang' ) );
218 + function get_bulk_actions() {
219 + return array( 'delete' => __( 'Delete','polylang' ) );
283 220 }
284 221
285 222 /**
286 223 * Get the current action selected from the bulk actions dropdown.
@@ -290,9 +227,9 @@
290 227 *
291 228 * @return string|false The action name or False if no action was selected
292 229 */
293 230 public function current_action() {
294 - return empty( $_POST['submit'] ) ? parent::current_action() : false; // phpcs:ignore WordPress.Security.NonceVerification
231 + return empty( $_POST['submit'] ) ? parent::current_action() : false;
295 232 }
296 233
297 234 /**
298 235 * Displays the dropdown list to filter strings per group
@@ -300,9 +237,9 @@
300 237 * @since 1.1
301 238 *
302 239 * @param string $which only 'top' is supported
303 240 */
304 - public function extra_tablenav( $which ) {
241 + function extra_tablenav( $which ) {
305 242 if ( 'top' !== $which ) {
306 243 return;
307 244 }
308 245
@@ -314,9 +251,9 @@
314 251 );
315 252 echo '<select id="select-group" name="group">' . "\n";
316 253 printf(
317 254 '<option value="-1"%s>%s</option>' . "\n",
318 - selected( $this->group_selected, -1, false ),
255 + -1 === $this->group_selected ? ' selected="selected"' : '',
319 256 esc_html__( 'View all groups', 'polylang' )
320 257 );
321 258
322 259 foreach ( $this->groups as $group ) {
@@ -322,15 +259,15 @@
322 259 foreach ( $this->groups as $group ) {
323 260 printf(
324 261 '<option value="%s"%s>%s</option>' . "\n",
325 262 esc_attr( urlencode( $group ) ),
326 - selected( $this->selected_group, $group, false ),
263 + $this->selected_group === $group ? ' selected="selected"' : '',
327 264 esc_html( $group )
328 265 );
329 266 }
330 - echo '</select>' . "\n";
267 + echo '</select>'."\n";
331 268
332 - submit_button( __( 'Filter', 'polylang' ), 'button', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
269 + submit_button( __( 'Filter' ), 'button', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
333 270 echo '</div>';
334 271 }
335 272
336 273 /**
@@ -350,20 +287,18 @@
350 287
351 288 $mo = new PLL_MO();
352 289 $mo->import_from_db( $language );
353 290
354 - $translations = array_map( 'trim', wp_unslash( $_POST['translation'][ $language->slug ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
355 - foreach ( $translations as $key => $translation ) {
291 + foreach ( $_POST['translation'][ $language->slug ] as $key => $translation ) {
356 292 /**
357 293 * Filter the string translation before it is saved in DB
358 294 * Allows to sanitize strings registered with pll_register_string
359 295 *
360 296 * @since 1.6
361 - * @since 2.7 The translation passed to the filter is unslashed.
362 297 *
363 - * @param string $translation The string translation.
364 - * @param string $name The name as defined in pll_register_string.
365 - * @param string $context The context as defined in pll_register_string.
298 + * @param string $translation the string translation
299 + * @param string $name the name as defined in pll_register_string
300 + * @param string $context the context as defined in pll_register_string
366 301 */
367 302 $translation = apply_filters( 'pll_sanitize_string_translation', $translation, $this->strings[ $key ]['name'], $this->strings[ $key ]['context'] );
368 303 $mo->add_entry( $mo->make_entry( $this->strings[ $key ]['string'], $translation ) );
369 304 }
@@ -391,9 +326,9 @@
391 326 }
392 327
393 328 // Unregisters strings registered through WPML API
394 329 if ( $this->current_action() === 'delete' && ! empty( $_POST['strings'] ) && function_exists( 'icl_unregister_string' ) ) {
395 - foreach ( array_map( 'sanitize_key', $_POST['strings'] ) as $key ) {
330 + foreach ( $_POST['strings'] as $key ) {
396 331 icl_unregister_string( $this->strings[ $key ]['context'], $this->strings[ $key ]['name'] );
397 332 }
398 333 }
399 334