PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.7.31.4
Pods – Custom Content Types and Fields v2.7.31.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / classes / PodsI18n.php
pods / classes Last commit date
cli 2 days ago fields 2 days ago widgets 2 days ago Pods.php 2 days ago PodsAPI.php 2 days ago PodsAdmin.php 2 days ago PodsArray.php 2 days ago PodsComponent.php 2 days ago PodsComponents.php 2 days ago PodsData.php 2 days ago PodsField.php 2 days ago PodsForm.php 2 days ago PodsI18n.php 2 days ago PodsInit.php 2 days ago PodsMeta.php 2 days ago PodsMigrate.php 2 days ago PodsRESTFields.php 2 days ago PodsRESTHandlers.php 2 days ago PodsTermSplitting.php 2 days ago PodsUI.php 2 days ago PodsView.php 2 days ago
PodsI18n.php
520 lines
1 <?php
2
3 /**
4 * @package Pods
5 * @since 2.7.0
6 */
7 final class PodsI18n {
8
9 /**
10 * @var PodsI18n Singleton instance
11 */
12 private static $instance = null;
13
14 /**
15 * @var array Key/value pairs with label/translation
16 */
17 private static $strings = array();
18
19 /**
20 * @var mixed Current language locale
21 */
22 private static $current_language = null;
23
24 /**
25 * @var mixed Current language data
26 */
27 private static $current_language_data = null;
28
29 /**
30 * Singleton handling for a basic pods_i18n() request
31 *
32 * @since 2.7.0
33 */
34 private function __construct() {
35
36 self::$instance = $this;
37
38 // Hook all enqueue scripts actions
39 add_action( 'pods_before_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
40
41 // Polylang
42 add_filter( 'pll_get_post_types', array( $this, 'pll_get_post_types' ), 10, 2 );
43 }
44
45 /**
46 * Singleton handling for a basic pods_i18n() request
47 *
48 * @return \PodsI18n
49 *
50 * @since 2.7.0
51 */
52 public static function get_instance() {
53
54 // Initialize if the class hasn't been setup yet for some reason
55 if ( ! is_object( self::$instance ) ) {
56 self::$instance = new self();
57 }
58
59 return self::$instance;
60 }
61
62 /**
63 * @since 2.7.0
64 */
65 public function enqueue_scripts() {
66
67 // Register our i18n script for JS
68 wp_register_script( 'sprintf', PODS_URL . 'ui/js/sprintf/sprintf.min.js', array(), '1.1.0', true );
69 wp_register_script( 'pods-i18n', PODS_URL . 'ui/js/pods-i18n.js', array( 'sprintf' ), PODS_VERSION, true );
70
71 self::localize_assets();
72 }
73
74 /**
75 * Localize assets:
76 * * Build localizations strings from the defaults and those provided via filter
77 * * Provide a global JavaScript object with the assembled localization strings via `wp_localize_script`
78 *
79 * @since 2.7.0
80 */
81 private static function localize_assets() {
82
83 /**
84 * Add strings to the localization
85 * Setting the key of your string to the original (non translated) value is mandatory
86 * Note: Existing keys in this class will overwrite the ones of this filter!
87 *
88 * @since 2.7.0
89 * @see default_strings()
90 *
91 * @param array
92 *
93 * @return array format: 'Untranslated string' => 'Translated string with use of WP translate functions'
94 */
95 $strings_extra = apply_filters( 'pods_localized_strings', array() );
96
97 self::$strings = array_merge( $strings_extra, self::default_strings() );
98
99 foreach ( self::$strings as $key => $str ) {
100 self::register( $key, $str );
101 }
102
103 // Some other stuff we need to pass through.
104 $i18n_base = array(
105 'debug' => ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG == true ) ? true : false,
106 );
107 // Add localization to our i18n script
108 wp_localize_script( 'pods-i18n', 'podsLocalizedStrings', array_merge( self::$strings, $i18n_base ) );
109 }
110
111 /**
112 * Register function that creates the references and combines these with the translated strings
113 *
114 * @param string $string_key
115 * @param string $translation
116 *
117 * @since 2.7.0
118 */
119 private static function register( $string_key, $translation ) {
120
121 /**
122 * Converts string into reference object variable
123 * Uses the same logic as JS to create the same references
124 */
125 $ref = '__' . $string_key;
126
127 // Add it to the strings localized
128 self::$strings[ $ref ] = $translation;
129
130 // Remove the old key
131 unset( self::$strings[ $string_key ] );
132 }
133
134 /**
135 * Register our labels to use in JS
136 * We need to register them as normal string to convert to JS references
137 * And we need to register the translations to attach to these references, these may not be variables!
138 *
139 * @return array Key/value pairs with label/translation
140 *
141 * @since 2.7.0
142 */
143 private static function default_strings() {
144
145 return array(
146
147 // Translators: %s stands for a name/identifier.
148 '%s is required.' => __( '%s is required.', 'pods' ),
149
150 'This field is required.' => __( 'This field is required.', 'pods' ),
151
152 'Add' => __( 'Add', 'pods' ),
153
154 'Add New' => __( 'Add New', 'pods' ),
155
156 'Add New Record' => __( 'Add New Record', 'pods' ),
157
158 'Added!' => __( 'Added!', 'pods' ),
159
160 'Added! Choose another or <a href="#">close this box</a>' => __( 'Added! Choose another or <a href="#">close this box</a>', 'pods' ),
161
162 'Copy' => __( 'Copy', 'pods' ),
163
164 'Reorder' => __( 'Reorder', 'pods' ),
165
166 'Remove' => __( 'Remove', 'pods' ),
167
168 'Deselect' => __( 'Deselect', 'pods' ),
169
170 'Download' => __( 'Download', 'pods' ),
171
172 'View' => __( 'View', 'pods' ),
173
174 'Edit' => __( 'Edit', 'pods' ),
175
176 'Search' => __( 'Search', 'pods' ),
177
178 // Translators: %s stands for a name/identifier.
179 'Search %s' => __( 'Search %s', 'pods' ),
180
181 'Navigating away from this page will discard any changes you have made.' => __( 'Navigating away from this page will discard any changes you have made.', 'pods' ),
182
183 'Some fields have changes that were not saved yet, please save them or cancel the changes before saving the Pod.' => __( 'Some fields have changes that were not saved yet, please save them or cancel the changes before saving the Pod.', 'pods' ),
184
185 'Unable to process request, please try again.' => __( 'Unable to process request, please try again.', 'pods' ),
186
187 'Error uploading file: ' => __( 'Error uploading file: ', 'pods' ),
188
189 'Allowed Files' => __( 'Allowed Files', 'pods' ),
190
191 'The Title' => __( 'The Title', 'pods' ),
192
193 'Select from existing' => __( 'Select from existing', 'pods' ),
194
195 'You can only select' => __( 'You can only select', 'pods' ),
196
197 // Translators: %s stands for a number.
198 '%s item' => __( '%s item', 'pods' ),
199
200 // Translators: %s stands for a number.
201 '%s items' => __( '%s items', 'pods' ),
202
203 // Translators: %s stands for a number.
204 'You can only select %s item' => __( 'You can only select %s item', 'pods' ),
205
206 // Translators: %s stands for a number.
207 'You can only select %s items' => __( 'You can only select %s items', 'pods' ),
208
209 'Icon' => __( 'Icon', 'pods' ),
210
211 );
212
213 }
214
215 /**
216 * Get current locale information from Multilingual plugins
217 *
218 * @since 2.7.0
219 *
220 * @param array $args (optional) {
221 *
222 * @type bool $refresh Rerun get_current_language() logic?
223 * }
224 *
225 * @return string
226 */
227 public function get_current_language( $args = array() ) {
228
229 $defaults = array(
230 'refresh' => false,
231 );
232
233 $args = wp_parse_args( $args, $defaults );
234
235 if ( ! $args['refresh'] && ! empty( self::$current_language ) ) {
236 return self::$current_language;
237 }
238
239 $this->get_current_language_data( $args );
240
241 return self::$current_language;
242 }
243
244 /**
245 * Get current language information from Multilingual plugins
246 *
247 * @since 2.6.6
248 * @since 2.7 Moved to this class from PodsAPI
249 *
250 * @param array $args (optional) {
251 *
252 * @type bool $refresh Rerun logic?
253 * }
254 *
255 * @return array
256 */
257 public function get_current_language_data( $args = array() ) {
258
259 $defaults = array(
260 'refresh' => false,
261 );
262
263 $args = wp_parse_args( $args, $defaults );
264
265 if ( ! $args['refresh'] && ! empty( self::$current_language_data ) ) {
266 return self::$current_language_data;
267 }
268
269 /**
270 * @var \SitePress $sitepress object
271 * @var \Polylang $polylang object
272 */
273 /*
274 * @todo wpml-comp Remove global object usage
275 */
276 global $sitepress, $polylang;
277
278 $lang_data = false;
279 $translator = false;
280 $current_language = false;
281
282 // Multilingual support.
283 if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
284 // WPML support.
285 $translator = 'WPML';
286
287 // Get the global current language (if set).
288 $wpml_language = apply_filters( 'wpml_current_language', null );
289 $current_language = ( 'all' !== $wpml_language ) ? $wpml_language : '';
290
291 } elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && function_exists( 'pll_current_language' ) ) {
292 // Polylang support.
293 $translator = 'PLL';
294
295 // Get the global current language (if set).
296 $current_language = pll_current_language( 'slug' );
297 }
298
299 /**
300 * Admin functions that overwrite the current language.
301 *
302 * @since 2.6.6
303 */
304 if ( is_admin() && ! empty( $translator ) ) {
305 if ( 'PLL' === $translator ) {
306 /**
307 * Polylang support.
308 * Get the current user's preferred language.
309 * This is a user meta setting that will overwrite the language returned from pll_current_language().
310 *
311 * @see \PLL_Admin_Base::init_user() (polylang/admin/admin-base.php)
312 */
313 $current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true );
314 }
315
316 $pods_ajax = pods_v( 'pods_ajax', 'request', false );
317
318 // Get current language based on the object language if available.
319 $page = basename( pods_v( 'SCRIPT_NAME', $_SERVER, '' ) );
320 if ( $pods_ajax && 'admin-ajax.php' === $page ) {
321 $page = basename( pods_v( 'HTTP_REFERER', $_SERVER, '' ) );
322 }
323 $page = explode( '?', $page );
324 $page = reset( $page );
325
326 /**
327 * Overwrite the current language if needed for post types.
328 */
329 if ( 'post.php' === $page || 'edit.php' === $page ) {
330
331 $current_post = (int) pods_v( 'post', 'request', 0 );
332 if ( $pods_ajax ) {
333 $current_post = (int) pods_v( 'id', 'request', $current_post );
334 }
335
336 if ( $current_post ) {
337
338 $current_post_type = get_post_type( $current_post );
339
340 /**
341 * WPML support.
342 * In WPML the current language is always set to default on an edit screen.
343 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages.
344 */
345 if ( 'WPML' === $translator && ! apply_filters( 'wpml_is_translated_post_type', false, $current_post_type ) ) {
346 // Overwrite the current language to nothing if this is a NOT-translatable post_type.
347 $current_language = '';
348 }
349
350 /**
351 * Polylang support.
352 * In polylang the preferred language could be anything.
353 */
354 if ( 'PLL' === $translator && pll_is_translated_post_type( $current_post_type ) ) {
355
356 /**
357 * Polylang (1.5.4+).
358 * We only want the related objects if they are not translatable OR the same language as the current object.
359 */
360 if ( function_exists( 'pll_get_post_language' ) ) {
361 // Overwrite the current language if this is a translatable post_type.
362 $current_language = pll_get_post_language( $current_post );
363 }
364
365 /**
366 * Polylang (1.0.1+).
367 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language.
368 */
369 $current_language = pods_v( 'new_lang', 'request', $current_language );
370 }
371 }
372 } //end if
373
374 /**
375 * Overwrite the current language if needed for taxonomies.
376 */
377 elseif ( 'term.php' === $page || 'edit-tags.php' === $page ) {
378
379 $current_term_id = pods_v( 'tag_ID', 'request', 0 );
380 if ( $pods_ajax ) {
381 $current_term_id = (int) pods_v( 'id', 'request', $current_term_id );
382 }
383
384 $current_taxonomy = pods_v( 'taxonomy', 'request', '' );
385 if ( ! $current_taxonomy && $current_term_id ) {
386 $current_taxonomy = pods_v( 'taxonomy', get_term( $current_term_id ), null );
387 }
388
389 // @todo MAYBE: Similar function like get_post_type for taxonomies so we don't need to check for $_GET['taxonomy']
390 if ( $current_taxonomy ) {
391
392 /*
393 * @todo wpml-comp API call for taxonomy needed!
394 * Suggested API call:
395 * add_filter( 'wpml_is_translated_taxonomy', $_GET['taxonomy'], 10, 2 );
396 */
397 /**
398 * WPML support.
399 * In WPML the current language is always set to default on an edit screen.
400 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages.
401 */
402 if ( 'WPML' === $translator && method_exists( $sitepress, 'is_translated_taxonomy' ) && ! $sitepress->is_translated_taxonomy( $current_taxonomy ) ) {
403 // Overwrite the current language to nothing if this is a NOT-translatable taxonomy.
404 $current_language = '';
405 }
406
407 /**
408 * Polylang support.
409 * In polylang the preferred language could be anything.
410 */
411 if ( 'PLL' === $translator && pll_is_translated_taxonomy( $current_taxonomy ) ) {
412
413 /**
414 * Polylang (1.5.4+).
415 * We only want the related objects if they are not translatable OR the same language as the current object.
416 */
417 if ( $current_term_id && function_exists( 'pll_get_term_language' ) ) {
418 // Overwrite the current language if this is a translatable taxonomy
419 $current_language = pll_get_term_language( $current_term_id );
420 }
421
422 /**
423 * Polylang (1.0.1+).
424 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language.
425 */
426 $current_language = pods_v( 'new_lang', 'request', $current_language );
427 }
428 }//end if
429 }//end if
430
431 }//end if (admin)
432
433 $current_language = pods_sanitize( sanitize_text_field( $current_language ) );
434
435 if ( ! empty( $current_language ) ) {
436 // We need to return language data
437 $lang_data = array(
438 'language' => $current_language,
439 't_id' => 0,
440 'tt_id' => 0,
441 'term' => null,
442 );
443
444 /**
445 * Polylang support.
446 * Get the language taxonomy object for the current language.
447 */
448 if ( 'PLL' === $translator ) {
449 $current_language_t = false;
450
451 // Get the language term object.
452 if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) {
453 // Polylang 1.8 and newer.
454 $current_language_t = PLL()->model->get_language( $current_language );
455 } elseif ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) {
456 // Polylang 1.2 - 1.7.x
457 $current_language_t = $polylang->model->get_language( $current_language );
458 } elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) {
459 // Polylang 1.1.x and older.
460 $current_language_t = $polylang->get_language( $current_language );
461 }
462
463 // If the language object exists, add it!
464 if ( $current_language_t && ! empty( $current_language_t->term_id ) ) {
465 $lang_data['t_id'] = (int) $current_language_t->term_id;
466 $lang_data['tt_id'] = (int) $current_language_t->term_taxonomy_id;
467 $lang_data['tl_t_id'] = (int) $current_language_t->tl_term_id;
468 $lang_data['tl_tt_id'] = (int) $current_language_t->tl_term_taxonomy_id;
469 $lang_data['term'] = $current_language_t;
470 }
471 }//end if
472 }//end if
473
474 /**
475 * Override language data used by Pods.
476 *
477 * @since 2.6.6
478 *
479 * @param array|false $lang_data {
480 * Language data
481 * @type string $language Language slug
482 * @type int $t_id Language term_id
483 * @type int $tt_id Language term_taxonomy_id
484 * @type WP_Term $term Language term object
485 * }
486 *
487 * @param string|boolean $translator Language plugin used.
488 */
489 $lang_data = apply_filters( 'pods_get_current_language', $lang_data, $translator );
490
491 if ( $lang_data ) {
492 self::$current_language = $lang_data['language'];
493 self::$current_language_data = $lang_data;
494 }
495
496 return $lang_data;
497
498 }
499
500 /**
501 * Add Pods templates to possible i18n enabled post-types (polylang settings).
502 *
503 * @since 2.7.0
504 *
505 * @param array $post_types
506 * @param bool $is_settings
507 *
508 * @return array mixed
509 */
510 public function pll_get_post_types( $post_types, $is_settings = false ) {
511
512 if ( $is_settings ) {
513 $post_types['_pods_template'] = '_pods_template';
514 }
515
516 return $post_types;
517 }
518
519 }
520