PLL_Admin_Base

Base class for both admin.

Defined (1)

The class is defined in the following location(s).

/admin/admin-base.php  
  1. class PLL_Admin_Base extends PLL_Base { 
  2. public $filter_lang, $curlang, $pref_lang; 
  3.  
  4. /** 
  5. * Loads the polylang text domain 
  6. * Setups actions needed on all admin pages 
  7. * @since 1.8 
  8. * @param object $links_model 
  9. */ 
  10. public function __construct( &$links_model ) { 
  11. parent::__construct( $links_model ); 
  12.  
  13. // Plugin i18n, only needed for backend 
  14. load_plugin_textdomain( 'polylang', false, basename( POLYLANG_DIR ).'/languages' ); 
  15.  
  16. // Adds the link to the languages panel in the WordPress admin menu 
  17. add_action( 'admin_menu', array( $this, 'add_menus' ) ); 
  18.  
  19. // Setup js scripts and css styles 
  20. add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); 
  21. add_action( 'admin_print_footer_scripts', array( $this, 'admin_print_footer_scripts' ) ); 
  22.  
  23. // Lingotek 
  24. if ( ! defined( 'PLL_LINGOTEK_AD' ) || PLL_LINGOTEK_AD ) { 
  25. require_once POLYLANG_DIR . '/lingotek/lingotek.php'; 
  26.  
  27. /** 
  28. * Setups filters and action needed on all admin pages and on plugins page 
  29. * Loads the settings pages or the filters base on the request 
  30. * @since 1.2 
  31. * @param object $links_model 
  32. */ 
  33. public function init() { 
  34. if ( ! $this->model->get_languages_list() ) { 
  35. return; 
  36.  
  37. $this->links = new PLL_Admin_Links( $this ); // FIXME needed here ? 
  38. $this->static_pages = new PLL_Admin_Static_Pages( $this ); // FIXME needed here ? 
  39. $this->filters_links = new PLL_Filters_Links( $this ); // FIXME needed here ? 
  40.  
  41. // Filter admin language for users 
  42. // We must not call user info before WordPress defines user roles in wp-settings.php 
  43. add_filter( 'setup_theme', array( $this, 'init_user' ) ); 
  44. add_filter( 'request', array( $this, 'request' ) ); 
  45.  
  46. // Adds the languages in admin bar 
  47. add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 100 ); // 100 determines the position 
  48.  
  49. /** 
  50. * Adds the link to the languages panel in the WordPress admin menu 
  51. * @since 0.1 
  52. */ 
  53. public function add_menus() { 
  54. // Prepare the list of tabs 
  55. $tabs = array( 'lang' => __( 'Languages', 'polylang' ) ); 
  56.  
  57. // Only if at least one language has been created 
  58. if ( $this->model->get_languages_list() ) { 
  59. $tabs['strings'] = __( 'Strings translations', 'polylang' ); 
  60.  
  61. $tabs['settings'] = __( 'Settings', 'polylang' ); 
  62.  
  63. /** 
  64. * Filter the list of tabs in Polylang settings 
  65. * @since 1.5.1 
  66. * @param array $tabs list of tab names 
  67. */ 
  68. $tabs = apply_filters( 'pll_settings_tabs', $tabs ); 
  69.  
  70. foreach ( $tabs as $tab => $title ) { 
  71. $page = 'lang' === $tab ? 'mlang' : "mlang_$tab"; 
  72. if ( empty( $parent ) ) { 
  73. $parent = $page; 
  74. add_menu_page( $title, __( 'Languages', 'polylang' ), 'manage_options', $page, null , 'dashicons-translation' ); 
  75.  
  76. add_submenu_page( $parent, $title, $title, 'manage_options', $page , array( $this, 'languages_page' ) ); 
  77.  
  78. /** 
  79. * Setup js scripts & css styles ( only on the relevant pages ) 
  80. * @since 0.6 
  81. */ 
  82. public function admin_enqueue_scripts() { 
  83. $screen = get_current_screen(); 
  84. if ( empty( $screen ) ) { 
  85. return; 
  86.  
  87. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 
  88.  
  89. // For each script: 
  90. // 0 => the pages on which to load the script 
  91. // 1 => the scripts it needs to work 
  92. // 2 => 1 if loaded even if languages have not been defined yet, 0 otherwise 
  93. // 3 => 1 if loaded in footer 
  94. // FIXME: check if I can load more scripts in footer 
  95. $scripts = array( 
  96. 'post' => array( array( 'post', 'media', 'async-upload', 'edit' ), array( 'jquery', 'wp-ajax-response', 'post', 'jquery-ui-autocomplete' ), 0 , 1 ),  
  97. 'media' => array( array( 'upload' ), array( 'jquery' ), 0 , 1 ),  
  98. 'term' => array( array( 'edit-tags', 'term' ), array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), 0, 1 ),  
  99. 'user' => array( array( 'profile', 'user-edit' ), array( 'jquery' ), 0 , 0 ),  
  100. ); 
  101.  
  102. foreach ( $scripts as $script => $v ) { 
  103. if ( in_array( $screen->base, $v[0] ) && ( $v[2] || $this->model->get_languages_list() ) ) { 
  104. wp_enqueue_script( 'pll_' . $script, plugins_url( '/js/' . $script . $suffix . '.js', POLYLANG_FILE ), $v[1], POLYLANG_VERSION, $v[3] ); 
  105.  
  106. wp_enqueue_style( 'polylang_admin', plugins_url( '/css/admin' . $suffix . '.css', POLYLANG_FILE ), array(), POLYLANG_VERSION ); 
  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. * Takes care to various situations: 
  112. * when the ajax request has no options.data thanks to ScreenfeedFr 
  113. * see: https://wordpress.org/support/topic/ajaxprefilter-may-not-work-as-expected 
  114. * when options.data is a json string 
  115. * see: https://wordpress.org/support/topic/polylang-breaking-third-party-ajax-requests-on-admin-panels 
  116. * when options.data is an empty string (GET request with the method 'load') 
  117. * see: https://wordpress.org/support/topic/invalid-url-during-wordpress-new-dashboard-widget-operation 
  118. * @since 1.4 
  119. */ 
  120. public function admin_print_footer_scripts() { 
  121. global $post_ID; 
  122.  
  123. $params = array( 'pll_ajax_backend' => 1 ); 
  124. if ( ! empty( $post_ID ) ) { 
  125. $params = array_merge( $params, array( 'pll_post_id' => (int) $post_ID ) ); 
  126.  
  127. $str = http_build_query( $params ); 
  128. $arr = json_encode( $params ); 
  129. ?> 
  130. <script type="text/javascript"> 
  131. if (typeof jQuery != 'undefined') { 
  132. (function($) { 
  133. $.ajaxPrefilter(function (options, originalOptions, jqXHR) { 
  134. if ( -1 != options.url.indexOf( ajaxurl ) || -1 != ajaxurl.indexOf( options.url ) ) { 
  135. if ( 'undefined' === typeof options.data ) { 
  136. options.data = ( 'get' === options.type.toLowerCase() ) ? '<?php echo $str;?>' : <?php echo $arr;?>; 
  137. } else { 
  138. if ( 'string' === typeof options.data ) { 
  139. if ( '' === options.data && 'get' === options.type.toLowerCase() ) { 
  140. options.url = options.url+'&<?php echo $str;?>'; 
  141. } else { 
  142. try { 
  143. o = $.parseJSON(options.data); 
  144. o = $.extend(o, <?php echo $arr;?>); 
  145. options.data = JSON.stringify(o); 
  146. catch(e) { 
  147. options.data = '<?php echo $str;?>&'+options.data; 
  148. } else { 
  149. options.data = $.extend(options.data, <?php echo $arr;?>); 
  150. }); 
  151. })(jQuery) 
  152. </script><?php 
  153.  
  154. /** 
  155. * Sets the admin current language, used to filter the content 
  156. * @since 2.0 
  157. */ 
  158. public function set_current_language() { 
  159. $this->curlang = $this->filter_lang; 
  160.  
  161. // Edit Post 
  162. if ( isset( $_REQUEST['pll_post_id'] ) && $lang = $this->model->post->get_language( (int) $_REQUEST['pll_post_id'] ) ) { 
  163. $this->curlang = $lang; 
  164. } elseif ( 'post.php' === $GLOBALS['pagenow'] && isset( $_GET['post'] ) && is_numeric( $_GET['post'] ) && $lang = $this->model->post->get_language( (int) $_GET['post'] ) ) { 
  165. $this->curlang = $lang; 
  166. } elseif ( 'post-new.php' === $GLOBALS['pagenow'] && ( empty( $_GET['post_type'] ) || $this->model->is_translated_post_type( $_GET['post_type'] ) ) ) { 
  167. $this->curlang = empty( $_GET['new_lang'] ) ? $this->pref_lang : $this->model->get_language( $_GET['new_lang'] ); 
  168.  
  169. // Edit Term 
  170. // FIXME 'edit-tags.php' for backward compatibility with WP < 4.5 
  171. 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'] ) ) { 
  172. $this->curlang = $lang; 
  173. } elseif ( 'edit-tags.php' === $GLOBALS['pagenow'] && isset( $_GET['taxonomy'] ) && $this->model->is_translated_taxonomy( $_GET['taxonomy'] ) ) { 
  174. if ( ! empty( $_GET['new_lang'] ) ) { 
  175. $this->curlang = $this->model->get_language( $_GET['new_lang'] ); 
  176. } elseif ( empty( $this->curlang ) ) { 
  177. $this->curlang = $this->pref_lang; 
  178.  
  179. // Ajax 
  180. if ( defined( 'DOING_AJAX' ) && DOING_AJAX && ! empty( $_REQUEST['lang'] ) ) { 
  181. $this->curlang = $this->model->get_language( $_REQUEST['lang'] ); 
  182.  
  183. /** 
  184. * Defines the backend language and the admin language filter based on user preferences 
  185. * @since 1.2.3 
  186. */ 
  187. public function init_user() { 
  188. // Backend locale 
  189. // FIXME: Backward compatibility with WP < 4.7 
  190. if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) { 
  191. add_filter( 'locale', array( $this, 'get_locale' ) ); 
  192.  
  193. // Language for admin language filter: may be empty 
  194. // $_GET['lang'] is numeric when editing a language, not when selecting a new language in the filter 
  195. if ( ! defined( 'DOING_AJAX' ) && ! empty( $_GET['lang'] ) && ! is_numeric( $_GET['lang'] ) && current_user_can( 'edit_user', $user_id = get_current_user_id() ) ) { 
  196. update_user_meta( $user_id, 'pll_filter_content', ( $lang = $this->model->get_language( $_GET['lang'] ) ) ? $lang->slug : '' ); 
  197.  
  198. $this->filter_lang = $this->model->get_language( get_user_meta( get_current_user_id(), 'pll_filter_content', true ) ); 
  199.  
  200. // Set preferred language for use when saving posts and terms: must not be empty 
  201. $this->pref_lang = empty( $this->filter_lang ) ? $this->model->get_language( $this->options['default_lang'] ) : $this->filter_lang; 
  202.  
  203. /** 
  204. * Filter the preferred language on amin side 
  205. * The preferred language is used for example to determine the language of a new post 
  206. * @since 1.2.3 
  207. * @param object $pref_lang preferred language 
  208. */ 
  209. $this->pref_lang = apply_filters( 'pll_admin_preferred_language', $this->pref_lang ); 
  210.  
  211. $this->set_current_language(); 
  212.  
  213. // Inform that the admin language has been set 
  214. // Only if the admin language is one of the Polylang defined language 
  215. // FIXME test get_user_locale for backward compatibility with WP 4.7 
  216. if ( $curlang = $this->model->get_language( function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale() ) ) { 
  217. // FIXME: Backward compatibility with WP < 4.7 
  218. if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) { 
  219. $GLOBALS['text_direction'] = $curlang->is_rtl ? 'rtl' : 'ltr'; // force text direction according to language setting 
  220.  
  221. /** This action is documented in frontend/choose-lang.php */ 
  222. do_action( 'pll_language_defined', $curlang->slug, $curlang ); 
  223. } else { 
  224. /** This action is documented in include/class-polylang.php */ 
  225. do_action( 'pll_no_language_defined' ); // to load overriden textdomains 
  226.  
  227. /** 
  228. * Avoids parsing a tax query when all languages are requested 
  229. * Fixes https://wordpress.org/support/topic/notice-undefined-offset-0-in-wp-includesqueryphp-on-line-3877 introduced in WP 4.1 
  230. * @see the suggestion of @boonebgorges, https://core.trac.wordpress.org/ticket/31246 
  231. * @since 1.6.5 
  232. * @param array $qvars 
  233. * @return array 
  234. */ 
  235. public function request( $qvars ) { 
  236. if ( isset( $qvars['lang'] ) && 'all' === $qvars['lang'] ) { 
  237. unset( $qvars['lang'] ); 
  238.  
  239. return $qvars; 
  240.  
  241. /** 
  242. * Get the locale based on user preference 
  243. * FIXME: Backward compatibility with WP < 4.7 
  244. * @since 0.4 
  245. * @param string $locale 
  246. * @return string modified locale 
  247. */ 
  248. public function get_locale( $locale ) { 
  249. return ( $loc = get_user_meta( get_current_user_id(), 'locale', 'true' ) ) ? $loc : $locale; 
  250.  
  251. /** 
  252. * Adds the languages list in admin bar for the admin languages filter 
  253. * @since 0.9 
  254. * @param object $wp_admin_bar 
  255. */ 
  256. public function admin_bar_menu( $wp_admin_bar ) { 
  257. $url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 
  258.  
  259. $all_item = (object) array( 
  260. 'slug' => 'all',  
  261. 'name' => __( 'Show all languages', 'polylang' ),  
  262. 'flag' => '<span class="ab-icon"></span>',  
  263. ); 
  264.  
  265. $selected = empty( $this->filter_lang ) ? $all_item : $this->filter_lang; 
  266.  
  267. $title = sprintf( 
  268. '<span class="ab-label"%s>%s</span>',  
  269. 'all' === $selected->slug ? '' : sprintf( ' lang="%s"', esc_attr( $selected->get_locale( 'display' ) ) ),  
  270. esc_html( $selected->name ) 
  271. ); 
  272.  
  273. $wp_admin_bar->add_menu( array( 
  274. 'id' => 'languages',  
  275. 'title' => $selected->flag . $title,  
  276. 'meta' => array( 'title' => __( 'Filters content by language', 'polylang' ) ),  
  277. ) ); 
  278.  
  279. foreach ( array_merge( array( $all_item ), $this->model->get_languages_list() ) as $lang ) { 
  280. if ( $selected->slug === $lang->slug ) { 
  281. continue; 
  282.  
  283. $wp_admin_bar->add_menu( array( 
  284. 'parent' => 'languages',  
  285. 'id' => $lang->slug,  
  286. 'title' => $lang->flag . esc_html( $lang->name ),  
  287. 'href' => esc_url( add_query_arg( 'lang', $lang->slug, remove_query_arg( 'paged', $url ) ) ),  
  288. 'meta' => 'all' === $lang->slug ? array() : array( 'lang' => esc_attr( $lang->get_locale( 'display' ) ) ),  
  289. ) );