PLL_OLT_Manager

It is best practice that plugins do nothing before plugins_loaded is fired so it is what Polylang intends to do but some plugins load their text domain as soon as loaded, thus before plugins_loaded is fired this class differs text domain loading until the language is defined either in a plugins_loaded action or in a wp action ( when the language is set from content on frontend ).

Defined (1)

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

/include/olt-manager.php  
  1. class PLL_OLT_Manager { 
  2. static protected $instance; // For singleton 
  3. protected $default_locale; 
  4. protected $list_textdomains = array(); // All text domains 
  5. public $labels = array(); // Post types and taxonomies labels to translate 
  6.  
  7. /** 
  8. * Constructor: setups relevant filters 
  9. * @since 1.2 
  10. */ 
  11. public function __construct() { 
  12. // Allows Polylang to be the first plugin loaded ;-) 
  13. add_filter( 'pre_update_option_active_plugins', array( $this, 'make_polylang_first' ) ); 
  14. add_filter( 'pre_update_option_active_sitewide_plugins', array( $this, 'make_polylang_first' ) ); 
  15.  
  16. // Overriding load text domain only on front since WP 4.7 
  17. // FIXME test get_user_locale for backward compatibility with WP < 4.7 
  18. if ( is_admin() && function_exists( 'get_user_locale' ) ) { 
  19. return; 
  20.  
  21. // Saves the default locale before we start any language manipulation 
  22. $this->default_locale = get_locale(); 
  23.  
  24. // Filters for text domain management 
  25. add_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' ), 10, 2 ); 
  26. add_filter( 'gettext', array( $this, 'gettext' ), 10, 3 ); 
  27. add_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ), 10, 4 ); 
  28.  
  29. // Loads text domains 
  30. add_action( 'pll_language_defined', array( $this, 'load_textdomains' ), 2 ); // After PLL_Frontend::pll_language_defined 
  31. add_action( 'pll_no_language_defined', array( $this, 'load_textdomains' ) ); 
  32.  
  33.  
  34. /** 
  35. * Access to the single instance of the class 
  36. * @since 1.7 
  37. * @return object 
  38. */ 
  39. static public function instance() { 
  40. if ( empty( self::$instance ) ) { 
  41. self::$instance = new self(); 
  42.  
  43. return self::$instance; 
  44.  
  45. /** 
  46. * Loads text domains 
  47. * @since 0.1 
  48. */ 
  49. public function load_textdomains() { 
  50. // Our load_textdomain_mofile filter has done its job. let's remove it before calling load_textdomain 
  51. remove_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' ), 10, 2 ); 
  52. remove_filter( 'gettext', array( $this, 'gettext' ), 10, 3 ); 
  53. remove_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ), 10, 4 ); 
  54. $new_locale = get_locale(); 
  55.  
  56.  
  57. // Don't try to save time for en_US as some users have theme written in another language 
  58. // Now we can load all overriden text domains with the right language 
  59. if ( ! empty( $this->list_textdomains ) ) { 
  60.  
  61. // Since WP 4.7 we need to reset the internal cache of _get_path_to_translation when switching from any locale to en_US 
  62. // See WP_Locale_Switcher::changle_locale() 
  63. // FIXME test _get_path_to_translation for backward compatibility with WP < 4.7 
  64. if ( function_exists( '_get_path_to_translation' ) ) { 
  65. _get_path_to_translation( null, true ); 
  66.  
  67. foreach ( $this->list_textdomains as $textdomain ) { 
  68. // Since WP 4.6, plugins translations are first loaded from wp-content/languages 
  69. if ( ! load_textdomain( $textdomain['domain'], str_replace( "{$this->default_locale}.mo", "$new_locale.mo", $textdomain['mo'] ) ) ) { 
  70. // Since WP 3.5 themes may store languages files in /wp-content/languages/themes 
  71. if ( ! load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/themes/{$textdomain['domain']}-$new_locale.mo" ) ) { 
  72. // Since WP 3.7 plugins may store languages files in /wp-content/languages/plugins 
  73. load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/plugins/{$textdomain['domain']}-$new_locale.mo" ); 
  74.  
  75. // First remove taxonomies and post_types labels that we don't need to translate 
  76. $taxonomies = array( 'language', 'term_language', 'term_translations', 'post_translations' ); 
  77. $post_types = array( 'polylang_mo' ); 
  78.  
  79. // We don't need to translate core taxonomies and post types labels when setting the language from the url 
  80. // As they will be translated when registered the second time 
  81. if ( ! did_action( 'setup_theme' ) ) { 
  82. $taxonomies = array_merge( array( 'category', 'post_tag', 'nav_menu', 'link_category', 'post_format' ), $taxonomies ); 
  83. $post_types = array_merge( array( 'post', 'page', 'attachment', 'revision', 'nav_menu_item' ), $post_types ); 
  84.  
  85. // Translate labels of post types and taxonomies 
  86. foreach ( array_diff_key( $GLOBALS['wp_taxonomies'], array_flip( $taxonomies ) ) as $tax ) { 
  87. $this->translate_labels( $tax ); 
  88. foreach ( array_diff_key( $GLOBALS['wp_post_types'], array_flip( $post_types ) ) as $pt ) { 
  89. $this->translate_labels( $pt ); 
  90.  
  91. // Act only if the language has not been set early ( before default textdomain loading and $wp_locale creation ) 
  92. if ( did_action( 'after_setup_theme' ) ) { 
  93. // Reinitializes wp_locale for weekdays and months 
  94. unset( $GLOBALS['wp_locale'] ); 
  95. $GLOBALS['wp_locale'] = new WP_Locale(); 
  96.  
  97. /** 
  98. * Fires after the post types and taxonomies labels have been translated 
  99. * This allows plugins to translate text the same way we do for post types and taxonomies labels 
  100. * @since 1.2 
  101. * @param array $labels list of strings to trnaslate 
  102. */ 
  103. do_action_ref_array( 'pll_translate_labels', array( &$this->labels ) ); 
  104.  
  105. // Free memory 
  106. unset( $this->default_locale, $this->list_textdomains, $this->labels ); 
  107.  
  108. /** 
  109. * FIXME: Backward compatibility with Polylang for WooCommerce < 0.3.4 
  110. * To remove in Polylang 2.1 
  111. * @since 0.1 
  112. * @param bool $bool not used 
  113. * @param string $domain text domain name 
  114. * @param string $mofile translation file name 
  115. * @return bool 
  116. */ 
  117. public function mofile( $bool, $domain, $mofile ) { 
  118. return $bool; 
  119.  
  120. /** 
  121. * Saves all text domains in a table for later usage 
  122. * It replaces the 'override_load_textdomain' filter used since 0.1 
  123. * @since 2.0.4 
  124. * @param string $mofile translation file name 
  125. * @param string $domain text domain name 
  126. * @return bool 
  127. */ 
  128. public function load_textdomain_mofile( $mofile, $domain ) { 
  129. $this->list_textdomains[ $domain ] = array( 'mo' => $mofile, 'domain' => $domain ); 
  130. return ''; // Hack to prevent WP loading text domains as we will load them all later 
  131.  
  132. /** 
  133. * Saves post types and taxonomies labels for a later usage 
  134. * @since 0.9 
  135. * @param string $translation not used 
  136. * @param string $text string to translate 
  137. * @param string $domain text domain 
  138. * @return string unmodified $translation 
  139. */ 
  140. public function gettext( $translation, $text, $domain ) { 
  141. if ( is_string( $text ) ) { // Avoid a warning with some buggy plugins which pass an array 
  142. $this->labels[ $text ] = array( 'domain' => $domain ); 
  143. return $translation; 
  144.  
  145. /** 
  146. * Saves post types and taxonomies labels for a later usage 
  147. * @since 0.9 
  148. * @param string $translation not used 
  149. * @param string $text string to translate 
  150. * @param string $context some comment to describe the context of string to translate 
  151. * @param string $domain text domain 
  152. * @return string unmodified $translation 
  153. */ 
  154. public function gettext_with_context( $translation, $text, $context, $domain ) { 
  155. $this->labels[ $text ] = array( 'domain' => $domain, 'context' => $context ); 
  156. return $translation; 
  157.  
  158. /** 
  159. * Translates post types and taxonomies labels once the language is known 
  160. * @since 0.9 
  161. * @param object $type either a post type or a taxonomy 
  162. */ 
  163. public function translate_labels( $type ) { 
  164. // Use static array to avoid translating several times the same ( default ) labels 
  165. static $translated = array(); 
  166.  
  167. foreach ( $type->labels as $key => $label ) { 
  168. if ( is_string( $label ) && isset( $this->labels[ $label ] ) ) { 
  169. if ( empty( $translated[ $label ] ) ) { 
  170. $type->labels->$key = $translated[ $label ] = isset( $this->labels[ $label ]['context'] ) ? 
  171. _x( $label, $this->labels[ $label ]['context'], $this->labels[ $label ]['domain'] ) : 
  172. __( $label, $this->labels[ $label ]['domain'] ); 
  173. else { 
  174. $type->labels->$key = $translated[ $label ]; 
  175.  
  176. /** 
  177. * Allows Polylang to be the first plugin loaded ;- ) 
  178. * @since 1.2 
  179. * @param array $plugins list of active plugins 
  180. * @return array list of active plugins 
  181. */ 
  182. public function make_polylang_first( $plugins ) { 
  183. if ( $key = array_search( POLYLANG_BASENAME, $plugins ) ) { 
  184. unset( $plugins[ $key ] ); 
  185. array_unshift( $plugins, POLYLANG_BASENAME ); 
  186. return $plugins;