PluginProbe
Polylang / 2.7.2
Polylang v2.7.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 / language.php

language.php in Polylang 2.7.2, at include/language.php

304 lines 10.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * A language object is made of two terms in 'language' and 'term_language' taxonomies
5 * manipulating only one object per language instead of two terms should make things easier
6 *
7 * Properties:
8 * term_id => id of term in 'language' taxonomy
9 * name => language name. Ex: English
10 * slug => language code used in url. Ex: en
11 * term_group => order of the language when displayed in a list of languages
12 * term_taxonomy_id => term taxonomy id in 'language' taxonomy
13 * taxonomy => 'language'
14 * description => language locale for backward compatibility
15 * parent => 0 / not used
16 * count => number of posts and pages in that language
17 * tl_term_id => id of the term in 'term_language' taxonomy
18 * tl_term_taxonomy_id => term taxonomy id in 'term_language' taxonomy
19 * tl_count => number of terms in that language ( not used by Polylang )
20 * locale => WordPress language locale. Ex: en_US
21 * is_rtl => 1 if the language is rtl
22 * w3c => W3C locale
23 * flag_code => code of the flag
24 * flag_url => url of the flag
25 * flag => html img of the flag
26 * custom_flag_url => url of the custom flag if exists, internal use only, moves to flag_url on frontend
27 * custom_flag => html img of the custom flag if exists, internal use only, moves to flag on frontend
28 * home_url => home url in this language
29 * search_url => home url to use in search forms
30 * host => host of this language
31 * mo_id => id of the post storing strings translations
32 * page_on_front => id of the page on front in this language ( set from pll_languages_list filter )
33 * page_for_posts => id of the page for posts in this language ( set from pll_languages_list filter )
34 *
35 * @since 1.2
36 */
37 class PLL_Language {
38 public $term_id, $name, $slug, $term_group, $term_taxonomy_id, $taxonomy, $description, $parent, $count;
39 public $tl_term_id, $tl_term_taxonomy_id, $tl_count;
40 public $locale, $is_rtl;
41 public $w3c, $facebook;
42 public $flag_url, $flag;
43 public $home_url, $search_url;
44 public $host, $mo_id;
45 public $page_on_front, $page_for_posts;
46
47 /**
48 * Constructor: builds a language object given its two corresponding terms in language and term_language taxonomies
49 *
50 * @since 1.2
51 *
52 * @param object|array $language 'language' term or language object properties stored as an array
53 * @param object $term_language Corresponding 'term_language' term
54 */
55 public function __construct( $language, $term_language = null ) {
56 // Build the object from all properties stored as an array
57 if ( empty( $term_language ) ) {
58 foreach ( $language as $prop => $value ) {
59 $this->$prop = $value;
60 }
61 }
62
63 // Build the object from taxonomies
64 else {
65 foreach ( $language as $prop => $value ) {
66 $this->$prop = in_array( $prop, array( 'term_id', 'term_taxonomy_id', 'count' ) ) ? (int) $language->$prop : $language->$prop;
67 }
68
69 $this->tl_term_id = (int) $term_language->term_id;
70 $this->tl_term_taxonomy_id = (int) $term_language->term_taxonomy_id;
71 $this->tl_count = (int) $term_language->count;
72
73 // The description field can contain any property
74 // Backward compatibility for is_rtl
75 $description = maybe_unserialize( $language->description );
76 foreach ( $description as $prop => $value ) {
77 'rtl' == $prop ? $this->is_rtl = $value : $this->$prop = $value;
78 }
79
80 $this->description = &$this->locale; // Backward compatibility with Polylang < 1.2
81
82 $this->mo_id = PLL_MO::get_id( $this );
83
84 $languages = include PLL_SETTINGS_INC . '/languages.php';
85 $this->w3c = isset( $languages[ $this->locale ]['w3c'] ) ? $languages[ $this->locale ]['w3c'] : str_replace( '_', '-', $this->locale );
86 if ( isset( $languages[ $this->locale ]['facebook'] ) ) {
87 $this->facebook = $languages[ $this->locale ]['facebook'];
88 }
89 }
90 }
91
92 /**
93 * Get the flag informations
94 * 'url' => Flag url
95 * 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
96 * 'width' => Optional, flag width in pixels
97 * 'height' => Optional, flag height in pixels
98 *
99 * @since 2.6
100 *
101 * @param string $code Flag code.
102 * @return array Flag informations.
103 */
104 public static function get_flag_informations( $code ) {
105 $flag = array( 'url' => '' );
106
107 // Polylang builtin flags
108 if ( ! empty( $code ) && file_exists( POLYLANG_DIR . ( $file = '/flags/' . $code . '.png' ) ) ) {
109 $flag['url'] = $_url = plugins_url( $file, POLYLANG_FILE );
110 }
111
112 /**
113 * Filter flag informations
114 * 'url' => Flag url
115 * 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
116 * 'width' => Optional, flag width in pixels
117 * 'height' => Optional, flag height in pixels
118 *
119 * @since 2.4
120 *
121 * @param array $flag Information about the flag
122 * @param string $code Flag code
123 */
124 $flag = apply_filters( 'pll_flag', $flag, $code );
125
126 if ( empty( $flag['src'] ) ) {
127 // If using predefined flags and base64 encoded flags are preferred
128 if ( isset( $_url ) && $flag['url'] === $_url && ( ! defined( 'PLL_ENCODED_FLAGS' ) || PLL_ENCODED_FLAGS ) ) {
129 list( $flag['width'], $flag['height'] ) = getimagesize( POLYLANG_DIR . $file );
130 $file_contents = file_get_contents( POLYLANG_DIR . $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
131 $flag['src'] = 'data:image/png;base64,' . base64_encode( $file_contents ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
132 } else {
133 $flag['src'] = esc_url( set_url_scheme( $flag['url'], 'relative' ) );
134 }
135 }
136
137 $flag['url'] = esc_url_raw( $flag['url'] );
138
139 return $flag;
140 }
141
142 /**
143 * Sets flag_url and flag properties
144 *
145 * @since 1.2
146 */
147 public function set_flag() {
148 $flags = array( 'flag' => self::get_flag_informations( $this->flag_code ) );
149
150 // Custom flags ?
151 $directories = array(
152 PLL_LOCAL_DIR,
153 get_stylesheet_directory() . '/polylang',
154 get_template_directory() . '/polylang',
155 );
156
157 foreach ( $directories as $dir ) {
158 if ( file_exists( $file = "{$dir}/{$this->locale}.png" ) || file_exists( $file = "{$dir}/{$this->locale}.jpg" ) || file_exists( $file = "{$dir}/{$this->locale}.svg" ) ) {
159 $flags['custom_flag']['url'] = content_url( '/' . str_replace( WP_CONTENT_DIR, '', $file ) );
160 break;
161 }
162 }
163
164 /**
165 * Filter the custom flag informations
166 * 'url' => Flag url
167 * 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
168 * 'width' => Optional, flag width in pixels
169 * 'height' => Optional, flag height in pixels
170 *
171 * @since 2.4
172 *
173 * @param array $flag Information about the custom flag
174 * @param string $code Flag code
175 */
176 $flags['custom_flag'] = apply_filters( 'pll_custom_flag', empty( $flags['custom_flag'] ) ? null : $flags['custom_flag'], $this->flag_code );
177
178 if ( ! empty( $flags['custom_flag']['url'] ) ) {
179 if ( empty( $flags['custom_flag']['src'] ) ) {
180 $flags['custom_flag']['src'] = esc_url( set_url_scheme( $flags['custom_flag']['url'], 'relative' ) );
181 }
182
183 $flags['custom_flag']['url'] = esc_url_raw( $flags['custom_flag']['url'] );
184 } else {
185 unset( $flags['custom_flag'] );
186 }
187
188 /**
189 * Filter the flag title attribute
190 * Defaults to the language name
191 *
192 * @since 0.7
193 *
194 * @param string $title the flag title attribute
195 * @param string $slug the language code
196 * @param string $locale the language locale
197 */
198 $title = apply_filters( 'pll_flag_title', $this->name, $this->slug, $this->locale );
199
200 foreach ( $flags as $key => $flag ) {
201 $this->{$key . '_url'} = empty( $flag['url'] ) ? '' : $flag['url'];
202
203 /**
204 * Filter the html markup of a flag
205 *
206 * @since 1.0.2
207 *
208 * @param string $flag html markup of the flag or empty string
209 * @param string $slug language code
210 */
211 $this->{$key} = apply_filters(
212 'pll_get_flag',
213 self::get_flag_html( $flag, $title, $this->name ),
214 $this->slug
215 );
216 }
217 }
218
219 /**
220 * Get HTML code for flag
221 *
222 * @since 2.7
223 *
224 * @param array $flag flag properties: src, width and height
225 * @param string $title optional title attribute
226 * @param string $alt optional alt attribute
227 */
228 public static function get_flag_html( $flag, $title = '', $alt = '' ) {
229 return empty( $flag['src'] ) ? '' : sprintf(
230 '<img src="%s"%s%s%s%s />',
231 $flag['src'],
232 empty( $title ) ? '' : sprintf( ' title="%s"', esc_attr( $title ) ),
233 empty( $alt ) ? '' : sprintf( ' alt="%s"', esc_attr( $alt ) ),
234 empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] ),
235 empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] )
236 );
237 }
238
239 /**
240 * Replace flag by custom flag
241 * Takes care of url scheme
242 *
243 * @since 1.7
244 */
245 public function set_custom_flag() {
246 // Overwrite with custom flags on frontend only
247 if ( ! empty( $this->custom_flag ) ) {
248 $this->flag = $this->custom_flag;
249 $this->flag_url = $this->custom_flag_url;
250 unset( $this->custom_flag, $this->custom_flag_url ); // hide this
251 }
252
253 // Set url scheme, also for default flags
254 $this->flag_url = set_url_scheme( $this->flag_url );
255 }
256
257 /**
258 * Updates post and term count
259 *
260 * @since 1.2
261 */
262 public function update_count() {
263 wp_update_term_count( $this->term_taxonomy_id, 'language' ); // posts count
264 wp_update_term_count( $this->tl_term_taxonomy_id, 'term_language' ); // terms count
265 }
266
267 /**
268 * Set home_url and search_url properties
269 *
270 * @since 1.3
271 *
272 * @param string $search_url
273 * @param string $home_url
274 */
275 public function set_home_url( $search_url, $home_url ) {
276 $this->search_url = $search_url;
277 $this->home_url = $home_url;
278 }
279
280 /**
281 * Set home_url scheme
282 * this can't be cached across pages
283 *
284 * @since 1.6.4
285 */
286 public function set_home_url_scheme() {
287 $this->home_url = set_url_scheme( $this->home_url );
288 $this->search_url = set_url_scheme( $this->search_url );
289 }
290
291 /**
292 * Returns the language locale
293 * Converts WP locales to W3C valid locales for display
294 *
295 * @since 1.8
296 *
297 * @param string $filter either 'display' or 'raw', defaults to raw
298 * @return string
299 */
300 public function get_locale( $filter = 'raw' ) {
301 return 'display' === $filter ? $this->w3c : $this->locale;
302 }
303 }
304