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

376 lines 13.6 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 ot 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 is it the best class for this?
291 * FIXME use language packs API coming with WP 3.7 instead (does not seem to work fully yet)
292 *
293 * @since 0.6
294 *
295 * @param string $locale locale to download
296 * @param bool $upgrade optional true if this is an upgrade, false if this is the first download, defaults to false
297 * @return bool true on success, false otherwise
298 */
299 static public function download_mo($locale, $upgrade = false) {
300 global $wp_version;
301 $mofile = WP_LANG_DIR."/$locale.mo";
302
303 // does file exists ?
304 if ((file_exists($mofile) && !$upgrade) || $locale == 'en_US')
305 return true;
306
307 // does language directory exists ?
308 if (!is_dir(WP_LANG_DIR)) {
309 if (!@mkdir(WP_LANG_DIR))
310 return false;
311 }
312
313 // will first look in tags/ (most languages) then in branches/ (only Greek ?)
314 $base = 'http://svn.automattic.com/wordpress-i18n/'.$locale;
315 $bases = array($base.'/tags/', $base.'/branches/');
316
317 foreach ($bases as $base) {
318 // get all the versions available in the subdirectory
319 $resp = wp_remote_get($base);
320 if (is_wp_error($resp) || 200 != $resp['response']['code'])
321 continue;
322
323 preg_match_all('#>([0-9\.]+)\/#', $resp['body'], $matches);
324 if (empty($matches[1]))
325 continue;
326
327 rsort($matches[1]); // sort from newest to oldest
328 $versions = $matches[1];
329
330 $newest = $upgrade ? $upgrade : $wp_version;
331 foreach ($versions as $key=>$version) {
332 // will not try to download a too recent mofile
333 if (version_compare($version, $newest, '>'))
334 unset($versions[$key]);
335 // will not download an older version if we are upgrading
336 if ($upgrade && version_compare($version, $wp_version, '<='))
337 unset($versions[$key]);
338 }
339
340 $versions = array_splice($versions, 0, 5); // reduce the number of versions to test to 5
341 $args = array('timeout' => 30, 'stream' => true);
342
343 // try to download the file
344 foreach ($versions as $version) {
345 $resp = wp_remote_get($base."$version/messages/$locale.mo", $args + array('filename' => $mofile));
346 if (is_wp_error($resp) || 200 != $resp['response']['code']) {
347 unlink($mofile); // otherwise we download a gzipped 404 page
348 continue;
349 }
350 // try to download ms and continents-cities files if exist (will not return false if failed)
351 // with new files introduced in WP 3.4
352 foreach (array('ms', 'continents-cities', 'admin', 'admin-network') as $file) {
353 $resp = wp_remote_get($base."$version/messages/$file-$locale.mo", $args + array('filename' => WP_LANG_DIR."/$file-$locale.mo"));
354 if (is_wp_error($resp) || 200 != $resp['response']['code'])
355 unlink(WP_LANG_DIR."/$file-$locale.mo");
356 }
357 // try to download theme files if exist (will not return false if failed)
358 // FIXME not updated when the theme is updated outside a core update
359 foreach (array('twentyten', 'twentyeleven', 'twentytwelve', 'twentythirteen', 'twentyfourteen') as $theme) {
360 if (!is_dir($theme_dir = get_theme_root()."/$theme/languages"))
361 continue; // the theme is not present
362
363 $resp = wp_remote_get($base."$version/messages/$theme/$locale.mo", $args + array('filename' => "$theme_dir/$locale.mo"));
364 if (is_wp_error($resp) || 200 != $resp['response']['code'])
365 unlink("$theme_dir/$locale.mo");
366 }
367 return true;
368 }
369 }
370
371 // we did not succeeded to download a file :(
372 add_settings_error('general', 'pll_download_mo', __('The language was created, but the WordPress language file was not downloaded. Please install it manually.', 'polylang'));
373 return false;
374 }
375 }
376