PluginProbe
Polylang / 2.1.6
Polylang v2.1.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 / include / olt-manager.php

olt-manager.php in Polylang 2.1.6, at include/olt-manager.php

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