PluginProbe
Polylang / 1.6
Polylang v1.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 / admin / admin.php

admin.php in Polylang 1.6, at admin/admin.php

375 lines 13.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * admin side controller
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 * settings_page => optional, reference to PLL_Settings object
12 * links => reference to PLL_Links object
13 * curlang => optional, current language used to filter admin content
14 * pref_lang => preferred language used as default when saving posts or terms
15 * filters => reference to PLL_Filters object
16 * filters_columns => reference to PLL_Admin_Filters_Columns object
17 * filters_post => reference to PLL_Admin_Filters_Post object
18 * filters_term => reference to PLL_Admin_filters_Term object
19 * nav_menu => reference to PLL_Admin_Nav_Menu object
20 * sync => reference to PLL_Admin_Sync object
21 * filters_media => optional, reference to PLL_Admin_Filters_Media object
22 *
23 * @since 1.2
24 */
25 class PLL_Admin extends PLL_Base {
26 public $curlang, $pref_lang;
27 public $settings_page, $filters, $filters_columns, $filters_post, $filters_term, $nav_menu, $sync, $filters_media;
28
29 /*
30 * loads the polylang text domain
31 * setups filters and action needed on all admin pages and on plugins page
32 *
33 * @since 1.2
34 *
35 * @param object $links_model
36 */
37 public function __construct(&$links_model) {
38 parent::__construct($links_model);
39
40 // plugin i18n, only needed for backend
41 load_plugin_textdomain('polylang', false, basename(POLYLANG_DIR).'/languages');
42
43 // adds the link to the languages panel in the wordpress admin menu
44 add_action('admin_menu', array(&$this, 'add_menus'));
45
46 // setup js scripts and css styles
47 add_action('admin_enqueue_scripts', array(&$this, 'admin_enqueue_scripts'));
48 add_action('admin_print_footer_scripts', array(&$this, 'admin_print_footer_scripts'));
49
50 // adds a 'settings' link in the plugins table
51 add_filter('plugin_action_links_' . POLYLANG_BASENAME, array(&$this, 'plugin_action_links'));
52 add_action('in_plugin_update_message-' . POLYLANG_BASENAME, array(&$this, 'plugin_update_message'), 10, 2);
53 }
54
55 /*
56 * setups filters and action needed on all admin pages and on plugins page
57 * loads the settings pages or the filters base on the request
58 *
59 * @since 1.2
60 *
61 * @param object $links_model
62 */
63 public function init() {
64 if (PLL_SETTINGS)
65 $this->settings_page = new PLL_Settings($this);
66
67 if (!$this->model->get_languages_list())
68 return;
69
70 $this->links = new PLL_Links($this);
71
72 // filter admin language for users
73 // we must not call user info before WordPress defines user roles in wp-settings.php
74 add_filter('setup_theme', array(&$this, 'init_user'));
75
76 // adds the languages in admin bar
77 add_action('admin_bar_menu', array(&$this, 'admin_bar_menu'), 100); // 100 determines the position
78
79 // setup filters for admin pages
80 if (!PLL_SETTINGS)
81 add_action('wp_loaded', array(&$this, 'add_filters'));
82 }
83
84 /*
85 * adds the link to the languages panel in the wordpress admin menu
86 *
87 * @since 0.1
88 */
89 public function add_menus() {
90 add_submenu_page('options-general.php', $title = __('Languages', 'polylang'), $title, 'manage_options', 'mlang',
91 PLL_SETTINGS ? array($this->settings_page, 'languages_page') : create_function('', ''));
92 }
93
94 /*
95 * setup js scripts & css styles (only on the relevant pages)
96 *
97 * @since 0.6
98 */
99 public function admin_enqueue_scripts() {
100 $screen = get_current_screen();
101 $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
102
103 // for each script:
104 // 0 => the pages on which to load the script
105 // 1 => the scripts it needs to work
106 // 2 => 1 if loaded even if languages have not been defined yet, 0 otherwise
107 // 3 => 1 if loaded in footer
108 // FIXME: check if I can load more scripts in footer
109 $scripts = array(
110 'admin' => array( array('settings_page_mlang'), array('jquery', 'wp-ajax-response', 'postbox'), 1 , 0),
111 'post' => array( array('post', 'media', 'async-upload', 'edit'), array('jquery', 'wp-ajax-response', 'inline-edit-post', 'post', 'jquery-ui-autocomplete'), 0 , 0),
112 'term' => array( array('edit-tags'), array('jquery', 'wp-ajax-response', 'jquery-ui-autocomplete'), 0, 1),
113 'user' => array( array('profile', 'user-edit'), array('jquery'), 0 , 0),
114 );
115
116 foreach ($scripts as $script => $v)
117 if (in_array($screen->base, $v[0]) && ($v[2] || $this->model->get_languages_list()))
118 wp_enqueue_script('pll_'.$script, POLYLANG_URL .'/js/'.$script.$suffix.'.js', $v[1], POLYLANG_VERSION, $v[3]);
119
120 wp_enqueue_style('polylang_admin', POLYLANG_URL .'/css/admin'.$suffix.'.css', array(), POLYLANG_VERSION);
121
122 // backward compatibility WP < 3.8
123 // don't load this for old versions
124 if (version_compare($GLOBALS['wp_version'], '3.8alpha' , '>='))
125 wp_enqueue_style('polylang_admin_mobi', POLYLANG_URL .'/css/admin-mobi'.$suffix.'.css', array(), POLYLANG_VERSION);
126 }
127
128 /*
129 * sets pll_ajax_backend on all backend ajax request
130 *
131 * @since 1.4
132 */
133 public function admin_print_footer_scripts() {
134 global $post_ID;
135 $params = array('pll_ajax_backend' => 1);
136 if (!empty($post_ID))
137 $params = array_merge($params, array('pll_post_id' => $post_ID));
138
139 $str = $arr = '';
140 foreach ($params as $k => $v) {
141 $str .= $k . '=' . $v . '&';
142 $arr .= (empty($arr) ? '' : ', ') . $k . ': ' . $v;
143 }
144 ?>
145 <script type="text/javascript">
146 if (typeof jQuery != 'undefined') {
147 (function($){
148 $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
149 if (typeof options.data == 'string') {
150 options.data = '<?php echo $str;?>'+options.data;
151 }
152 else {
153 options.data = $.extend(options.data, {<?php echo $arr;?>});
154 }
155 });
156 })(jQuery)
157 }
158 </script><?php
159
160 }
161
162 /*
163 * adds a 'settings' link in the plugins table
164 *
165 * @since 0.1
166 *
167 * @param array $links list of links associated to the plugin
168 * @return array modified list of links
169 */
170 public function plugin_action_links($links) {
171 array_unshift($links, '<a href="admin.php?page=mlang">' . __('Settings', 'polylang') . '</a>');
172 return $links;
173 }
174
175 /*
176 * adds the upgrade notice in plugins table
177 *
178 * @since 1.1.6
179 *
180 * @param array $plugin_data not used
181 * @param object $r plugin update data
182 */
183 function plugin_update_message($plugin_data, $r) {
184 if (isset($r->upgrade_notice))
185 printf('<p style="margin: 3px 0 0 0; border-top: 1px solid #ddd; padding-top: 3px">%s</p>', $r->upgrade_notice);
186 }
187
188 /*
189 * defines the backend language and the admin language filter based on user preferences
190 *
191 * @since 1.2.3
192 */
193 public function init_user() {
194 // backend locale
195 add_filter('locale', array(&$this, 'get_locale'));
196
197 // language for admin language filter: may be empty
198 // $_GET['lang'] is numeric when editing a language, not when selecting a new language in the filter
199 if (!defined('DOING_AJAX') && !empty($_GET['lang']) && !is_numeric($_GET['lang']) && current_user_can('edit_user', $user_id = get_current_user_id()))
200 update_user_meta($user_id, 'pll_filter_content', ($lang = $this->model->get_language($_GET['lang'])) ? $lang->slug : '');
201
202 $this->curlang = $this->model->get_language(get_user_meta(get_current_user_id(), 'pll_filter_content', true));
203
204 // set preferred language for use when saving posts and terms: must not be empty
205 $this->pref_lang = empty($this->curlang) ? $this->model->get_language($this->options['default_lang']) : $this->curlang;
206 $this->pref_lang = apply_filters('pll_admin_preferred_language', $this->pref_lang);
207
208 // inform that the admin language has been set
209 // only if the admin language is one of the Polylang defined language
210 if ($curlang = $this->model->get_language(get_locale())) {
211 $GLOBALS['text_direction'] = $curlang->is_rtl ? 'rtl' : 'ltr'; // force text direction according to language setting
212 do_action('pll_language_defined', $curlang->slug, $curlang);
213 }
214 else
215 do_action('pll_no_language_defined'); // to load overriden textdomains
216 }
217
218 /*
219 * get the locale based on user preference
220 *
221 * @since 0.4
222 *
223 * @param string $locale
224 * @return string modified locale
225 */
226 public function get_locale($locale) {
227 return ($loc = get_user_meta(get_current_user_id(), 'user_lang', 'true')) ? $loc : $locale;
228 }
229
230 /*
231 * setup filters for admin pages
232 *
233 * @since 1.2
234 */
235 public function add_filters() {
236 // all these are separated just for convenience and maintainability
237 $classes = array('Filters', 'Filters_Columns', 'Filters_Post', 'Filters_Term', 'Nav_Menu', 'Sync');
238
239 // don't load media filters if option is disabled or if user has no right
240 if ($this->options['media_support'] && ($obj = get_post_type_object('attachment')) && (current_user_can($obj->cap->edit_posts) || current_user_can($obj->cap->create_posts)))
241 $classes[] = 'Filters_Media';
242
243 foreach ($classes as $class) {
244 $obj = strtolower($class);
245 $class = apply_filters('pll_' . $obj, 'PLL_Admin_' . $class);
246 $this->$obj = new $class($this);
247 }
248 }
249
250 /*
251 * adds the languages list in admin bar for the admin languages filter
252 *
253 * @since 0.9
254 *
255 * @param object $wp_admin_bar
256 */
257 public function admin_bar_menu($wp_admin_bar) {
258 $url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
259
260 $all_item = (object) array(
261 'slug' => 'all',
262 'name' => __('Show all languages', 'polylang'),
263 'flag' => '<span class="ab-icon"></span>'
264 );
265
266 $selected = empty($this->curlang) ? $all_item : $this->curlang;
267
268 $wp_admin_bar->add_menu(array(
269 'id' => 'languages',
270 'title' => $selected->flag . '<span class="ab-label">'. esc_html($selected->name) . '</span>',
271 'meta' => array('title' => __('Filters content by language', 'polylang')),
272 ));
273
274 foreach (array_merge(array($all_item), $this->model->get_languages_list()) as $lang) {
275 if ($selected->slug == $lang->slug)
276 continue;
277
278 $img = empty($lang->flag) ? '' : (false !== strpos($lang->flag, 'img') ? $lang->flag . '&nbsp;' : $lang->flag);
279
280 $wp_admin_bar->add_menu(array(
281 'parent' => 'languages',
282 'id' => $lang->slug,
283 'title' => $lang->flag . esc_html($lang->name),
284 'href' => esc_url(add_query_arg('lang', $lang->slug, remove_query_arg('paged',$url))),
285 ));
286 }
287 }
288 /*
289 * downloads mofiles from http://svn.automattic.com/wordpress-i18n/
290 * FIXME backward compatibility WP < 4.0
291 *
292 * @since 0.6
293 *
294 * @param string $locale locale to download
295 * @param bool $upgrade optional true if this is an upgrade, false if this is the first download, defaults to false
296 * @return bool true on success, false otherwise
297 */
298 static public function download_mo($locale, $upgrade = false) {
299 global $wp_version;
300 $mofile = WP_LANG_DIR."/$locale.mo";
301
302 // does file exists ?
303 if ((file_exists($mofile) && !$upgrade) || $locale == 'en_US')
304 return true;
305
306 // does language directory exists ?
307 if (!is_dir(WP_LANG_DIR)) {
308 if (!@mkdir(WP_LANG_DIR))
309 return false;
310 }
311
312 // will first look in tags/ (most languages) then in branches/ (only Greek ?)
313 $base = 'http://svn.automattic.com/wordpress-i18n/'.$locale;
314 $bases = array($base.'/tags/', $base.'/branches/');
315
316 foreach ($bases as $base) {
317 // get all the versions available in the subdirectory
318 $resp = wp_remote_get($base);
319 if (is_wp_error($resp) || 200 != $resp['response']['code'])
320 continue;
321
322 preg_match_all('#>([0-9\.]+)\/#', $resp['body'], $matches);
323 if (empty($matches[1]))
324 continue;
325
326 rsort($matches[1]); // sort from newest to oldest
327 $versions = $matches[1];
328
329 $newest = $upgrade ? $upgrade : $wp_version;
330 foreach ($versions as $key=>$version) {
331 // will not try to download a too recent mofile
332 if (version_compare($version, $newest, '>'))
333 unset($versions[$key]);
334 // will not download an older version if we are upgrading
335 if ($upgrade && version_compare($version, $wp_version, '<='))
336 unset($versions[$key]);
337 }
338
339 $versions = array_splice($versions, 0, 5); // reduce the number of versions to test to 5
340 $args = array('timeout' => 30, 'stream' => true);
341
342 // try to download the file
343 foreach ($versions as $version) {
344 $resp = wp_remote_get($base."$version/messages/$locale.mo", $args + array('filename' => $mofile));
345 if (is_wp_error($resp) || 200 != $resp['response']['code']) {
346 unlink($mofile); // otherwise we download a gzipped 404 page
347 continue;
348 }
349 // try to download ms and continents-cities files if exist (will not return false if failed)
350 // with new files introduced in WP 3.4
351 foreach (array('ms', 'continents-cities', 'admin', 'admin-network') as $file) {
352 $resp = wp_remote_get($base."$version/messages/$file-$locale.mo", $args + array('filename' => WP_LANG_DIR."/$file-$locale.mo"));
353 if (is_wp_error($resp) || 200 != $resp['response']['code'])
354 unlink(WP_LANG_DIR."/$file-$locale.mo");
355 }
356 // try to download theme files if exist (will not return false if failed)
357 // FIXME not updated when the theme is updated outside a core update
358 foreach (array('twentyten', 'twentyeleven', 'twentytwelve', 'twentythirteen', 'twentyfourteen') as $theme) {
359 if (!is_dir($theme_dir = get_theme_root()."/$theme/languages"))
360 continue; // the theme is not present
361
362 $resp = wp_remote_get($base."$version/messages/$theme/$locale.mo", $args + array('filename' => "$theme_dir/$locale.mo"));
363 if (is_wp_error($resp) || 200 != $resp['response']['code'])
364 unlink("$theme_dir/$locale.mo");
365 }
366 return true;
367 }
368 }
369
370 // we did not succeeded to download a file :(
371 add_settings_error('general', 'pll_download_mo', __('The language was created, but the WordPress language file was not downloaded. Please install it manually.', 'polylang'));
372 return false;
373 }
374 }
375