Completed
Pull Request — 2.x (#4068)
by Jory
04:54
created

PodsI18n::get_instance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package Pods
4
 * @since   2.7
5
 */
6
final class PodsI18n {
7
8
	/**
9
	 * @var PodsI18n Singleton instance
10
	 */
11
	private static $instance = null;
12
13
	/**
14
	 * @var array Key/value pairs with label/translation
15
	 */
16
	private static $strings = array();
17
18
	/**
19
	 * @var mixed Current language locale
20
	 */
21
	private static $current_language = null;
22
23
	/**
24
	 * @var mixed Current language data
25
	 */
26
	private static $current_language_data = null;
27
28
	/**
29
	 * Singleton handling for a basic pods_i18n() request
30
	 *
31
	 * @since 2.7
32
	 */
33
	private function __construct() {
34
		self::$instance = $this;
35
36
		// Hook all enqueue scripts actions
37
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
38
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
39
		add_action( 'login_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
40
	}
41
42
	/**
43
	 * Singleton handling for a basic pods_i18n() request
44
	 *
45
	 * @return \PodsI18n
46
	 *
47
	 * @since 2.7
48
	 */
49
	public static function get_instance() {
50
51
		// Initialize if the class hasn't been setup yet for some reason
52
		if ( ! is_object( self::$instance ) ) {
53
			self::$instance = new self();
54
		}
55
56
		return self::$instance;
57
	}
58
59
	/**
60
	 * @since 2.7
61
	 */
62
	public function enqueue_scripts() {
63
64
		// Register our i18n script for JS
65
		wp_register_script( 'pods-i18n', PODS_URL . 'ui/js/pods-i18n.js', array(), PODS_VERSION, true );
66
67
		self::localize_assets();
68
	}
69
70
	/**
71
	 * Localize assets:
72
	 *     * Build localizations strings from the defaults and those provided via filter
73
	 *     * Provide a global JavaScript object with the assembled localization strings via `wp_localize_script`
74
	 *
75
	 * @since 2.7
76
	 */
77
	private static function localize_assets() {
78
79
		/**
80
		 * Add strings to the localization
81
		 * Setting the key of your string to the original (non translated) value is mandatory
82
		 * Note: Existing keys in this class will overwrite the ones of this filter!
83
		 *
84
		 * @since 2.7
85
		 * @see   default_strings()
86
		 *
87
		 * @param array
88
		 *
89
		 * @return array format: 'Untranslated string' => 'Translated string with use of WP translate functions'
90
		 */
91
		$strings_extra = apply_filters( 'pods_localized_strings', array() );
92
93
		self::$strings = array_merge( $strings_extra, self::default_strings() );
94
95
		foreach ( self::$strings as $key => $str ) {
96
			self::register( $key, $str );
97
		}
98
99
		// Some other stuff we need to pass through
100
		$i18n_base = array(
101
			'debug' => ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG == true ) ? true : false,
102
		);
103
		// Add localization to our i18n script
104
		wp_localize_script( 'pods-i18n', 'podsLocalizedStrings', array_merge( self::$strings, $i18n_base ) );
105
	}
106
107
	/**
108
	 * Register function that creates the references and combines these with the translated strings
109
	 *
110
	 * @param string $string_key
111
	 * @param string $translation
112
	 *
113
	 * @since 2.7
114
	 */
115
	private static function register( $string_key, $translation ) {
116
117
		/**
118
		 * Converts string into reference object variable
119
		 * Uses the same logic as JS to create the same references
120
		 */
121
		$ref = '__' . $string_key;
122
123
		// Add it to the strings localized
124
		self::$strings[ $ref ] = $translation;
125
126
		// Remove the old key
127
		unset( self::$strings[ $string_key ] );
128
	}
129
130
	/**
131
	 * Register our labels to use in JS
132
	 * We need to register them as normal string to convert to JS references
133
	 * And we need to register the translations to attach to these references, these may not be variables!
134
	 *
135
	 * @return array Key/value pairs with label/translation
136
	 *
137
	 * @since 2.7
138
	 */
139
	private static function default_strings() {
140
141
		return array(
142
143
			'%s is required.' =>
144
				__( '%s is required.', 'pods' ),
145
146
			'This field is required.' =>
147
				__( 'This field is required.', 'pods' ),
148
149
			'Add' =>
150
				__( 'Add', 'pods' ),
151
152
			'Add New' =>
153
				__( 'Add New', 'pods' ),
154
155
			'Add New Record' =>
156
				__( 'Add New Record', 'pods' ),
157
158
			'Added!' =>
159
				__( 'Added!', 'pods' ),
160
161
			'Added! Choose another or <a href="#">close this box</a>' =>
162
				__( 'Added! Choose another or <a href="#">close this box</a>', 'pods' ),
163
164
			'Copy' =>
165
				__( 'Copy', 'pods' ),
166
167
			'Reorder' =>
168
				__( 'Reorder', 'pods' ),
169
170
			'Remove' =>
171
				__( 'Remove', 'pods' ),
172
173
			'Download' =>
174
				__( 'Download', 'pods' ),
175
176
			'View' =>
177
				__( 'View', 'pods' ),
178
179
			'Edit' =>
180
				__( 'Edit', 'pods' ),
181
182
			'Navigating away from this page will discard any changes you have made.' =>
183
				__( 'Navigating away from this page will discard any changes you have made.', 'pods' ),
184
185
			'Unable to process request, please try again.' =>
186
				__( 'Unable to process request, please try again.', 'pods' ),
187
188
			'There was an issue with the file upload, please try again.' =>
189
				__( 'There was an issue with the file upload, please try again.', 'pods' ),
190
191
			'Allowed Files' =>
192
				__( 'Allowed Files', 'pods' ),
193
194
			'The Title' =>
195
				__( 'The Title', 'pods' ),
196
197
			'Icon' =>
198
				__( 'Icon', 'pods' ),
199
200
		);
201
202
	}
203
204
	/**
205
	 * Get current locale information from Multilingual plugins
206
	 *
207
	 * @since 2.7
208
	 *
209
	 * @param array $args (optional) {
210
	 *     @type bool $refresh Rerun get_current_language() logic?
211
	 * }
212
	 *
213
	 * @return string
214
	 */
215
	public function get_current_language( $args = array() ) {
216
217
		$args = wp_parse_args( $args, array(
218
			'refresh' => false,
219
		) );
220
221
		if ( ! $args['refresh'] && ! empty( self::$current_language ) ) {
222
			return self::$current_language;
223
		}
224
225
		$this->get_current_language_data( $args );
226
		return self::$current_language;
227
	}
228
229
	/**
230
	 * Get current language information from Multilingual plugins
231
	 *
232
	 * @since 2.6.6
233
	 * @since 2.7 Moved to this class from PodsAPI
234
	 *
235
	 * @param array $args (optional) {
236
	 *     @type bool $refresh Rerun logic?
237
	 * }
238
	 *
239
	 * @return array
240
	 */
241
	public function get_current_language_data( $args = array() ) {
242
243
		$args = wp_parse_args( $args, array(
244
			'refresh' => false,
245
		) );
246
247
		if ( ! $args['refresh'] && ! empty( self::$current_language_data ) ) {
248
			return self::$current_language_data;
249
		}
250
251
		/**
252
		 * @var $sitepress SitePress object
253
		 * @var $polylang  Polylang object
254
		 */
255
		/*
256
		 * @todo wpml-comp Remove global object usage
257
		 */
258
		global $sitepress, $polylang;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
259
260
		$lang_data        = false;
261
		$translator       = false;
262
		$current_language = false;
263
264
		// Multilingual support
265
		if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
266
			// WPML support
267
			$translator = 'WPML';
268
269
			// Get the global current language (if set)
270
			$wpml_language = apply_filters( 'wpml_current_language', null );
271
			$current_language = ( $wpml_language != 'all' ) ? $wpml_language : '';
272
273
		} elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && function_exists( 'pll_current_language' ) ) {
274
			// Polylang support
275
			$translator = 'PLL';
276
277
			// Get the global current language (if set)
278
			$current_language = pll_current_language( 'slug' );
279
		}
280
281
		/**
282
		 * Admin functions that overwrite the current language
283
		 *
284
		 * @since 2.6.6
285
		 */
286
		if ( is_admin() && ! empty( $translator ) ) {
287
			if ( $translator == 'PLL' ) {
288
				/**
289
				 * Polylang support
290
				 * Get the current user's preferred language.
291
				 * This is a user meta setting that will overwrite the language returned from pll_current_language()
292
				 * @see polylang/admin/admin-base.php -> init_user()
293
				 */
294
				$current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true );
295
			}
296
297
			// Get current language based on the object language if available
298
			if ( function_exists( 'get_current_screen' ) ) {
299
				$current_screen = get_current_screen();
300
301
				/**
302
				 * Overwrite the current language if needed for post types
303
				 */
304
				if ( isset( $current_screen->base ) && ( $current_screen->base == 'post' || $current_screen->base == 'edit' ) ) {
305
					if ( ! empty( $_GET['post'] ) ) {
306
						/**
307
						 * WPML support
308
						 * In WPML the current language is always set to default on an edit screen
309
						 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
310
						 */
311
						if (   $translator == 'WPML'
312
						       && ! apply_filters( 'wpml_is_translated_post_type', false, ( get_post_type( $_GET['post'] ) ) )
313
						) {
314
							// Overwrite the current language to nothing if this is a NOT-translatable post_type
315
							$current_language = '';
316
						}
317
318
						/**
319
						 * Polylang support (1.5.4+)
320
						 * In polylang the preferred language could be anything.
321
						 * We only want the related objects if they are not translatable OR the same language as the current object
322
						 */
323
						if (   $translator == 'PLL'
324
						       && function_exists( 'pll_get_post_language' )
325
						       && pll_is_translated_post_type( get_post_type( $_GET['post'] ) )
326
						) {
327
							// Overwrite the current language if this is a translatable post_type
328
							$current_language = pll_get_post_language( (int) $_GET['post'] );
329
						}
330
					}
331
332
					/**
333
					 * Polylang support (1.0.1+)
334
					 * In polylang the preferred language could be anything.
335
					 * 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
336
					 */
337 View Code Duplication
					if (   $translator == 'PLL'
338
					       && ! empty( $_GET['new_lang'] )
339
					       && ! empty( $_GET['post_type'] )
340
					       && pll_is_translated_post_type( sanitize_text_field( $_GET['post_type'] ) )
341
					) {
342
						$current_language = $_GET['new_lang'];
343
					}
344
345
					/**
346
					 * Overwrite the current language if needed for taxonomies
347
					 */
348
				} elseif ( isset( $current_screen->base ) && ( $current_screen->base == 'term' || $current_screen->base == 'edit-tags' ) ) {
349
					// @todo MAYBE: Similar function like get_post_type for taxonomies so we don't need to check for $_GET['taxonomy']
350
					if ( ! empty( $_GET['taxonomy'] ) ) {
351
						/*
352
						 * @todo wpml-comp API call for taxonomy needed!
353
						 * Suggested API call:
354
						 * add_filter( 'wpml_is_translated_taxonomy', $_GET['taxonomy'], 10, 2 );
355
						 */
356
						/**
357
						 * WPML support
358
						 * In WPML the current language is always set to default on an edit screen
359
						 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
360
						 */
361
						if (   $translator == 'WPML'
362
						       && method_exists( $sitepress, 'is_translated_taxonomy')
363
						       && ! $sitepress->is_translated_taxonomy( $_GET['taxonomy'] )
364
						) {
365
							// Overwrite the current language to nothing if this is a NOT-translatable taxonomy
366
							$current_language = '';
367
						}
368
369
						/**
370
						 * Polylang support (1.5.4+)
371
						 * In polylang the preferred language could be anything.
372
						 * We only want the related objects if they are not translatable OR the same language as the current object
373
						 */
374
						if (   $translator == 'PLL'
375
						       && ! empty( $_GET['tag_ID'] )
376
						       && function_exists( 'pll_get_term_language' )
377
						       && pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) )
378
						) {
379
							// Overwrite the current language if this is a translatable taxonomy
380
							$current_language = pll_get_term_language( (int) $_GET['tag_ID'] );
381
						}
382
					}
383
384
					/**
385
					 * Polylang support (1.0.1+)
386
					 * In polylang the preferred language could be anything.
387
					 * 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
388
					 */
389 View Code Duplication
					if (   $translator == 'PLL'
390
					       && ! empty( $_GET['new_lang'] )
391
					       && ! empty( $_GET['taxonomy'] )
392
					       && pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) )
393
					) {
394
						$current_language = $_GET['new_lang'];
395
					}
396
				}
397
			}
398
		}
399
400
		$current_language = pods_sanitize( sanitize_text_field( $current_language ) );
401
402
		if ( ! empty( $current_language ) ) {
403
			// We need to return language data
404
			$lang_data = array(
405
				'language' => $current_language,
406
				't_id'     => 0,
407
				'tt_id'    => 0,
408
				'term'     => null,
409
			);
410
411
			/**
412
			 * Polylang support
413
			 * Get the language taxonomy object for the current language
414
			 */
415
			if ( $translator == 'PLL' ) {
416
				$current_language_t = false;
417
418
				// Get the language term object
419
				if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) {
420
					// Polylang 1.8 and newer
421
					$current_language_t = PLL()->model->get_language( $current_language );
422
				} elseif ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) {
423
					// Polylang 1.2 - 1.7.x
424
					$current_language_t = $polylang->model->get_language( $current_language );
425
				} elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) {
426
					// Polylang 1.1.x and older
427
					$current_language_t = $polylang->get_language( $current_language );
428
				}
429
430
				// If the language object exists, add it!
431
				if ( $current_language_t && ! empty( $current_language_t->term_id ) ) {
432
					$lang_data['t_id']  = (int) $current_language_t->term_id;
433
					$lang_data['tt_id'] = (int) $current_language_t->term_taxonomy_id;
434
					$lang_data['tl_t_id'] = (int) $current_language_t->tl_term_id;
435
					$lang_data['tl_tt_id'] = (int) $current_language_t->tl_term_taxonomy_id;
436
					$lang_data['term']  = $current_language_t;
437
				}
438
			}
439
		}
440
441
		/**
442
		 * Override language data used by Pods.
443
		 *
444
		 * @since 2.6.6
445
		 *
446
		 * @param array|false    $lang_data {
447
		 *      Language data
448
		 *
449
		 *      @type string       $language  Language slug
450
		 *      @type int          $t_id      Language term_id
451
		 *      @type int          $tt_id     Language term_taxonomy_id
452
		 *      @type WP_Term      $term      Language term object
453
		 * }
454
		 * @param string|boolean $translator Language plugin used
455
		 */
456
		$lang_data = apply_filters( 'pods_get_current_language', $lang_data, $translator );
457
458
		self::$current_language = $lang_data['language'];
459
		self::$current_language_data = $lang_data;
460
461
		return $lang_data;
462
463
	}
464
465
}
466