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

248 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 /**
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 protected static $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 public static 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 overridden 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::change_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 // On multisite, 2 files are sharing the same domain so we need to distinguish them
164 if ( 'default' === $domain && false !== strpos( $mofile, '/ms-' ) ) {
165 $this->list_textdomains['ms-default'] = array( 'mo' => $mofile, 'domain' => $domain );
166 } else {
167 $this->list_textdomains[ $domain ] = array( 'mo' => $mofile, 'domain' => $domain );
168 }
169 return ''; // Hack to prevent WP loading text domains as we will load them all later
170 }
171
172 /**
173 * Saves post types and taxonomies labels for a later usage
174 *
175 * @since 0.9
176 *
177 * @param string $translation not used
178 * @param string $text string to translate
179 * @param string $domain text domain
180 * @return string unmodified $translation
181 */
182 public function gettext( $translation, $text, $domain ) {
183 if ( is_string( $text ) ) { // Avoid a warning with some buggy plugins which pass an array
184 $this->labels[ $text ] = array( 'domain' => $domain );
185 }
186 return $translation;
187 }
188
189 /**
190 * Saves post types and taxonomies labels for a later usage
191 *
192 * @since 0.9
193 *
194 * @param string $translation not used
195 * @param string $text string to translate
196 * @param string $context some comment to describe the context of string to translate
197 * @param string $domain text domain
198 * @return string unmodified $translation
199 */
200 public function gettext_with_context( $translation, $text, $context, $domain ) {
201 $this->labels[ $text ] = array( 'domain' => $domain, 'context' => $context );
202 return $translation;
203 }
204
205 /**
206 * Translates post types and taxonomies labels once the language is known
207 *
208 * @since 0.9
209 *
210 * @param object $type either a post type or a taxonomy
211 */
212 public function translate_labels( $type ) {
213 // Use static array to avoid translating several times the same ( default ) labels
214 static $translated = array();
215
216 foreach ( $type->labels as $key => $label ) {
217 if ( is_string( $label ) && isset( $this->labels[ $label ] ) ) {
218 if ( empty( $translated[ $label ] ) ) {
219 // PHPCS:disable WordPress.WP.I18n
220 $type->labels->$key = $translated[ $label ] = isset( $this->labels[ $label ]['context'] ) ?
221 _x( $label, $this->labels[ $label ]['context'], $this->labels[ $label ]['domain'] ) :
222 __( $label, $this->labels[ $label ]['domain'] );
223 // PHPCS:enable
224 }
225 else {
226 $type->labels->$key = $translated[ $label ];
227 }
228 }
229 }
230 }
231
232 /**
233 * Allows Polylang to be the first plugin loaded ;- )
234 *
235 * @since 1.2
236 *
237 * @param array $plugins list of active plugins
238 * @return array list of active plugins
239 */
240 public function make_polylang_first( $plugins ) {
241 if ( $key = array_search( POLYLANG_BASENAME, $plugins ) ) {
242 unset( $plugins[ $key ] );
243 array_unshift( $plugins, POLYLANG_BASENAME );
244 }
245 return $plugins;
246 }
247 }
248