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

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