PluginProbe
Polylang / 1.5.2
Polylang v1.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
polylang / admin / settings.php

settings.php in Polylang 1.5.2, at admin/settings.php

379 lines 12.9 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 *
6 * @since 1.2
7 */
8 class PLL_Settings {
9 public $links_model, $model, $options;
10 protected $active_tab, $strings = array(); // strings to translate
11
12 /*
13 * constructor
14 *
15 * @since 1.2
16 *
17 * @param object $polylang
18 */
19 public function __construct(&$polylang) {
20 $this->links_model = &$polylang->links_model;
21 $this->model = &$polylang->model;
22 $this->options = &$polylang->options;
23
24 $this->active_tab = !empty($_GET['tab']) ? $_GET['tab'] : 'lang';
25
26 // adds screen options and the about box in the languages admin panel
27 add_action('load-settings_page_mlang', array(&$this, 'load_page'));
28
29 // saves per-page value in screen option
30 add_filter('set-screen-option', create_function('$s, $o, $v', 'return $v;'), 10, 3);
31 }
32
33 /*
34 * adds screen options and the about box in the languages admin panel
35 *
36 * @since 0.9.5
37 */
38 public function load_page() {
39 // test of $this->active_tab avoids displaying the automatically generated screen options on other tabs
40 switch ($this->active_tab) {
41 case 'lang':
42 if (!defined('PLL_DISPLAY_ABOUT') || PLL_DISPLAY_ABOUT) {
43 add_meta_box(
44 'pll_about_box',
45 __('About Polylang', 'polylang'),
46 create_function('', "include(PLL_ADMIN_INC.'/view-about.php');"),
47 'settings_page_mlang',
48 'normal'
49 );
50 }
51
52 add_screen_option('per_page', array(
53 'label' => __('Languages', 'polylang'),
54 'default' => 10,
55 'option' => 'pll_lang_per_page'
56 ));
57 break;
58
59 case 'strings':
60 add_screen_option('per_page', array(
61 'label' => __('Strings translations', 'polylang'),
62 'default' => 10,
63 'option' => 'pll_strings_per_page'
64 ));
65 break;
66
67 default:
68 break;
69 }
70 }
71
72 /*
73 * diplays the 3 tabs pages: languages, strings translations, settings
74 * also manages user input for these pages
75 *
76 * @since 0.1
77 */
78 public function languages_page() {
79 // prepare the list of tabs
80 $tabs = array('lang' => __('Languages','polylang'));
81
82 // only if at least one language has been created
83 if ($listlanguages = $this->model->get_languages_list()) {
84 $tabs['strings'] = __('Strings translation','polylang');
85 $tabs['settings'] = __('Settings', 'polylang');
86 }
87
88 $tabs = apply_filters('pll_settings_tabs', $tabs);
89
90 switch($this->active_tab) {
91 case 'lang':
92 // prepare the list table of languages
93 $list_table = new PLL_Table_Languages();
94 $list_table->prepare_items($listlanguages);
95 break;
96
97 case 'strings':
98 // get the strings to translate
99 $data = $this->get_strings();
100
101 $selected = empty($_REQUEST['group']) ? -1 : $_REQUEST['group'];
102 foreach ($data as $key=>$row) {
103 $groups[] = $row['context']; // get the groups
104
105 // filter for search string
106 if (($selected !=-1 && $row['context'] != $selected) || (!empty($_REQUEST['s']) && stripos($row['name'], $_REQUEST['s']) === false && stripos($row['string'], $_REQUEST['s']) === false))
107 unset ($data[$key]);
108 }
109
110 $groups = array_unique($groups);
111
112 // load translations
113 foreach ($listlanguages as $language) {
114 // filters by language if requested
115 if (($lg = get_user_meta(get_current_user_id(), 'pll_filter_content', true)) && $language->slug != $lg)
116 continue;
117
118 $mo = new PLL_MO();
119 $mo->import_from_db($language);
120 foreach ($data as $key=>$row) {
121 $data[$key]['translations'][$language->name] = $mo->translate($row['string']);
122 $data[$key]['row'] = $key; // store the row number for convenience
123 }
124 }
125
126 $string_table = new PLL_Table_String($groups, $selected);
127 $string_table->prepare_items($data);
128 break;
129
130 case 'settings':
131 $post_types = get_post_types(array('public' => true, '_builtin' => false));
132 $post_types = array_diff($post_types, get_post_types(array('_pll' => true)));
133 $post_types = array_unique(apply_filters('pll_get_post_types', $post_types, true));
134
135 $taxonomies = get_taxonomies(array('public' => true, '_builtin' => false));
136 $taxonomies = array_diff($taxonomies, get_taxonomies(array('_pll' => true)));
137 $taxonomies = array_unique(apply_filters('pll_get_taxonomies', $taxonomies , true));
138 break;
139
140 default:
141 break;
142 }
143
144 $using_permalinks = $GLOBALS['wp_rewrite']->using_permalinks();
145
146 $action = isset($_REQUEST['pll_action']) ? $_REQUEST['pll_action'] : '';
147
148 switch ($action) {
149 case 'add':
150 check_admin_referer( 'add-lang', '_wpnonce_add-lang' );
151
152 if ($this->model->add_language($_POST))
153 PLL_Admin::download_mo($_POST['locale']);
154
155 $this->redirect(); // to refresh the page (possible thanks to the $_GET['noheader']=true)
156 break;
157
158 case 'delete':
159 check_admin_referer('delete-lang');
160
161 if (!empty($_GET['lang']))
162 $this->model->delete_language((int) $_GET['lang']);
163
164 $this->redirect(); // to refresh the page (possible thanks to the $_GET['noheader']=true)
165 break;
166
167 case 'edit':
168 if (!empty($_GET['lang']))
169 $edit_lang = $this->model->get_language((int) $_GET['lang']);
170 break;
171
172 case 'update':
173 check_admin_referer( 'add-lang', '_wpnonce_add-lang' );
174
175 $error = $this->model->update_language($_POST);
176
177 $this->redirect(); // to refresh the page (possible thanks to the $_GET['noheader']=true)
178 break;
179
180 case 'string-translation':
181 if (!empty($_REQUEST['submit'])) {
182 check_admin_referer( 'string-translation', '_wpnonce_string-translation' );
183 $strings = $this->get_strings();
184
185 foreach ($this->model->get_languages_list() as $language) {
186 if(empty($_POST['translation'][$language->name])) // in case the language filter is active (thanks to John P. Bloch)
187 continue;
188
189 $mo = new PLL_MO();
190 $mo->import_from_db($language);
191
192 foreach ($_POST['translation'][$language->name] as $key=>$translation)
193 $mo->add_entry($mo->make_entry($strings[$key]['string'], stripslashes($translation)));
194
195 // clean database (removes all strings which were registered some day but are no more)
196 if (!empty($_POST['clean'])) {
197 $new_mo = new PLL_MO();
198
199 foreach ($strings as $string)
200 $new_mo->add_entry($mo->make_entry($string['string'], $mo->translate($string['string'])));
201 }
202
203 isset($new_mo) ? $new_mo->export_to_db($language) : $mo->export_to_db($language);
204 }
205 add_settings_error('general', 'pll_strings_translations_updated', __('Translations updated.', 'polylang'), 'updated');
206 }
207
208 do_action('pll_save_strings_translations');
209
210 // unregisters strings registered through WPML API
211 if ($string_table->current_action() == 'delete' && !empty($_REQUEST['strings']) && function_exists('icl_unregister_string')) {
212 check_admin_referer( 'string-translation', '_wpnonce_string-translation' );
213 $strings = $this->get_strings();
214
215 foreach ($_REQUEST['strings'] as $key)
216 icl_unregister_string($strings[$key]['context'], $strings[$key]['name']);
217 }
218
219 // to refresh the page (possible thanks to the $_GET['noheader']=true)
220 $this->redirect(array_intersect_key($_REQUEST, array_flip(array('s', 'paged', 'group'))));
221 break;
222
223 case 'options':
224 check_admin_referer( 'options-lang', '_wpnonce_options-lang' );
225
226 $this->options['default_lang'] = sanitize_title($_POST['default_lang']); // we have slug as value
227
228 foreach(array('force_lang', 'rewrite') as $key)
229 $this->options[$key] = isset($_POST[$key]) ? (int) $_POST[$key] : 0;
230
231 // FIXME : TODO error message if not a valid url
232 if (3 == $this->options['force_lang'] && isset($_POST['domains']) && is_array($_POST['domains'])) {
233 foreach ($_POST['domains'] as $key => $domain) {
234 $this->options['domains'][$key] = esc_url_raw(trim($domain));
235 }
236 $this->options['domains'][$this->options['default_lang']] = get_option('home');
237 }
238
239 foreach (array('browser', 'hide_default', 'redirect_lang', 'media_support') as $key)
240 $this->options[$key] = isset($_POST[$key]) ? 1 : 0;
241
242 if (3 == $this->options['force_lang'])
243 $this->options['browser'] = $this->options['hide_default'] = 0;
244
245 foreach (array('sync', 'post_types', 'taxonomies') as $key)
246 $this->options[$key] = empty($_POST[$key]) ? array() : array_keys($_POST[$key], 1);
247
248 update_option('polylang', $this->options);
249
250 // refresh rewrite rules in case rewrite, hide_default, post types or taxonomies options have been modified
251 // it seems useless to refresh permastruct here
252 flush_rewrite_rules();
253
254 // refresh language cache in case home urls have been modified
255 $this->model->clean_languages_cache();
256
257 // fills existing posts & terms with default language
258 if (isset($_POST['fill_languages']) && $nolang = $this->model->get_objects_with_no_lang()) {
259 if (!empty($nolang['posts']))
260 $this->model->set_language_in_mass('post', $nolang['posts'], $this->options['default_lang']);
261 if (!empty($nolang['terms']))
262 $this->model->set_language_in_mass('term', $nolang['terms'], $this->options['default_lang']);
263 }
264
265 add_settings_error('general', 'settings_updated', __('Settings saved.'), 'updated');
266 $this->redirect();
267 break;
268
269 default:
270 break;
271 }
272
273 // displays the page
274 include(PLL_ADMIN_INC.'/view-languages.php');
275 }
276
277 /*
278 * register strings for translation making sure it is not duplicate or empty
279 *
280 * @since 0.6
281 *
282 * @param string $name a unique name for the string
283 * @param string $string the string to register
284 * @param string $context optional the group in which the string is registered, defaults to 'polylang'
285 * @param bool $multiline optional wether the string table should display a multiline textarea or a single line input, defaults to single line
286 */
287 public function register_string($name, $string, $context = 'polylang', $multiline = false) {
288 // backward compatibility with Polylang older than 1.1
289 if (is_bool($context)) {
290 $multiline = $context;
291 $context = 'polylang';
292 }
293
294 $to_register = compact('name', 'string', 'context', 'multiline');
295 if (!in_array($to_register, $this->strings) && $to_register['string'])
296 $this->strings[] = $to_register;
297 }
298
299 /*
300 * get registered strings
301 *
302 * @since 0.6.1
303 *
304 * @return array list of all registered strings
305 */
306 public function &get_strings() {
307 // WP strings
308 $this->register_string(__('Site Title'), get_option('blogname'), 'WordPress');
309 $this->register_string(__('Tagline'), get_option('blogdescription'), 'WordPress');
310 $this->register_string(__('Date Format'), get_option('date_format'), 'WordPress');
311 $this->register_string(__('Time Format'), get_option('time_format'), 'WordPress');
312
313 // widgets titles
314 global $wp_registered_widgets;
315 $sidebars = wp_get_sidebars_widgets();
316 foreach ($sidebars as $sidebar => $widgets) {
317 if ($sidebar == 'wp_inactive_widgets' || empty($widgets))
318 continue;
319
320 foreach ($widgets as $widget) {
321 // nothing can be done if the widget is created using pre WP2.8 API :(
322 // there is no object, so we can't access it to get the widget options
323 if (!isset($wp_registered_widgets[$widget]['callback'][0]) || !is_object($wp_registered_widgets[$widget]['callback'][0]) || !method_exists($wp_registered_widgets[$widget]['callback'][0], 'get_settings'))
324 continue;
325
326 $widget_settings = $wp_registered_widgets[$widget]['callback'][0]->get_settings();
327 $number = $wp_registered_widgets[$widget]['params'][0]['number'];
328 // don't enable widget title translation if the widget is visible in only one language or if there is no title
329 if (empty($widget_settings[$number]['pll_lang']) && isset($widget_settings[$number]['title']) && $title = $widget_settings[$number]['title'])
330 $this->register_string(__('Widget title', 'polylang'), $title, 'Widget');
331 }
332 }
333
334 // allow plugins to modify our list of strings, mainly for use by our PLL_WPML_Compat class
335 $this->strings = apply_filters('pll_get_strings', $this->strings);
336 return $this->strings;
337 }
338
339 /*
340 * list the post metas to synchronize
341 *
342 * @since 1.0
343 *
344 * @return array
345 */
346 static public function list_metas_to_sync() {
347 return array(
348 'taxonomies' => __('Taxonomies', 'polylang'),
349 'post_meta' => __('Custom fields', 'polylang'),
350 'comment_status' => __('Comment status', 'polylang'),
351 'ping_status' => __('Ping status', 'polylang'),
352 'sticky_posts' => __('Sticky posts', 'polylang'),
353 'post_date' => __('Published date', 'polylang'),
354 'post_format' => __('Post format', 'polylang'),
355 'post_parent' => __('Page parent', 'polylang'),
356 '_wp_page_template' => __('Page template', 'polylang'),
357 'menu_order' => __('Page order', 'polylang'),
358 '_thumbnail_id' => __('Featured image', 'polylang'),
359 );
360 }
361
362 /*
363 * redirects to language page (current active tab)
364 * saves error messages in a transient for reuse in redirected page
365 *
366 * @since 1.5
367 *
368 * @param array $args query arguments to add to the url
369 */
370 protected function redirect($args = array()) {
371 if ($errors = get_settings_errors()) {
372 set_transient('settings_errors', $errors, 30);
373 $args['settings-updated'] = 1;
374 }
375 wp_redirect(add_query_arg($args, wp_get_referer() ));
376 exit;
377 }
378 }
379