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

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