| @@ -1,8 +1,5 @@ | ||
| 1 | 1 | <?php |
| 2 | -/** | |
| 3 | - * @package Polylang | |
| 4 | - */ | |
| 5 | 2 | |
| 6 | 3 | /** |
| 7 | 4 | * Setup miscellaneous admin filters as well as filters common to admin and frontend |
| 8 | 5 | * |
| @@ -44,11 +41,8 @@ | ||
| 44 | 41 | add_filter( 'sanitize_user', array( $this, 'sanitize_user' ), 10, 3 ); |
| 45 | 42 | } |
| 46 | 43 | |
| 47 | 44 | add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) ); |
| 48 | - | |
| 49 | - // Add post state for translations of the privacy policy page | |
| 50 | - add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 ); | |
| 51 | 45 | } |
| 52 | 46 | |
| 53 | 47 | /** |
| 54 | 48 | * Modifies the widgets forms to add our language dropdown list |
| @@ -62,30 +56,25 @@ | ||
| 62 | 56 | public function in_widget_form( $widget, $return, $instance ) { |
| 63 | 57 | $screen = get_current_screen(); |
| 64 | 58 | |
| 65 | 59 | // Test the Widgets screen and the Customizer to avoid displaying the option in page builders |
| 66 | - // Saving the widget reloads the form. And curiously the action is in $_REQUEST but neither in $_POST, nor in $_GET. | |
| 67 | - if ( ( isset( $screen ) && 'widgets' === $screen->base ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification | |
| 60 | + // Saving the widget reloads the form. And curiously the action is in $_REQUEST but neither in $_POST, not in $_GET. | |
| 61 | + if ( ( isset( $screen ) && 'widgets' === $screen->base ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) { | |
| 68 | 62 | $dropdown = new PLL_Walker_Dropdown(); |
| 69 | - | |
| 70 | - $dropdown_html = $dropdown->walk( | |
| 71 | - array_merge( | |
| 72 | - array( (object) array( 'slug' => 0, 'name' => __( 'All languages', 'polylang' ) ) ), | |
| 73 | - $this->model->get_languages_list() | |
| 74 | - ), | |
| 75 | - -1, | |
| 76 | - array( | |
| 77 | - 'name' => $widget->id . '_lang_choice', | |
| 78 | - 'class' => 'tags-input pll-lang-choice', | |
| 79 | - 'selected' => empty( $instance['pll_lang'] ) ? '' : $instance['pll_lang'], | |
| 80 | - ) | |
| 81 | - ); | |
| 82 | - | |
| 83 | - printf( | |
| 84 | - '<p><label for="%1$s">%2$s %3$s</label></p>', | |
| 63 | + printf( '<p><label for="%1$s">%2$s %3$s</label></p>', | |
| 85 | 64 | esc_attr( $widget->id . '_lang_choice' ), |
| 86 | 65 | esc_html__( 'The widget is displayed for:', 'polylang' ), |
| 87 | - $dropdown_html // phpcs:ignore WordPress.Security.EscapeOutput | |
| 66 | + $dropdown->walk( | |
| 67 | + array_merge( | |
| 68 | + array( (object) array( 'slug' => 0, 'name' => __( 'All languages', 'polylang' ) ) ), | |
| 69 | + $this->model->get_languages_list() | |
| 70 | + ), | |
| 71 | + array( | |
| 72 | + 'name' => $widget->id . '_lang_choice', | |
| 73 | + 'class' => 'tags-input', | |
| 74 | + 'selected' => empty( $instance['pll_lang'] ) ? '' : $instance['pll_lang'], | |
| 75 | + ) | |
| 76 | + ) | |
| 88 | 77 | ); |
| 89 | 78 | } |
| 90 | 79 | } |
| 91 | 80 | |
| @@ -101,12 +90,10 @@ | ||
| 101 | 90 | * @param object $widget WP_Widget object |
| 102 | 91 | * @return array Widget options |
| 103 | 92 | */ |
| 104 | 93 | public function widget_update_callback( $instance, $new_instance, $old_instance, $widget ) { |
| 105 | - $key = $widget->id . '_lang_choice'; | |
| 106 | - | |
| 107 | - if ( ! empty( $_POST[ $key ] ) && $lang = $this->model->get_language( sanitize_key( $_POST[ $key ] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification | |
| 108 | - $instance['pll_lang'] = $lang->slug; | |
| 94 | + if ( ! empty( $_POST[ $key = $widget->id . '_lang_choice' ] ) && in_array( $_POST[ $key ], $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) ) { | |
| 95 | + $instance['pll_lang'] = $_POST[ $key ]; | |
| 109 | 96 | } else { |
| 110 | 97 | unset( $instance['pll_lang'] ); |
| 111 | 98 | } |
| 112 | 99 | |
| @@ -120,12 +107,19 @@ | ||
| 120 | 107 | * |
| 121 | 108 | * @param int $user_id |
| 122 | 109 | */ |
| 123 | 110 | public function personal_options_update( $user_id ) { |
| 111 | + // Admin language | |
| 112 | + // FIXME Backward compatibility with WP < 4.7 | |
| 113 | + if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) { | |
| 114 | + $user_lang = in_array( $_POST['user_lang'], $this->model->get_languages_list( array( 'fields' => 'locale' ) ) ) ? $_POST['user_lang'] : 0; | |
| 115 | + update_user_meta( $user_id, 'locale', $user_lang ); | |
| 116 | + } | |
| 117 | + | |
| 124 | 118 | // Biography translations |
| 125 | 119 | foreach ( $this->model->get_languages_list() as $lang ) { |
| 126 | 120 | $meta = $lang->slug == $this->options['default_lang'] ? 'description' : 'description_' . $lang->slug; |
| 127 | - $description = empty( $_POST[ 'description_' . $lang->slug ] ) ? '' : trim( $_POST[ 'description_' . $lang->slug ] ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput | |
| 121 | + $description = empty( $_POST[ 'description_' . $lang->slug ] ) ? '' : trim( $_POST[ 'description_' . $lang->slug ] ); | |
| 128 | 122 | |
| 129 | 123 | /** This filter is documented in wp-includes/user.php */ |
| 130 | 124 | $description = apply_filters( 'pre_user_description', $description ); // Applies WP default filter wp_filter_kses |
| 131 | 125 | update_user_meta( $user_id, $meta, $description ); |
| @@ -132,9 +126,9 @@ | ||
| 132 | 126 | } |
| 133 | 127 | } |
| 134 | 128 | |
| 135 | 129 | /** |
| 136 | - * Outputs hidden information to modify the biography form with js | |
| 130 | + * Form for language user preference in user profile | |
| 137 | 131 | * |
| 138 | 132 | * @since 0.4 |
| 139 | 133 | * |
| 140 | 134 | * @param object $profileuser |
| @@ -139,8 +133,32 @@ | ||
| 139 | 133 | * |
| 140 | 134 | * @param object $profileuser |
| 141 | 135 | */ |
| 142 | 136 | public function personal_options( $profileuser ) { |
| 137 | + // FIXME: Backward compatibility with WP < 4.7 | |
| 138 | + if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) { | |
| 139 | + $dropdown = new PLL_Walker_Dropdown(); | |
| 140 | + printf( ' | |
| 141 | + <tr> | |
| 142 | + <th><label for="user_lang">%s</label></th> | |
| 143 | + <td>%s</td> | |
| 144 | + </tr>', | |
| 145 | + esc_html__( 'Admin language', 'polylang' ), | |
| 146 | + $dropdown->walk( | |
| 147 | + array_merge( | |
| 148 | + array( (object) array( 'locale' => 0, 'name' => __( 'WordPress default', 'polylang' ) ) ), | |
| 149 | + $this->model->get_languages_list() | |
| 150 | + ), | |
| 151 | + array( | |
| 152 | + 'name' => 'user_lang', | |
| 153 | + 'value' => 'locale', | |
| 154 | + 'selected' => get_user_meta( $profileuser->ID, 'locale', true ), | |
| 155 | + ) | |
| 156 | + ) | |
| 157 | + ); | |
| 158 | + } | |
| 159 | + | |
| 160 | + // Hidden information to modify the biography form with js | |
| 143 | 161 | foreach ( $this->model->get_languages_list() as $lang ) { |
| 144 | 162 | $meta = $lang->slug == $this->options['default_lang'] ? 'description' : 'description_' . $lang->slug; |
| 145 | 163 | |
| 146 | 164 | /** This filter is documented in wp-includes/user.php */ |
| @@ -145,10 +163,9 @@ | ||
| 145 | 163 | |
| 146 | 164 | /** This filter is documented in wp-includes/user.php */ |
| 147 | 165 | $description = apply_filters( 'user_description', get_user_meta( $profileuser->ID, $meta, true ) ); // Applies WP default filter wp_kses_data |
| 148 | 166 | |
| 149 | - printf( | |
| 150 | - '<input type="hidden" class="biography" name="%s___%s" value="%s" />', | |
| 167 | + printf( '<input type="hidden" class="biography" name="%s___%s" value="%s" />', | |
| 151 | 168 | esc_attr( $lang->slug ), |
| 152 | 169 | esc_attr( $lang->name ), |
| 153 | 170 | esc_attr( $description ) |
| 154 | 171 | ); |
| @@ -180,9 +197,9 @@ | ||
| 180 | 197 | * |
| 181 | 198 | * @param array $locales Not used |
| 182 | 199 | * @return array list of locales to update |
| 183 | 200 | */ |
| 184 | - public function update_check_locales( $locales ) { | |
| 201 | + function update_check_locales( $locales ) { | |
| 185 | 202 | return $this->model->get_languages_list( array( 'fields' => 'locale' ) ); |
| 186 | 203 | } |
| 187 | 204 | |
| 188 | 205 | /** |
| @@ -194,19 +211,9 @@ | ||
| 194 | 211 | * @param string $locale |
| 195 | 212 | * @return string |
| 196 | 213 | */ |
| 197 | 214 | public function get_locale( $locale ) { |
| 198 | - if ( isset( $_POST['post_lang_choice'] ) && $lang = $this->model->get_language( sanitize_key( $_POST['post_lang_choice'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification | |
| 199 | - $locale = $lang->locale; | |
| 200 | - } elseif ( isset( $_POST['term_lang_choice'] ) && $lang = $this->model->get_language( sanitize_key( $_POST['term_lang_choice'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification | |
| 201 | - $locale = $lang->locale; | |
| 202 | - } elseif ( isset( $_POST['inline_lang_choice'] ) && $lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification | |
| 203 | - $locale = $lang->locale; | |
| 204 | - } elseif ( ! empty( $this->curlang ) ) { | |
| 205 | - $locale = $this->curlang->locale; | |
| 206 | - } | |
| 207 | - | |
| 208 | - return $locale; | |
| 215 | + return $this->curlang->locale; | |
| 209 | 216 | } |
| 210 | 217 | |
| 211 | 218 | /** |
| 212 | 219 | * Maybe fix the result of sanitize_title() in case the languages include German or Danish |
| @@ -223,9 +230,9 @@ | ||
| 223 | 230 | */ |
| 224 | 231 | public function sanitize_title( $title, $raw_title, $context ) { |
| 225 | 232 | static $once = false; |
| 226 | 233 | |
| 227 | - if ( ! $once && 'save' == $context && ! empty( $title ) ) { | |
| 234 | + if ( ! $once && 'save' == $context && ! empty( $this->curlang ) && ! empty( $title ) ) { | |
| 228 | 235 | $once = true; |
| 229 | 236 | add_filter( 'locale', array( $this, 'get_locale' ), 20 ); // After the filter for the admin interface |
| 230 | 237 | $title = sanitize_title( $raw_title, '', $context ); |
| 231 | 238 | remove_filter( 'locale', array( $this, 'get_locale' ), 20 ); |
| @@ -246,9 +253,9 @@ | ||
| 246 | 253 | */ |
| 247 | 254 | public function sanitize_user( $username, $raw_username, $strict ) { |
| 248 | 255 | static $once = false; |
| 249 | 256 | |
| 250 | - if ( ! $once ) { | |
| 257 | + if ( ! $once && ! empty( $this->curlang ) ) { | |
| 251 | 258 | $once = true; |
| 252 | 259 | add_filter( 'locale', array( $this, 'get_locale' ), 20 ); // After the filter for the admin interface |
| 253 | 260 | $username = sanitize_user( $raw_username, '', $strict ); |
| 254 | 261 | remove_filter( 'locale', array( $this, 'get_locale' ), 20 ); |
| @@ -269,25 +276,6 @@ | ||
| 269 | 276 | if ( ! empty( $this->curlang ) ) { |
| 270 | 277 | $classes .= ' pll-dir-' . ( $this->curlang->is_rtl ? 'rtl' : 'ltr' ); |
| 271 | 278 | } |
| 272 | 279 | return $classes; |
| 273 | - } | |
| 274 | - | |
| 275 | - /** | |
| 276 | - * Add post state for translations of the privacy policy page | |
| 277 | - * | |
| 278 | - * @since 2.7 | |
| 279 | - * | |
| 280 | - * @param array $post_states An array of post display states. | |
| 281 | - * @param object $post The current post object. | |
| 282 | - * @return array | |
| 283 | - */ | |
| 284 | - public function display_post_states( $post_states, $post ) { | |
| 285 | - $page_for_privacy_policy = get_option( 'wp_page_for_privacy_policy' ); | |
| 286 | - | |
| 287 | - if ( $page_for_privacy_policy && in_array( $post->ID, $this->model->post->get_translations( $page_for_privacy_policy ) ) ) { | |
| 288 | - $post_states['page_for_privacy_policy'] = __( 'Privacy Policy Page', 'polylang' ); | |
| 289 | - } | |
| 290 | - | |
| 291 | - return $post_states; | |
| 292 | 280 | } |
| 293 | 281 | } |