PluginProbe
Polylang / 2.0.8
Polylang v2.0.8
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-base.php

admin-base.php in Polylang 2.0.8, at admin/admin-base.php

327 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Base class for both admin
5 *
6 * @since 1.8
7 */
8 class PLL_Admin_Base extends PLL_Base {
9 public $filter_lang, $curlang, $pref_lang;
10
11 /**
12 * Loads the polylang text domain
13 * Setups actions needed on all admin pages
14 *
15 * @since 1.8
16 *
17 * @param object $links_model
18 */
19 public function __construct( &$links_model ) {
20 parent::__construct( $links_model );
21
22 // Plugin i18n, only needed for backend
23 load_plugin_textdomain( 'polylang', false, basename( POLYLANG_DIR ).'/languages' );
24
25 // Adds the link to the languages panel in the WordPress admin menu
26 add_action( 'admin_menu', array( $this, 'add_menus' ) );
27
28 // Setup js scripts and css styles
29 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
30 add_action( 'admin_print_footer_scripts', array( $this, 'admin_print_footer_scripts' ) );
31
32 // Lingotek
33 if ( ! defined( 'PLL_LINGOTEK_AD' ) || PLL_LINGOTEK_AD ) {
34 require_once( POLYLANG_DIR . '/lingotek/lingotek.php' );
35 }
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 ( ! $this->model->get_languages_list() ) {
48 return;
49 }
50
51 $this->links = new PLL_Admin_Links( $this ); // FIXME needed here ?
52 $this->static_pages = new PLL_Admin_Static_Pages( $this ); // FIXME needed here ?
53 $this->filters_links = new PLL_Filters_Links( $this ); // FIXME needed here ?
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 add_filter( 'request', array( $this, 'request' ) );
59
60 // Adds the languages in admin bar
61 add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 100 ); // 100 determines the position
62 }
63
64 /**
65 * Adds the link to the languages panel in the WordPress admin menu
66 *
67 * @since 0.1
68 */
69 public function add_menus() {
70 add_submenu_page( 'options-general.php', $title = __( 'Languages', 'polylang' ), $title, 'manage_options', 'mlang', '__return_null' );
71 }
72
73 /**
74 * Setup js scripts & css styles ( only on the relevant pages )
75 *
76 * @since 0.6
77 */
78 public function admin_enqueue_scripts() {
79 $screen = get_current_screen();
80 if ( empty( $screen ) ) {
81 return;
82 }
83
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 'post' => array( array( 'post', 'media', 'async-upload', 'edit' ), array( 'jquery', 'wp-ajax-response', 'post', 'jquery-ui-autocomplete' ), 0 , 1 ),
94 'media' => array( array( 'upload' ), array( 'jquery' ), 0 , 1 ),
95 'term' => array( array( 'edit-tags', 'term' ), array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), 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 }
104
105 wp_enqueue_style( 'polylang_admin', POLYLANG_URL . '/css/admin' . $suffix . '.css', array(), POLYLANG_VERSION );
106 }
107
108 /**
109 * Sets pll_ajax_backend on all backend ajax request
110 * The final goal is to detect if an ajax request is made on admin or frontend
111 *
112 * Takes care to various situations:
113 * when the ajax request has no options.data thanks to ScreenfeedFr
114 * see: https://wordpress.org/support/topic/ajaxprefilter-may-not-work-as-expected
115 * when options.data is a json string
116 * see: https://wordpress.org/support/topic/polylang-breaking-third-party-ajax-requests-on-admin-panels
117 * when options.data is an empty string (GET request with the method 'load')
118 * see: https://wordpress.org/support/topic/invalid-url-during-wordpress-new-dashboard-widget-operation
119 *
120 * @since 1.4
121 */
122 public function admin_print_footer_scripts() {
123 global $post_ID;
124
125 $params = array( 'pll_ajax_backend' => 1 );
126 if ( ! empty( $post_ID ) ) {
127 $params = array_merge( $params, array( 'pll_post_id' => (int) $post_ID ) );
128 }
129
130 $str = http_build_query( $params );
131 $arr = json_encode( $params );
132 ?>
133 <script type="text/javascript">
134 if (typeof jQuery != 'undefined') {
135 (function($){
136 $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
137 if ( -1 != options.url.indexOf( ajaxurl ) ) {
138 if ( 'undefined' === typeof options.data ) {
139 options.data = ( 'get' === options.type.toLowerCase() ) ? '<?php echo $str;?>' : <?php echo $arr;?>;
140 } else {
141 if ( 'string' === typeof options.data ) {
142 if ( '' === options.data && 'get' === options.type.toLowerCase() ) {
143 options.url = options.url+'&<?php echo $str;?>';
144 } else {
145 try {
146 o = $.parseJSON(options.data);
147 o = $.extend(o, <?php echo $arr;?>);
148 options.data = JSON.stringify(o);
149 }
150 catch(e) {
151 options.data = '<?php echo $str;?>&'+options.data;
152 }
153 }
154 } else {
155 options.data = $.extend(options.data, <?php echo $arr;?>);
156 }
157 }
158 }
159 });
160 })(jQuery)
161 }
162 </script><?php
163 }
164
165 /**
166 * Sets the admin current language, used to filter the content
167 *
168 * @since 2.0
169 */
170 public function set_current_language() {
171 $this->curlang = $this->filter_lang;
172
173 // Edit Post
174 if ( isset( $_REQUEST['pll_post_id'] ) && $lang = $this->model->post->get_language( (int) $_REQUEST['pll_post_id'] ) ) {
175 $this->curlang = $lang;
176 } elseif ( 'post.php' === $GLOBALS['pagenow'] && isset( $_GET['post'] ) && is_numeric( $_GET['post'] ) && $lang = $this->model->post->get_language( (int) $_GET['post'] ) ) {
177 $this->curlang = $lang;
178 } elseif ( 'post-new.php' === $GLOBALS['pagenow'] && ( empty( $_GET['post_type'] ) || $this->model->is_translated_post_type( $_GET['post_type'] ) ) ) {
179 $this->curlang = empty( $_GET['new_lang'] ) ? $this->pref_lang : $this->model->get_language( $_GET['new_lang'] );
180 }
181
182 // Edit Term
183 // FIXME 'edit-tags.php' for backward compatibility with WP < 4.5
184 elseif ( in_array( $GLOBALS['pagenow'], array( 'edit-tags.php', 'term.php' ) ) && isset( $_GET['tag_ID'] ) && $lang = $this->model->term->get_language( (int) $_GET['tag_ID'] ) ) {
185 $this->curlang = $lang;
186 } elseif ( 'edit-tags.php' === $GLOBALS['pagenow'] && isset( $_GET['taxonomy'] ) && $this->model->is_translated_taxonomy( $_GET['taxonomy'] ) ) {
187 if ( ! empty( $_GET['new_lang'] ) ) {
188 $this->curlang = $this->model->get_language( $_GET['new_lang'] );
189 } elseif ( empty( $this->curlang ) ) {
190 $this->curlang = $this->pref_lang;
191 }
192 }
193
194 // Ajax
195 if ( defined( 'DOING_AJAX' ) && DOING_AJAX && ! empty( $_REQUEST['lang'] ) ) {
196 $this->curlang = $this->model->get_language( $_REQUEST['lang'] );
197 }
198 }
199
200 /**
201 * Defines the backend language and the admin language filter based on user preferences
202 *
203 * @since 1.2.3
204 */
205 public function init_user() {
206 // Backend locale
207 // FIXME: Backward compatibility with WP < 4.7
208 if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
209 add_filter( 'locale', array( $this, 'get_locale' ) );
210 }
211
212 // Language for admin language filter: may be empty
213 // $_GET['lang'] is numeric when editing a language, not when selecting a new language in the filter
214 if ( ! defined( 'DOING_AJAX' ) && ! empty( $_GET['lang'] ) && ! is_numeric( $_GET['lang'] ) && current_user_can( 'edit_user', $user_id = get_current_user_id() ) ) {
215 update_user_meta( $user_id, 'pll_filter_content', ( $lang = $this->model->get_language( $_GET['lang'] ) ) ? $lang->slug : '' );
216 }
217
218 $this->filter_lang = $this->model->get_language( get_user_meta( get_current_user_id(), 'pll_filter_content', true ) );
219
220 // Set preferred language for use when saving posts and terms: must not be empty
221 $this->pref_lang = empty( $this->filter_lang ) ? $this->model->get_language( $this->options['default_lang'] ) : $this->filter_lang;
222
223 /**
224 * Filter the preferred language on amin side
225 * The preferred language is used for example to determine the language of a new post
226 *
227 * @since 1.2.3
228 *
229 * @param object $pref_lang preferred language
230 */
231 $this->pref_lang = apply_filters( 'pll_admin_preferred_language', $this->pref_lang );
232
233 $this->set_current_language();
234
235 // Inform that the admin language has been set
236 // Only if the admin language is one of the Polylang defined language
237 if ( $curlang = $this->model->get_language( get_locale() ) ) {
238 // FIXME: Backward compatibility with WP < 4.7
239 if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
240 $GLOBALS['text_direction'] = $curlang->is_rtl ? 'rtl' : 'ltr'; // force text direction according to language setting
241 }
242
243 /** This action is documented in frontend/choose-lang.php */
244 do_action( 'pll_language_defined', $curlang->slug, $curlang );
245 } else {
246 /** This action is documented in include/class-polylang.php */
247 do_action( 'pll_no_language_defined' ); // to load overriden textdomains
248 }
249 }
250
251 /**
252 * Avoids parsing a tax query when all languages are requested
253 * Fixes https://wordpress.org/support/topic/notice-undefined-offset-0-in-wp-includesqueryphp-on-line-3877 introduced in WP 4.1
254 * @see the suggestion of @boonebgorges, https://core.trac.wordpress.org/ticket/31246
255 *
256 * @since 1.6.5
257 *
258 * @param array $qvars
259 * @return array
260 */
261 public function request( $qvars ) {
262 if ( isset( $qvars['lang'] ) && 'all' === $qvars['lang'] ) {
263 unset( $qvars['lang'] );
264 }
265
266 return $qvars;
267 }
268
269 /**
270 * Get the locale based on user preference
271 * FIXME: Backward compatibility with WP < 4.7
272 *
273 * @since 0.4
274 *
275 * @param string $locale
276 * @return string modified locale
277 */
278 public function get_locale( $locale ) {
279 return ( $loc = get_user_meta( get_current_user_id(), 'locale', 'true' ) ) ? $loc : $locale;
280 }
281
282 /**
283 * Adds the languages list in admin bar for the admin languages filter
284 *
285 * @since 0.9
286 *
287 * @param object $wp_admin_bar
288 */
289 public function admin_bar_menu( $wp_admin_bar ) {
290 $url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
291
292 $all_item = (object) array(
293 'slug' => 'all',
294 'name' => __( 'Show all languages', 'polylang' ),
295 'flag' => '<span class="ab-icon"></span>',
296 );
297
298 $selected = empty( $this->filter_lang ) ? $all_item : $this->filter_lang;
299
300 $title = sprintf(
301 '<span class="ab-label"%s>%s</span>',
302 'all' === $selected->slug ? '' : sprintf( ' lang="%s"', esc_attr( $selected->get_locale( 'display' ) ) ),
303 esc_html( $selected->name )
304 );
305
306 $wp_admin_bar->add_menu( array(
307 'id' => 'languages',
308 'title' => $selected->flag . $title,
309 'meta' => array( 'title' => __( 'Filters content by language', 'polylang' ) ),
310 ) );
311
312 foreach ( array_merge( array( $all_item ), $this->model->get_languages_list() ) as $lang ) {
313 if ( $selected->slug === $lang->slug ) {
314 continue;
315 }
316
317 $wp_admin_bar->add_menu( array(
318 'parent' => 'languages',
319 'id' => $lang->slug,
320 'title' => $lang->flag . esc_html( $lang->name ),
321 'href' => esc_url( add_query_arg( 'lang', $lang->slug, remove_query_arg( 'paged', $url ) ) ),
322 'meta' => 'all' === $lang->slug ? array() : array( 'lang' => esc_attr( $lang->get_locale( 'display' ) ) ),
323 ) );
324 }
325 }
326 }
327