PluginProbe
Polylang / 2.6
Polylang v2.6
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
polylang / settings / settings.php

settings.php in Polylang 2.6, at settings/settings.php

397 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * A class for the Polylang settings pages
5 * accessible in $polylang global object
6 *
7 * Properties:
8 * options => inherited, reference to Polylang options array
9 * model => inherited, reference to PLL_Model object
10 * links_model => inherited, reference to PLL_Links_Model object
11 * links => inherited, reference to PLL_Admin_Links object
12 * static_pages => inherited, reference to PLL_Admin_Static_Pages object
13 * filters_links => inherited, reference to PLL_Filters_Links object
14 * curlang => inherited, optional, current language used to filter admin content
15 * pref_lang => inherited, preferred language used as default when saving posts or terms
16 *
17 * @since 1.2
18 */
19 class PLL_Settings extends PLL_Admin_Base {
20 protected $active_tab, $modules;
21
22 /**
23 * Constructor
24 *
25 * @since 1.2
26 *
27 * @param object $links_model
28 */
29 public function __construct( &$links_model ) {
30 parent::__construct( $links_model );
31
32 if ( isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
33 $this->active_tab = 'mlang' === $_GET['page'] ? 'lang' : substr( sanitize_key( $_GET['page'] ), 6 ); // phpcs:ignore WordPress.Security.NonceVerification
34 }
35
36 PLL_Admin_Strings::init();
37
38 // FIXME put this as late as possible
39 add_action( 'admin_init', array( $this, 'register_settings_modules' ) );
40
41 // Adds screen options and the about box in the languages admin panel
42 add_action( 'load-toplevel_page_mlang', array( $this, 'load_page' ) );
43 add_action( 'load-languages_page_mlang_strings', array( $this, 'load_page_strings' ) );
44
45 // Saves per-page value in screen option
46 add_filter( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 );
47 }
48
49 /**
50 * Initializes the modules
51 *
52 * @since 1.8
53 */
54 public function register_settings_modules() {
55 $modules = array(
56 'PLL_Settings_Tools',
57 'PLL_Settings_Licenses',
58 );
59
60 if ( $this->model->get_languages_list() ) {
61 $modules = array_merge(
62 array(
63 'PLL_Settings_Url',
64 'PLL_Settings_Browser',
65 'PLL_Settings_Media',
66 'PLL_Settings_CPT',
67 'PLL_Settings_Sync',
68 'PLL_Settings_WPML',
69 'PLL_Settings_Share_Slug',
70 'PLL_Settings_Translate_Slugs',
71 ),
72 $modules
73 );
74 }
75
76 /**
77 * Filter the list of setting modules
78 *
79 * @since 1.8
80 *
81 * @param array $modules the list of module classes
82 */
83 $modules = apply_filters( 'pll_settings_modules', $modules );
84
85 foreach ( $modules as $key => $class ) {
86 $key = is_numeric( $key ) ? strtolower( str_replace( 'PLL_Settings_', '', $class ) ) : $key;
87 $this->modules[ $key ] = new $class( $this );
88 }
89 }
90
91 /**
92 * Loads the about metabox
93 *
94 * @since 0.8
95 */
96 public function metabox_about() {
97 include PLL_SETTINGS_INC . '/view-about.php';
98 }
99
100 /**
101 * Adds screen options and the about box in the languages admin panel
102 *
103 * @since 0.9.5
104 */
105 public function load_page() {
106 if ( ! defined( 'PLL_DISPLAY_ABOUT' ) || PLL_DISPLAY_ABOUT ) {
107 add_meta_box(
108 'pll-about-box',
109 __( 'About Polylang', 'polylang' ),
110 array( $this, 'metabox_about' ),
111 'settings_page_mlang', // FIXME not shown in screen options
112 'normal'
113 );
114 }
115
116 add_screen_option(
117 'per_page',
118 array(
119 'label' => __( 'Languages', 'polylang' ),
120 'default' => 10,
121 'option' => 'pll_lang_per_page',
122 )
123 );
124
125 add_action( 'admin_notices', array( $this, 'notice_objects_with_no_lang' ) );
126 }
127
128 /**
129 * Adds screen options in the strings translations admin panel
130 *
131 * @since 2.1
132 */
133 public function load_page_strings() {
134 add_screen_option(
135 'per_page',
136 array(
137 'label' => __( 'Strings translations', 'polylang' ),
138 'default' => 10,
139 'option' => 'pll_strings_per_page',
140 )
141 );
142 }
143
144 /**
145 * Save the "Views/Uploads per page" option set by this user
146 *
147 * @since 0.9.5
148 *
149 * @param mixed $status false or value returned by previous filter
150 * @param string $option Name of the option being changed
151 * @param string $value Value of the option
152 *
153 * @return string New value if this is our option, otherwise nothing
154 */
155 public function set_screen_option( $status, $option, $value ) {
156 return 'pll_lang_per_page' === $option || 'pll_strings_per_page' === $option ? $value : $status;
157 }
158
159 /**
160 * Manages the user input for the languages pages
161 *
162 * @since 1.9
163 *
164 * @param string $action
165 */
166 public function handle_actions( $action ) {
167 switch ( $action ) {
168 case 'add':
169 check_admin_referer( 'add-lang', '_wpnonce_add-lang' );
170 $errors = $this->model->add_language( $_POST );
171
172 if ( is_wp_error( $errors ) ) {
173 foreach ( $errors->get_error_messages() as $message ) {
174 add_settings_error( 'general', 'pll_add_language', $message );
175 }
176 } else {
177 add_settings_error( 'general', 'pll_languages_created', __( 'Language added.', 'polylang' ), 'updated' );
178 $locale = sanitize_text_field( wp_unslash( $_POST['locale'] ) ); // phpcs:ignore WordPress.Security
179
180 if ( 'en_US' !== $locale ) {
181 // Attempts to install the language pack
182 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
183 if ( ! wp_download_language_pack( $locale ) ) {
184 add_settings_error( 'general', 'pll_download_mo', __( 'The language was created, but the WordPress language file was not downloaded. Please install it manually.', 'polylang' ) );
185 }
186
187 // Force checking for themes and plugins translations updates
188 wp_clean_themes_cache();
189 wp_clean_plugins_cache();
190 }
191 }
192 self::redirect(); // To refresh the page ( possible thanks to the $_GET['noheader']=true )
193 break;
194
195 case 'delete':
196 check_admin_referer( 'delete-lang' );
197
198 if ( ! empty( $_GET['lang'] ) && $this->model->delete_language( (int) $_GET['lang'] ) ) {
199 add_settings_error( 'general', 'pll_languages_deleted', __( 'Language deleted.', 'polylang' ), 'updated' );
200 }
201
202 self::redirect(); // To refresh the page ( possible thanks to the $_GET['noheader']=true )
203 break;
204
205 case 'update':
206 check_admin_referer( 'add-lang', '_wpnonce_add-lang' );
207 $errors = $this->model->update_language( $_POST );
208
209 if ( is_wp_error( $errors ) ) {
210 foreach ( $errors->get_error_messages() as $message ) {
211 add_settings_error( 'general', 'pll_update_language', $message );
212 }
213 } else {
214 add_settings_error( 'general', 'pll_languages_updated', __( 'Language updated.', 'polylang' ), 'updated' );
215 }
216
217 self::redirect(); // To refresh the page ( possible thanks to the $_GET['noheader']=true )
218 break;
219
220 case 'default-lang':
221 check_admin_referer( 'default-lang' );
222
223 if ( $lang = $this->model->get_language( (int) $_GET['lang'] ) ) {
224 $this->model->update_default_lang( $lang->slug );
225 }
226
227 self::redirect(); // To refresh the page ( possible thanks to the $_GET['noheader']=true )
228 break;
229
230 case 'content-default-lang':
231 check_admin_referer( 'content-default-lang' );
232
233 if ( $nolang = $this->model->get_objects_with_no_lang() ) {
234 if ( ! empty( $nolang['posts'] ) ) {
235 $this->model->set_language_in_mass( 'post', $nolang['posts'], $this->options['default_lang'] );
236 }
237 if ( ! empty( $nolang['terms'] ) ) {
238 $this->model->set_language_in_mass( 'term', $nolang['terms'], $this->options['default_lang'] );
239 }
240 }
241
242 self::redirect(); // To refresh the page ( possible thanks to the $_GET['noheader']=true )
243 break;
244
245 case 'activate':
246 check_admin_referer( 'pll_activate' );
247 if ( isset( $_GET['module'] ) ) {
248 $module = sanitize_key( $_GET['module'] );
249 if ( isset( $this->modules[ $module ] ) ) {
250 $this->modules[ $module ]->activate();
251 }
252 }
253 self::redirect();
254 break;
255
256 case 'deactivate':
257 check_admin_referer( 'pll_deactivate' );
258 if ( isset( $_GET['module'] ) ) {
259 $module = sanitize_key( $_GET['module'] );
260 if ( isset( $this->modules[ $module ] ) ) {
261 $this->modules[ $module ]->deactivate();
262 }
263 }
264 self::redirect();
265 break;
266
267 default:
268 /**
269 * Fires when a non default action has been sent to Polylang settings
270 *
271 * @since 1.8
272 */
273 do_action( "mlang_action_$action" );
274 break;
275 }
276 }
277
278 /**
279 * Displays the 3 tabs pages: languages, strings translations, settings
280 * Also manages user input for these pages
281 *
282 * @since 0.1
283 */
284 public function languages_page() {
285 switch ( $this->active_tab ) {
286 case 'lang':
287 // Prepare the list table of languages
288 $list_table = new PLL_Table_Languages();
289 $list_table->prepare_items( $this->model->get_languages_list() );
290 break;
291
292 case 'strings':
293 $string_table = new PLL_Table_String( $this->model->get_languages_list() );
294 $string_table->prepare_items();
295 break;
296 }
297
298 // Handle user input
299 $action = isset( $_REQUEST['pll_action'] ) ? sanitize_key( $_REQUEST['pll_action'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
300 if ( 'edit' === $action && ! empty( $_GET['lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
301 $edit_lang = $this->model->get_language( (int) $_GET['lang'] ); // phpcs:ignore WordPress.Security.NonceVerification
302 } else {
303 $this->handle_actions( $action );
304 }
305
306 // Displays the page
307 include PLL_SETTINGS_INC . '/view-languages.php';
308 }
309
310 /**
311 * Enqueues scripts and styles
312 */
313 public function admin_enqueue_scripts() {
314 parent::admin_enqueue_scripts();
315
316 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
317
318 wp_enqueue_script( 'pll_admin', plugins_url( '/js/admin' . $suffix . '.js', POLYLANG_FILE ), array( 'jquery', 'wp-ajax-response', 'postbox', 'jquery-ui-selectmenu' ), POLYLANG_VERSION );
319 wp_localize_script( 'pll_admin', 'pll_flag_base_url', plugins_url( '/flags/', POLYLANG_FILE ) );
320
321 wp_enqueue_style( 'pll_selectmenu', plugins_url( '/css/selectmenu' . $suffix . '.css', POLYLANG_FILE ), array(), POLYLANG_VERSION );
322 }
323
324 /**
325 * Displays a notice when there are objects with no language assigned
326 *
327 * @since 1.8
328 */
329 public function notice_objects_with_no_lang() {
330 if ( ! empty( $this->options['default_lang'] ) && $this->model->get_objects_with_no_lang( 1 ) ) {
331 printf(
332 '<div class="error"><p>%s <a href="%s">%s</a></p></div>',
333 esc_html__( 'There are posts, pages, categories or tags without language.', 'polylang' ),
334 esc_url( wp_nonce_url( '?page=mlang&pll_action=content-default-lang&noheader=true', 'content-default-lang' ) ),
335 esc_html__( 'You can set them all to the default language.', 'polylang' )
336 );
337 }
338 }
339
340 /**
341 * Redirects to language page ( current active tab )
342 * saves error messages in a transient for reuse in redirected page
343 *
344 * @since 1.5
345 *
346 * @param array $args query arguments to add to the url
347 */
348 public static function redirect( $args = array() ) {
349 if ( $errors = get_settings_errors() ) {
350 set_transient( 'settings_errors', $errors, 30 );
351 $args['settings-updated'] = 1;
352 }
353 // Remove possible 'pll_action' and 'lang' query args from the referer before redirecting
354 wp_safe_redirect( add_query_arg( $args, remove_query_arg( array( 'pll_action', 'lang' ), wp_get_referer() ) ) );
355 exit;
356 }
357
358 /**
359 * Get the list of predefined languages
360 *
361 * @since 2.3
362 */
363 public function get_predefined_languages() {
364 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
365
366 $languages = include PLL_SETTINGS_INC . '/languages.php';
367 $translations = wp_get_available_translations();
368
369 // Keep only languages with existing WP language pack
370 // Unless the transient has expired and we don't have an internet connection to refresh it
371 if ( ! empty( $translations ) ) {
372 $translations['en_US'] = ''; // Languages packs don't include en_US
373 $languages = array_intersect_key( $languages, $translations );
374 }
375
376 /**
377 * Filter the list of predefined languages
378 *
379 * @since 1.7.10
380 * @since 2.3 The languages arrays use associative keys instead of numerical keys
381 * @see settings/languages.php
382 *
383 * @param array $languages
384 */
385 $languages = apply_filters( 'pll_predefined_languages', $languages );
386
387 // Keep only languages with all necessary informations
388 foreach ( $languages as $k => $lang ) {
389 if ( ! isset( $lang['code'], $lang['locale'], $lang['name'], $lang['dir'], $lang['flag'] ) ) {
390 unset( $languages[ $k ] );
391 }
392 }
393
394 return $languages;
395 }
396 }
397