PluginProbe
Polylang / 1.5
Polylang v1.5
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, at admin/settings.php

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