PluginProbe
Polylang / 1.4.4
Polylang v1.4.4
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.4.4, at admin/admin.php

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