Completed
Pull Request — 2.x (#4370)
by
unknown
05:02
created

Pods_Component_I18n::init()   F

Complexity

Conditions 23
Paths 1176

Size

Total Lines 100
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 44
nc 1176
nop 0
dl 0
loc 100
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 24 and the first side effect is on line 19.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Name: Translate Pods Admin
4
 *
5
 * Menu Name: Translate Pods
6
 *
7
 * Description: Allow UI of Pods and fields to be translated
8
 *
9
 * Version: 0.1
10
 *
11
 * Category: I18n
12
 *
13
 * Class: Pods_Component_I18n
14
 *
15
 * @package Pods\Components
16
 * @subpackage i18n
17
 */
18
19
! defined( 'ABSPATH' ) and die();
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
20
21
if ( class_exists( 'Pods_Component_I18n' ) )
22
	return;
23
24
class Pods_Component_I18n extends PodsComponent {
25
26
	public $settings = array();
27
	public $locale = null;
28
	public $languages = array();
29
	public $languages_available = array();
30
	public $languages_translated = array();
31
	public $cur_pod = null;
32
	public $option_key = 'pods_component_i18n_settings';
33
	public $admin_page = 'pods-component-translate-pods-admin';
34
	public $capability = 'pods_i18n_activate_lanuages';
35
	public $nonce = 'pods_i18n_activate_lanuages';
36
37
	public $translatable_fields = array(
38
		'label',
39
		'description',
40
		'placeholder',
41
		'menu_name',
42
		'name_admin_bar',
43
		'pick_select_text',
44
		'file_add_button',
45
		'file_modal_title',
46
		'file_modal_add_button',
47
	);
48
49
	/**
50
	 * Get mandatory data and add actions
51
	 *
52
	 * @since 0.1
53
	 */
54
	public function __construct () {
55
		$this->init();
56
	}
57
58
	/**
59
	 * Init function to register data, hooks and resources
60
	 * @since 0.1
61
	 */
62
	public function init() {
63
		$this->settings = get_option( $this->option_key, array() );
64
65
		// Polylang
66
		if ( function_exists( 'PLL' ) && file_exists( plugin_dir_path( __FILE__ ) . 'I18n-polylang.php' ) ) {
67
			include_once( plugin_dir_path( __FILE__ ) . 'I18n-polylang.php' );
68
		}
69
		// WPML
70
		if ( did_action( 'wpml_loaded' ) && file_exists( plugin_dir_path( __FILE__ ) . 'I18n-wpml.php' ) ) {
71
			include_once( plugin_dir_path( __FILE__ ) . 'I18n-wpml.php' );
72
		}
73
74
		$active = false;
75
		// Are there active languages?
76
		if ( ! empty( $this->settings['enabled_languages'] ) ) {
77
			$this->languages = $this->settings['enabled_languages'];
78
			$this->locale = get_locale();
79
			$active = true;
80
		}
81
82
		$is_component_page = false;
83
		$is_pods_edit_page = false;
84
		if ( is_admin() && isset( $_GET['page'] ) ) {
85
86
			// Is the current page the admin page of this component or a Pods edit page?
87
			if ( $_GET['page'] === $this->admin_page ) {
88
				$is_component_page = true;
89
			} elseif ( $_GET['page'] === 'pods' ) {
90
				$is_pods_edit_page = true;
91
			}
92
93
			if ( $is_component_page || ( $is_pods_edit_page && $active ) ) {
94
				add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
95
			}
96
		}
97
98
		if ( $is_component_page ) {
99
			// Do save action here because otherwise the loading of post_types get done first and labels aren't translated
100
			if ( pods_is_admin( $this->capability )
101
			    && isset( $_POST['_nonce_i18n'] )
102
			    && wp_verify_nonce( $_POST['_nonce_i18n'], $this->nonce )
103
			) {
104
				$this->admin_save();
105
			}
106
		}
107
108
		if ( $active ) {
109
			// WP Object filters (post_type and taxonomy)
110
			add_filter( 'pods_register_post_type', array( $this, 'pods_register_wp_object_i18n' ), 10, 2 );
111
			add_filter( 'pods_register_taxonomy', array( $this, 'pods_register_wp_object_i18n' ), 10, 2 );
112
113
			// ACT's
114
			add_filter( 'pods_advanced_content_type_pod_data', array( $this, 'pods_filter_object_strings_i18n' ), 10, 2 );
115
116
			// Setting pages
117
			add_filter( 'pods_admin_menu_page_title', array( $this, 'admin_menu_page_title_i18n' ), 10, 2 );
118
			add_filter( 'pods_admin_menu_label', array( $this, 'admin_menu_label_i18n' ), 10, 2 );
119
120
			// Default filters for all fields
121
			add_filter( 'pods_form_ui_label_text', array( $this, 'fields_ui_label_text_i18n' ), 10, 4 );
122
			add_filter( 'pods_form_ui_comment_text', array( $this, 'fields_ui_comment_text_i18n' ), 10, 3 );
123
124
			foreach ( pods_form()->field_types() as $type => $data ) {
125
				add_filter( 'pods_form_ui_field_' . $type . '_options', array( $this, 'form_ui_field_options_i18n' ), 10, 5 );
126
			}
127
128
			// Field specific
129
			//add_filter( 'pods_field_pick_data', array( $this, 'field_pick_data_i18n' ), 10, 6 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
130
131
			if ( $is_pods_edit_page ) {
132
133
				$pod = null;
134
				// Get the pod if available
135
				if ( isset( $_GET['id'] ) && is_numeric( $_GET['id'] ) ) {
136
					$pod = pods_api()->load_pod( array( 'id' => $_GET['id'] ) );
137
					// Append options to root array for pods_v function to work
138
					foreach ( $pod[ 'options' ] as $_option => $_value ) {
139
						$pod[ $_option ] = $_value;
140
					}
141
				}
142
				$this->cur_pod = $pod;
143
144
				//Add option tab for post types
145
				//add_filter( 'pods_admin_setup_edit_tabs_post_type', array( $this, 'pod_tab' ), 11, 3 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
146
147
				//Add the same tab for taxonomies
148
				//add_filter( 'pods_admin_setup_edit_tabs_taxonomy', array( $this, 'pod_tab' ), 11, 3 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
149
150
				//Add options to the new tab
151
				//add_filter( 'pods_admin_setup_edit_options', array( $this, 'pod_options' ), 12, 2 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
152
153
				//Add options metabox to the pod edit screens
154
				add_action( 'pods_add_meta_boxes', array( $this, 'admin_meta_box' ) );
155
156
				//Add the i18n input fields based on existing fields
157
				add_filter( 'pods_form_ui_field_text', array( $this, 'add_i18n_inputs' ), 10, 6 );
158
			}
159
160
		}
161
	}
162
163
	/**
164
	 * Load assets for this component
165
	 * @since 0.1
166
	 */
167
	public function admin_assets() {
168
		wp_enqueue_script( 'pods-admin-i18n', PODS_URL . 'components/I18n/pods-admin-i18n.js', array( 'jquery', 'pods-i18n' ), '1.0', true );
169
		$localize_script = array();
170
		if ( ! empty( $this->languages ) ) {
171
			foreach ( $this->languages as $lang => $lang_data ) {
172
				$lang_label = $this->create_lang_label( $lang_data );
173
				if ( ! empty( $lang_label ) ) {
174
					$lang_label = $lang . ' ('. $lang_label .')';
175
				} else {
176
					$lang_label = $lang;
177
				}
178
				$localize_script[ $lang ] = $lang_label;
179
			}
180
		}
181
		wp_localize_script( 'pods-admin-i18n', 'pods_admin_i18n_strings', $localize_script );
182
183
		// Add strings to the i18n js object
184
		add_filter( 'pods_localized_strings', array( $this, 'localize_assets' ) );
185
	}
186
187
	/**
188
	 * Localize the assets
189
	 * @param  array  $str  Existing strings
190
	 * @return array
191
	 */
192
	public function localize_assets( $str ) {
193
		$str['Add translation'] = __( 'Add translation', 'pods' );
194
		$str['Toggle translations'] = __( 'Toggle translations', 'pods' );
195
		$str['Show translations'] = __( 'Show translations', 'pods' );
196
		$str['Hide translations'] = __( 'Hide translations', 'pods' );
197
		$str['Select'] = __( 'Select', 'pods' );
198
		return $str;
199
	}
200
201
	/**
202
	 * Check is a field name is set for translation
203
	 *
204
	 * @since 0.1
205
	 * @param string $name
206
	 * @return bool
207
	 */
208
	public function is_translatable_field( $name ) {
209
210
		$translatable_fields = $this->get_translatable_fields();
211
212
		// All fields that start with "label"
213
		if ( strpos( $name, 'label' ) === 0 ) {
214
			return true;
215
		}
216
		// All translatable fields
217
		if ( in_array( $name, $translatable_fields ) ) {
218
			return true;
219
		}
220
		// Custom fields data, the name must begin with field_data[
221
		if ( strpos( $name, 'field_data[' ) === 0 ) {
222
			$name = str_replace( 'field_data[', '', $name );
223
			$name = rtrim( $name, ']' );
224
			$name = explode( '][', $name );
225
			$name = end( $name );
226
			// All translatable fields from field_data[ (int) ][ $name ]
227
			if ( in_array( $name, $translatable_fields ) ) {
228
				return true;
229
			}
230
		}
231
		return false;
232
	}
233
234
	/**
235
	 * Get a translated option for a field key (if available)
236
	 *
237
	 * @since  0.1
238
	 * @param  string $current Current value
239
	 * @param  string $key     The key / opion name to search for
240
	 * @param  array  $data    Pod data (can also be an options array of a pod or field)
241
	 * @return string
242
	 */
243
	public function get_value_translation( $current, $key, $data ) {
244
		$locale = $this->locale;
245
		// Validate locale and pod
246
		if ( is_array( $data ) && array_key_exists( $locale, $this->languages ) && $this->obj_is_language_enabled( $locale, $data ) ) {
247
			// Add option keys to $data array
248
			if ( ! empty( $data['options'] ) ) {
249
				$data = array_merge( $data, $data['options'] );
250
			}
251
			// Check if the i18n option exists and isn't empty
252
			if ( ! empty( $data[ $key . '_' . $locale ] ) ) {
253
				return (string) $data[ $key . '_' . $locale ];
254
			}
255
		}
256
		return $current;
257
	}
258
259
	/**
260
	 * Page title for setting pages
261
	 *
262
	 * @since  0.1
263
	 * @see    PodsAdmin.php >> admin_menu()
264
	 * @see    PodsAdmin.php >> admin_content_settings()
265
	 * @param  string $page_title Current page title
266
	 * @param  array  $pod        Pod data
267
	 * @return string
268
	 */
269
	public function admin_menu_page_title_i18n( $page_title, $pod ) {
270
		return (string) $this->get_value_translation( $page_title, 'label', $pod );
271
	}
272
273
	/**
274
	 * Menu title for setting pages
275
	 *
276
	 * @since  0.1
277
	 * @see    PodsAdmin.php >> admin_menu()
278
	 * @param  string $menu_label Current menu label
279
	 * @param  array  $pod        Pod data
280
	 * @return string
281
	 */
282
	public function admin_menu_label_i18n( $menu_label, $pod ) {
283
		return (string) $this->get_value_translation( $menu_label, 'menu_name', $pod );
284
	}
285
286
	/**
287
	 * Returns the translated label if available
288
	 *
289
	 * @since  0.1
290
	 * @see    PodsForm.php >> 'pods_form_ui_label_text' (filter)
291
	 * @param  string $label   The default label
292
	 * @param  string $name    The field name
293
	 * @param  string $help    The help text
294
	 * @param  array  $options The field options
295
	 * @return string
296
	 */
297
	public function fields_ui_label_text_i18n( $label, $name, $help, $options ) {
298
		return (string) $this->get_value_translation( $label, 'label', $options );
299
	}
300
301
	/**
302
	 * Returns the translated description if available
303
	 *
304
	 * @since  0.1
305
	 * @see    PodsForm.php >> 'pods_form_ui_comment_text' (filter)
306
	 * @param  string $message The default description
307
	 * @param  string $name    The field name
308
	 * @param  array  $options The field options
309
	 * @return string
310
	 */
311
	public function fields_ui_comment_text_i18n( $message, $name, $options ) {
312
		return (string) $this->get_value_translation( $message, 'description', $options );
313
	}
314
315
	/**
316
	 * Replaces the default selected text with a translation if available
317
	 *
318
	 * @since  0.1
319
	 * @see    pick.php >> 'pods_field_pick_data' (filter)
320
	 * @param  array  $data    The default data of the field
321
	 * @param  string $name    The field name
322
	 * @param  string $value   The field value
323
	 * @param  array  $options The field options
324
	 * @param  array  $pod     The Pod
325
	 * @param  int    $id      The field ID
326
	 * @return array
327
	 */
328
	public function field_pick_data_i18n( $data, $name, $value, $options, $pod, $id ) {
329
		if ( isset( $data[''] ) && isset( $options['pick_select_text'] ) ) {
330
			$locale = $this->locale;
331
			if (   isset( $options['pick_select_text_' . $locale ] )
332
				&& array_key_exists( $locale, $this->languages )
333
				&& $this->obj_is_language_enabled( $locale, $pod )
334
			) {
335
				$data[''] = $options['pick_select_text_' . $locale ];
336
			}
337
		}
338
		return $data;
339
	}
340
341
	/**
342
	 * Replaces the default values with a translation if available
343
	 *
344
	 * @since  0.1
345
	 * @see    PodsForm.php >> 'pods_form_ui_field_' . $type . '_options' (filter)
346
	 * @param  array  $options The field options
347
	 * @param  string $name    The field name
348
	 * @param  string $value   The field value
349
	 * @param  array  $pod     The Pod
350
	 * @param  int    $id      The field ID
351
	 * @return array
352
	 */
353
	public function form_ui_field_options_i18n( $options, $name, $value, $pod, $id ) {
354
		foreach ( $this->get_translatable_fields() as $field ) {
355
			$locale = $this->locale;
356
			if (   isset( $options[ $field . '_' . $locale ] )
357
				&& array_key_exists( $locale, $this->languages )
358
				&& $this->obj_is_language_enabled( $locale, $pod )
359
			) {
360
				$options[ $field ] = $options[ $field . '_' . $locale ];
361
			}
362
		}
363
		return $options;
364
	}
365
366
	/**
367
	 * Filter hook function to overwrite the labels and description with translations (if available)
368
	 *
369
	 * @since  0.1
370
	 * @see    PodsInit.php >> setup_content_types()
371
	 * @param  array   $options  The array of object options
372
	 * @param  string  $object   The object type name/slug
373
	 * @return array
374
	 */
375
	public function pods_register_wp_object_i18n( $options, $object ) {
376
377
		$locale = $this->locale;
378
379
		$pod = pods_api()->load_pod( $object );
380
381
		if ( ! $this->obj_is_language_enabled( $locale, $pod ) ) {
382
			return $options;
383
		}
384
385
		// Load the pod
386
		foreach ( $pod[ 'options' ] as $_option => $_value ) {
387
			$pod[ $_option ] = $_value;
388
		}
389
390
		// Default
391
		$locale_labels                          = array();
392
		$locale_labels['name']                  = esc_html( pods_v( 'label_'.$locale, $pod, '', true ) );
393
		$locale_labels['singular_name']         = esc_html( pods_v( 'label_singular_'.$locale, $pod, '', true ) );
394
		$locale_labels['menu_name']             = pods_v( 'menu_name_' . $locale, $pod, '', true );
395
		$locale_labels['add_new_item']          = pods_v( 'label_add_new_item_' . $locale, $pod, '', true );
396
		$locale_labels['edit_item']             = pods_v( 'label_edit_item_' . $locale, $pod, '', true );
397
		$locale_labels['view_item']             = pods_v( 'label_view_item_' . $locale, $pod, '', true );
398
		$locale_labels['all_items']             = pods_v( 'label_all_items_' . $locale, $pod, '', true );
399
		$locale_labels['search_items']          = pods_v( 'label_search_items_' . $locale, $pod, '', true );
400
		$locale_labels['parent_item_colon']     = pods_v( 'label_parent_item_colon_' . $locale, $pod, '', true );
401
		$locale_labels['not_found']             = pods_v( 'label_not_found_' . $locale, $pod, '', true );
402
		$locale_labels['items_list_navigation'] = pods_v( 'label_items_list_navigation_' . $locale, $pod, '', true );
403
		$locale_labels['items_list']            = pods_v( 'label_items_list_' . $locale, $pod, '', true );
404
405
		// Post Types
406
		$locale_labels['name_admin_bar']        = pods_v( 'name_admin_bar_' . $locale, $pod, '', true );
407
		$locale_labels['add_new']               = pods_v( 'label_add_new_' . $locale, $pod, '', true );
408
		$locale_labels['new_item']              = pods_v( 'label_new_item_' . $locale, $pod, '', true );
409
		$locale_labels['edit']                  = pods_v( 'label_edit_' . $locale, $pod, '', true );
410
		$locale_labels['view']                  = pods_v( 'label_view_' . $locale, $pod, '', true );
411
		$locale_labels['view_items']            = pods_v( 'label_view_items_' . $locale, $pod, '', true );
412
		$locale_labels['parent']                = pods_v( 'label_parent_' . $locale, $pod, '', true );
413
		$locale_labels['not_found_in_trash']    = pods_v( 'label_not_found_in_trash_' . $locale, $pod, '', true );
414
		$locale_labels['archives']              = pods_v( 'label_archives_' . $locale, $pod, '', true );
415
		$locale_labels['attributes']            = pods_v( 'label_attributes_' . $locale, $pod, '', true );
416
		$locale_labels['insert_into_item']      = pods_v( 'label_insert_into_item_' . $locale, $pod, '', true );
417
		$locale_labels['uploaded_to_this_item'] = pods_v( 'label_uploaded_to_this_item_' . $locale, $pod, '', true );
418
		$locale_labels['featured_image']        = pods_v( 'label_featured_image_' . $locale, $pod, '', true );
419
		$locale_labels['set_featured_image']    = pods_v( 'label_set_featured_image_' . $locale, $pod, '', true );
420
		$locale_labels['remove_featured_image'] = pods_v( 'label_remove_featured_image_' . $locale, $pod, '', true );
421
		$locale_labels['use_featured_image']    = pods_v( 'label_use_featured_image_' . $locale, $pod, '', true );
422
		$locale_labels['filter_items_list']     = pods_v( 'label_filter_items_list_' . $locale, $pod, '', true );
423
424
		// Taxonomies
425
		$locale_labels['update_item']                = pods_v( 'label_update_item_' . $locale, $pod, '', true );
426
		$locale_labels['popular_items']              = pods_v( 'label_popular_items_' . $locale, $pod, '', true );
427
		$locale_labels['parent_item']                = pods_v( 'label_parent_item_' . $locale, $pod, '', true );
428
		$locale_labels['new_item_name']              = pods_v( 'label_new_item_name_' . $locale, $pod, '', true );
429
		$locale_labels['separate_items_with_commas'] = pods_v( 'label_separate_items_with_commas_' . $locale, $pod, '', true );
430
		$locale_labels['add_or_remove_items']        = pods_v( 'label_add_or_remove_items_' . $locale, $pod, '', true );
431
		$locale_labels['choose_from_most_used']      = pods_v( 'label_choose_from_the_most_used_' . $locale, $pod, '', true );
432
		$locale_labels['no_terms']                   = pods_v( 'label_no_terms_' . $locale, $pod, '', true );
433
434
		// Assign to label array
435
		if ( isset( $options['labels'] ) && is_array( $options['labels'] ) ) {
436
			foreach( $options['labels'] as $key => $value ) {
437
				// @todo Currently I only overwrite, maybe also append even if the default locale isn't set?
438
				if ( isset( $locale_labels[ $key ] ) && ! empty( $locale_labels[ $key ] ) ) {
439
					$options['labels'][ $key ] = $locale_labels[ $key ];
440
				}
441
			}
442
		}
443
444
		return $options;
445
	}
446
447
	/**
448
	 * Filter hook function to overwrite the labels and description with translations (if available)
449
	 *
450
	 * @since  0.1
451
	 * @see    PodsInit.php >> admin_menu()
452
	 * @param  array   $options  The array of object options
453
	 * @param  string  $object   The object type name/slug
454
	 * @return array
455
	 */
456
	function pods_filter_object_strings_i18n( $options, $object ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
457
458
		/**
459
		 * @todo allow labels to be set even if the default language isn't
460
		 *
461
		 * - Find all keys that end with the current locale
462
		 * - Assign them to the keys without that locale
463
		 */
464
465
		foreach( $options as $key => $option ) {
466 View Code Duplication
			if ( is_string( $option ) && $this->is_translatable_field( $key ) ) {
467
				$options[ $key ] = $this->get_value_translation( $option, $key, $options );
468
			}
469
		}
470
471
		if ( ! empty( $options['options'] ) ) {
472
			foreach( $options['options'] as $key => $option ) {
473 View Code Duplication
				if ( is_string( $option ) && $this->is_translatable_field( $key ) ) {
474
					$options['options'][ $key ] = $this->get_value_translation( $option, $key, $options['options'] );
475
				}
476
			}
477
		}
478
479
		return $options;
480
	}
481
482
	/**
483
	 * Save component settings
484
	 *
485
	 * @since 0.1
486
	 */
487
	public function admin_save() {
488
489
		$this->languages_available = get_available_languages();
490
491
		/**
492
		 * format: array( language, version, updated, english_name, native_name, package, iso, strings )
493
		 */
494
		require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
495
		$this->languages_translated = wp_get_available_translations();
496
497
		$new_languages = array();
498
499
		if ( isset( $_POST['pods_i18n_enabled_languages'] ) && is_array( $_POST['pods_i18n_enabled_languages'] ) ) {
500
			foreach ( $_POST['pods_i18n_enabled_languages'] as $locale ) {
501
				$locale = sanitize_text_field( $locale );
502
503
				if ( in_array( $locale, $this->languages_available ) ) {
504
					$new_languages[ $locale ] = array();
505
506 View Code Duplication
					if ( isset( $this->languages_translated[ $locale ]['language'] ) ) {
507
						$new_languages[ $locale ]['language'] = $this->languages_translated[ $locale ]['language'];
508
					}
509
510 View Code Duplication
					if ( isset( $this->languages_translated[ $locale ]['english_name'] ) ) {
511
						$new_languages[ $locale ]['english_name'] = $this->languages_translated[ $locale ]['english_name'];
512
					}
513
514 View Code Duplication
					if ( isset( $this->languages_translated[ $locale ]['native_name'] ) ) {
515
						$new_languages[ $locale ]['native_name'] = $this->languages_translated[ $locale ]['native_name'];
516
					}
517
				}
518
			}
519
		}
520
521
		$this->languages = $new_languages;
522
		$this->settings['enabled_languages'] = $new_languages;
523
524
		update_option( $this->option_key, $this->settings );
525
526
	}
527
528
	/**
529
	 * Build admin area
530
	 *
531
	 * @since  0.1
532
	 * @param  $options
533
	 * @param  $component
534
	 * @return void
535
	 */
536
	public function admin ( $options, $component ) {
537
538
		$this->languages_available = get_available_languages();
539
540
		/**
541
		 * format: array( language, version, updated, english_name, native_name, package, iso, strings )
542
		 */
543
		require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
544
545
		$this->languages_translated = wp_get_available_translations();
546
547
		// en_US is always installed (default locale of WP)
548
		$data = array(
549
			'en_US' => array(
550
				'id'          => 'en_US',
551
				'locale'      => 'en_US',
552
				'lang'        => 'English',
553
				'lang_native' => 'English',
554
				'enabled'     => 'Default',
555
			)
556
		);
557
558
		foreach ( $this->languages_available as $locale ) {
559
			$checked = checked( isset( $this->languages[ $locale ] ), true, false );
560
561
			$enabled = sprintf(
562
				'<input type="checkbox" name="pods_i18n_enabled_languages[%s]" value="%s"%s />',
563
				esc_attr( $locale ),
564
				esc_attr( $locale ),
565
				$checked
566
			);
567
568
			$data[ $locale ] = array(
569
				'id'          => $locale,
570
				'locale'      => $locale,
571
				'lang'        => $this->languages_translated[ $locale ]['english_name'],
572
				'lang_native' => $this->languages_translated[ $locale ]['native_name'],
573
				'enabled'     => $enabled,
574
			);
575
		}
576
577
		$ui = array(
578
			'component' => $component,
579
			//'data' => $data,
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
580
			//'total' => count( $data ),
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
581
			//'total_found' => count( $data ),
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
582
			'items' => __('Languages', 'pods'),
583
			'item' => __('Language', 'pods'),
584
			'fields' => array(
585
				'manage' => array(
586
					'enabled' => array(
587
						'label' => __( 'Active', 'pods' ),
588
						'type' => 'raw',
589
					),
590
					'locale' => array( 'label' => __( 'Locale', 'pods' ), 'classes' => array( 'column-secondary' ) ),
591
					'lang' => array( 'label' => __( 'Language', 'pods' ) ),
592
					'lang_native' => array( 'label' => __( 'Native name', 'pods' ) ),
593
					/*'fields' => array(
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
594
						'label' => __( 'Fields', 'pods' ),
595
						'type' => 'text',
596
						'options' => array(
597
							'text_allow_html' => 1,
598
							'text_allowed_html_tags' => 'br code'
599
						)
600
					),*/
601
				)
602
			),
603
			'actions_disabled' => array( 'edit', 'add', 'delete', 'duplicate', 'view', 'export' ),
604
			'actions_custom' => array(
605
				//'add' => array( $this, 'admin_add' ),
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
606
				//'edit' => array( $this, 'admin_edit' ),
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
607
				//'delete' => array( $this, 'admin_delete' )
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
608
			),
609
			'search' => false,
610
			'searchable' => false,
611
			'sortable' => false,
612
			'pagination' => false
613
		);
614
615
		/**
616
		 * Filter the language data
617
		 * @since 0.1
618
		 * @param array
619
		 */
620
		$data = apply_filters( 'pods_component_i18n_admin_data', $data );
621
622
		/**
623
		 * Filter the UI fields
624
		 * @since 0.1
625
		 * @param array
626
		 */
627
		$ui['fields'] = apply_filters( 'pods_component_i18n_admin_ui_fields', $ui['fields'], $data );
628
629
		$ui['data'] = $data;
630
		$ui['total'] = count( $data );
631
		$ui['total_found'] = count( $data );
632
633
		/*if ( !pods_is_admin( array( 'pods_i18n_activate_lanuages' ) ) )
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
634
			$ui[ 'actions_disabled' ][] = 'edit';*/
635
636
		echo '<div id="pods_admin_i18n" class="pods-submittable-fields">';
637
638
		// Do save action here because otherwise the loading of post_types get done first and labels aren't translated
639
		if ( pods_is_admin( $this->capability )
640
			&& isset( $_POST['_nonce_i18n'] )
641
			&& wp_verify_nonce( $_POST['_nonce_i18n'], $this->nonce )
642
		) {
643
			pods_message( __( 'Updated active languages.', 'pods' ) );
644
		}
645
646
		pods_ui( $ui );
647
648
		// @todo Do this in pods_ui so we don't rely on javascript
649
		echo '<div id="pods_i18n_settings_save">';
650
		wp_nonce_field( $this->nonce, '_nonce_i18n', false );
651
		submit_button();
652
		echo '</div>';
653
654
		echo '</div>';
655
	}
656
657
	/**
658
	 * The i18n option tab.
659
	 *
660
	 * @todo  Remove if not used in final version
661
	 *
662
	 * @since  0.1
663
	 * @param  array $tabs
664
	 * @param  array $pod
665
	 * @param  array $args
666
	 * @return array
667
	 */
668
	public function pod_tab( $tabs, $pod, $args ) {
669
		$tabs[ 'pods-i18n' ] = __( 'Translation Options', 'pods' );
670
		return $tabs;
671
	}
672
673
	/**
674
	 * The i18n options
675
	 *
676
	 * @todo  Remove if not used in final version
677
	 *
678
	 * @since  0.1
679
	 * @param  array $options
680
	 * @param  array $pod
681
	 * @return array
682
	 */
683
	public function pod_options( $options, $pod ) {
684
685
		//if ( $pod['type'] === '' )
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
686
		/*$options[ 'pods-i18n' ] = array(
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
687
			'enabled_languages' => array(
688
				'label' => __( 'Enable/Disable languages for this Pod', 'pods' ),
689
				'help' => __( 'This overwrites the defaults set in the component admin.', 'pods' ),
690
				'group' => array(),
691
			),
692
		);
693
694
		foreach ( $this->languages as $locale => $lang_data ) {
695
			$options['pods-i18n']['enabled_languages']['group']['enable_i18n'][ $locale ] = array(
696
				'label'      => $locale . ' (' . $this->create_lang_label( $lang_data ) . ')',
697
				'default'    => 1,
698
				'type'       => 'boolean',
699
			);
700
		}*/
701
702
		return $options;
703
704
	}
705
706
	/**
707
	 * Add the i18n metabox.
708
	 *
709
	 * @since 0.1
710
	 */
711
	public function admin_meta_box() {
712
		add_meta_box(
713
			'pods_i18n', // ID
714
			__( 'Translation options', 'pods' ), // Label
715
			array( $this, 'meta_box' ), // Callback
716
			'_pods_pod', // Screen
717
			'side', // Context (side)
718
			'default' // Priority
719
		);
720
	}
721
722
	/**
723
	 * The i18n metabox.
724
	 *
725
	 * @todo Store enabled languages serialized instead of separate inputs
726
	 *
727
	 * @since  0.1
728
	 * @param  array $pod
729
	 */
730
	public function meta_box( $pod ) {
731
732
		if ( ! empty( $this->languages ) ) {
733
		?>
734
			<p><?php _e( 'Enable/Disable languages for this Pod', 'pods' ); ?></p>
735
			<p><small class="description"><?php _e( 'This overwrites the defaults set in the component admin.', 'pods' ); ?></small></p>
736
			<div class="pods-field-enable-disable-language">
737
		<?php
738
			foreach ( $this->languages as $locale => $lang_data ) {
739
740
				if ( ! isset( $pod['options']['enable_i18n'][ $locale ] ) ) {
741
					// Enabled by default
742
					$pod['options']['enable_i18n'][ $locale ] = 1;
743
				}
744
		?>
745
				<div class="pods-field-option pods-enable-disable-language" data-locale="<?php echo esc_attr( $locale ) ?>">
746
		<?php
747
					echo PodsForm::field( 'enable_i18n[' . $locale . ']', $pod['options']['enable_i18n'][ $locale ], 'boolean', array(
748
						'boolean_yes_label' =>  '<code>' . $locale . '</code> ' . $this->create_lang_label( $lang_data ),
749
						'boolean_no_label' =>  '',
750
					) );
751
		?>
752
				</div>
753
		<?php
754
			}
755
		?>
756
			</div>
757
			<hr>
758
			<p><button id="toggle_i18n" class="button-secondary"><?php _e( 'Toggle translation visibility', 'pods' ); ?></button></p>
759
		<?php
760
		}
761
	}
762
763
	/**
764
	 * Adds translation inputs to fields
765
	 *
766
	 * @since  0.1
767
	 * @see    PodsForm.php >> 'pods_form_ui_field_' . $type (filter)
768
	 * @param  string $output The default output of the field
769
	 * @param  string $name The field name
770
	 * @param  string $value The field value
771
	 * @param  array $options The field options
772
	 * @param  array $pod The Pod
773
	 * @param  int $id The field ID
774
	 * @return string
775
	 */
776
	public function add_i18n_inputs( $output, $name, $value, $options, $pod, $id ) {
777
778
		if ( ! empty( $pod ) || empty( $name ) || ! $this->is_translatable_field( $name ) ) {
779
			return $output;
780
		}
781
782
783
		$pod = $this->cur_pod;
784
		//print_r( $pod );
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
785
		if ( empty( $pod ) ) {
786
			// Setting the $pod var to a non-empty value is mandatory to prevent a loop
787
			$pod = true;
788
		}
789
790
		$output .= '<br clear="both" />';
791
		$output .= '<div class="pods-i18n-field">';
792
		foreach ( $this->languages as $locale => $lang_data ) {
793
794
			if ( ! $this->obj_is_language_enabled( $locale, (array) $pod ) ) {
795
				continue;
796
			}
797
			// Our own shiny label with language information
798
			$lang_code = '<code style="font-size: 1em;">' . $locale . '</code>';
799
			/*$lang_label = $this->create_lang_label( $lang_data );
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
800
			if ( ! empty( $lang_label ) ) {
801
				$lang_label = $lang_code . ' ('. $lang_label .')';
802
			} else {*/
803
				$lang_label = $lang_code;
804
			//}
805
			$lang_label = '<small>' . $lang_label . '</small>';
806
807
			$style = '';
808
809
			// Add language data to name for normal strings and array formatted strings
810
			if ( strpos( $name, ']' ) !== false ) {
811
				// Hide the i18n options for fields by default if they are empty
812
				$field_value = pods_v( $name, $pod );
813
814
				if ( strpos( $name, 'field_data' ) !== false && empty( $field_value ) ) {
815
					$style = ' style="display: none;"';
816
				}
817
818
				$field_name = rtrim( $name, ']' );
819
				$field_name .= '_'.$locale.']';
820
			} else {
821
				$field_name = $name.'_'.$locale;
822
			}
823
824
			// Add the translation fields
825
			$output .= '<div class="pods-i18n-input pods-i18n-input-' . $locale . '" data-locale="' . $locale . '" ' . $style . '>';
826
			$output .= PodsForm::label( $field_name, $lang_label );
827
			$output .= PodsForm::field( $field_name, pods_v( $field_name, $pod ), 'text', null, $pod );
828
			$output .= '</div>';
829
		}
830
		$output .= '</div>';
831
		return $output;
832
	}
833
834
	/**
835
	 * Check if a language is get to enabled for an object
836
	 *
837
	 * @since  0.1
838
	 * @param  string $locale The locale to validate
839
	 * @param  array  $data   Object data
840
	 * @return bool
841
	 */
842
	public function obj_is_language_enabled( $locale, $data ) {
843
		// If the locale isn't enabled in the global scope from the component it's always disabled
844
		if ( ! array_key_exists( $locale, $this->languages ) ) {
845
			return false;
846
		}
847
		$data = (array) $data;
848
		$options = ( isset( $data['options'] ) ) ? $data['options'] : $data;
849
		// If it doesn't exist in the object data then use the default (enabled)
850
		if ( isset( $options['enable_i18n'][ $locale ] ) && false === (bool) $options['enable_i18n'][ $locale ] ) {
851
			return false;
852
		}
853
		return true;
854
	}
855
856
	/**
857
	 * Create a label with the english and native name combined
858
	 *
859
	 * @since  0.1
860
	 * @param  array $lang_data
861
	 * @return string
862
	 */
863
	public function create_lang_label( $lang_data ) {
864
865
		$english_name = '';
866
		$native_name = '';
867
868
		if ( isset( $lang_data['english_name'] ) ) {
869
			$english_name = $lang_data['english_name'];
870
		}
871
		if ( isset( $lang_data['native_name'] ) ) {
872
			$native_name = $lang_data['native_name'];
873
		}
874
875
		if ( ! empty( $native_name ) && ! empty( $english_name ) ) {
876
			if ( $native_name == $english_name ) {
877
				return $english_name;
878
			} else {
879
				return $english_name . ' / ' . $native_name;
880
			}
881
		} else {
882
			if ( ! empty( $english_name ) ) {
883
				return $english_name;
884
			}
885
			if ( ! empty( $native_name ) ) {
886
				return $native_name;
887
			}
888
		}
889
		return '';
890
	}
891
892
	public function get_translatable_fields() {
893
		return apply_filters( 'pods_translatable_fields', $this->translatable_fields );
894
	}
895
896
}
897