PluginProbe
Polylang / 2.2
Polylang v2.2
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.2, at include/olt-manager.php

241 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() && ! Polylang::is_ajax_on_front() && 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 * Access to the single instance of the class
49 *
50 * @since 1.7
51 *
52 * @return object
53 */
54 static public function instance() {
55 if ( empty( self::$instance ) ) {
56 self::$instance = new self();
57 }
58
59 return self::$instance;
60 }
61
62 /**
63 * Loads text domains
64 *
65 * @since 0.1
66 */
67 public function load_textdomains() {
68 // Our load_textdomain_mofile filter has done its job. let's remove it before calling load_textdomain
69 remove_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' ), 10, 2 );
70 remove_filter( 'gettext', array( $this, 'gettext' ), 10, 3 );
71 remove_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ), 10, 4 );
72 $new_locale = get_locale();
73
74 // Don't try to save time for en_US as some users have theme written in another language
75 // Now we can load all overriden text domains with the right language
76 if ( ! empty( $this->list_textdomains ) ) {
77
78 // Since WP 4.7 we need to reset the internal cache of _get_path_to_translation when switching from any locale to en_US
79 // See WP_Locale_Switcher::changle_locale()
80 // FIXME test _get_path_to_translation for backward compatibility with WP < 4.7
81 if ( function_exists( '_get_path_to_translation' ) ) {
82 _get_path_to_translation( null, true );
83 }
84
85 foreach ( $this->list_textdomains as $textdomain ) {
86 // Since WP 4.6, plugins translations are first loaded from wp-content/languages
87 if ( ! load_textdomain( $textdomain['domain'], str_replace( "{$this->default_locale}.mo", "$new_locale.mo", $textdomain['mo'] ) ) ) {
88 // Since WP 3.5 themes may store languages files in /wp-content/languages/themes
89 if ( ! load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/themes/{$textdomain['domain']}-$new_locale.mo" ) ) {
90 // Since WP 3.7 plugins may store languages files in /wp-content/languages/plugins
91 load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/plugins/{$textdomain['domain']}-$new_locale.mo" );
92 }
93 }
94 }
95 }
96
97 // First remove taxonomies and post_types labels that we don't need to translate
98 $taxonomies = get_taxonomies( array( '_pll' => true ) );
99 $post_types = get_post_types( array( '_pll' => true ) );
100
101 // We don't need to translate core taxonomies and post types labels when setting the language from the url
102 // As they will be translated when registered the second time
103 if ( ! did_action( 'setup_theme' ) ) {
104 $taxonomies = array_merge( get_taxonomies( array( '_builtin' => true ) ), $taxonomies );
105 $post_types = array_merge( get_post_types( array( '_builtin' => true ) ), $post_types );
106 }
107
108 // Translate labels of post types and taxonomies
109 foreach ( array_diff_key( $GLOBALS['wp_taxonomies'], array_flip( $taxonomies ) ) as $tax ) {
110 $this->translate_labels( $tax );
111 }
112 foreach ( array_diff_key( $GLOBALS['wp_post_types'], array_flip( $post_types ) ) as $pt ) {
113 $this->translate_labels( $pt );
114 }
115
116 // Act only if the language has not been set early ( before default textdomain loading and $wp_locale creation )
117 if ( did_action( 'after_setup_theme' ) ) {
118 // Reinitializes wp_locale for weekdays and months
119 unset( $GLOBALS['wp_locale'] );
120 $GLOBALS['wp_locale'] = new WP_Locale();
121 }
122
123 /**
124 * Fires after the post types and taxonomies labels have been translated
125 * This allows plugins to translate text the same way we do for post types and taxonomies labels
126 *
127 * @since 1.2
128 *
129 * @param array $labels list of strings to trnaslate
130 */
131 do_action_ref_array( 'pll_translate_labels', array( &$this->labels ) );
132
133 // Free memory
134 unset( $this->default_locale, $this->list_textdomains, $this->labels );
135 }
136
137 /**
138 * FIXME: Backward compatibility with Polylang for WooCommerce < 0.3.4
139 * To remove in Polylang 2.1
140 *
141 * @since 0.1
142 *
143 * @param bool $bool not used
144 * @param string $domain text domain name
145 * @param string $mofile translation file name
146 * @return bool
147 */
148 public function mofile( $bool, $domain, $mofile ) {
149 return $bool;
150 }
151
152 /**
153 * Saves all text domains in a table for later usage
154 * It replaces the 'override_load_textdomain' filter used since 0.1
155 *
156 * @since 2.0.4
157 *
158 * @param string $mofile translation file name
159 * @param string $domain text domain name
160 * @return bool
161 */
162 public function load_textdomain_mofile( $mofile, $domain ) {
163 $this->list_textdomains[] = array( 'mo' => $mofile, 'domain' => $domain );
164 return ''; // Hack to prevent WP loading text domains as we will load them all later
165 }
166
167 /**
168 * Saves post types and taxonomies labels for a later usage
169 *
170 * @since 0.9
171 *
172 * @param string $translation not used
173 * @param string $text string to translate
174 * @param string $domain text domain
175 * @return string unmodified $translation
176 */
177 public function gettext( $translation, $text, $domain ) {
178 if ( is_string( $text ) ) { // Avoid a warning with some buggy plugins which pass an array
179 $this->labels[ $text ] = array( 'domain' => $domain );
180 }
181 return $translation;
182 }
183
184 /**
185 * Saves post types and taxonomies labels for a later usage
186 *
187 * @since 0.9
188 *
189 * @param string $translation not used
190 * @param string $text string to translate
191 * @param string $context some comment to describe the context of string to translate
192 * @param string $domain text domain
193 * @return string unmodified $translation
194 */
195 public function gettext_with_context( $translation, $text, $context, $domain ) {
196 $this->labels[ $text ] = array( 'domain' => $domain, 'context' => $context );
197 return $translation;
198 }
199
200 /**
201 * Translates post types and taxonomies labels once the language is known
202 *
203 * @since 0.9
204 *
205 * @param object $type either a post type or a taxonomy
206 */
207 public function translate_labels( $type ) {
208 // Use static array to avoid translating several times the same ( default ) labels
209 static $translated = array();
210
211 foreach ( $type->labels as $key => $label ) {
212 if ( is_string( $label ) && isset( $this->labels[ $label ] ) ) {
213 if ( empty( $translated[ $label ] ) ) {
214 $type->labels->$key = $translated[ $label ] = isset( $this->labels[ $label ]['context'] ) ?
215 _x( $label, $this->labels[ $label ]['context'], $this->labels[ $label ]['domain'] ) :
216 __( $label, $this->labels[ $label ]['domain'] );
217 }
218 else {
219 $type->labels->$key = $translated[ $label ];
220 }
221 }
222 }
223 }
224
225 /**
226 * Allows Polylang to be the first plugin loaded ;- )
227 *
228 * @since 1.2
229 *
230 * @param array $plugins list of active plugins
231 * @return array list of active plugins
232 */
233 public function make_polylang_first( $plugins ) {
234 if ( $key = array_search( POLYLANG_BASENAME, $plugins ) ) {
235 unset( $plugins[ $key ] );
236 array_unshift( $plugins, POLYLANG_BASENAME );
237 }
238 return $plugins;
239 }
240 }
241