PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 3.3.6
Pods – Custom Content Types and Fields v3.3.6
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 / components / I18n / I18n.php
pods / components / I18n Last commit date
I18n.php 4 months ago pods-admin-i18n.js 4 years ago
I18n.php
974 lines
1 <?php
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: 1.1
10 *
11 * Category: I18n
12 *
13 * Class: Pods_Component_I18n
14 *
15 * @package Pods\Components
16 * @subpackage i18n
17 */
18
19 // Don't load directly.
20 if ( ! defined( 'ABSPATH' ) ) {
21 die( '-1' );
22 }
23
24 if ( class_exists( 'Pods_Component_I18n' ) ) {
25 return;
26 }
27
28 /**
29 * Class Pods_Component_I18n
30 */
31 class Pods_Component_I18n extends PodsComponent {
32
33 public $settings = array();
34 public $locale = null;
35 public $languages = array();
36 public $languages_available = array();
37 public $languages_translated = array();
38 public $cur_pod = null;
39 public $option_key = 'pods_component_i18n_settings';
40 public $admin_page = 'pods-component-translate-pods-admin';
41 public $capability = 'pods_i18n_activate_lanuages';
42 public $nonce = 'pods_i18n_activate_lanuages';
43
44 /**
45 * All fields that are translatable.
46 * @var array
47 */
48 protected $translatable_fields = [
49 'label' => [],
50 'description' => [],
51 'placeholder' => [],
52 'menu_name' => [],
53 'name_admin_bar' => [],
54 'repeatable_add_new_label' => [
55 'depends-on' => [ 'repeatable' => true ],
56 ],
57 'boolean_yes_label' => [
58 'depends-on' => [ 'type' => 'boolean' ],
59 ],
60 'boolean_no_label' => [
61 'depends-on' => [ 'type' => 'boolean' ],
62 ],
63 'color_select_label' => [
64 'depends-on' => [ 'type' => 'color' ],
65 ],
66 'color_clear_label' => [
67 'depends-on' => [ 'type' => 'color' ],
68 ],
69 'file_add_button' => [
70 'depends-on' => [ 'type' => 'file' ],
71 ],
72 'file_modal_title' => [
73 'depends-on' => [ 'type' => 'file' ],
74 ],
75 'file_modal_add_button' => [
76 'depends-on' => [ 'type' => 'file' ],
77 ],
78 'pick_select_text' => [
79 'depends-on' => [ 'type' => 'pick' ],
80 ],
81 'pick_add_new_label' => [
82 'depends-on' => [ 'type' => 'pick' ],
83 ],
84 ];
85
86 /**
87 * {@inheritdoc}
88 */
89 public function init() {
90
91 $this->settings = get_option( $this->option_key, array() );
92
93 $active = false;
94 // Are there active languages?
95 if ( ! empty( $this->settings['enabled_languages'] ) ) {
96 $this->languages = $this->settings['enabled_languages'];
97
98 if ( function_exists( 'get_user_locale' ) ) {
99 // WP 4.7+
100 $this->locale = get_user_locale();
101 } else {
102 $this->locale = get_locale();
103 }
104
105 $active = true;
106 }
107
108 $is_component_page = false;
109 $is_pods_edit_page = false;
110
111 if ( is_admin() && isset( $_GET['page'] ) ) {
112
113 $page = $_GET['page'];
114
115 // Is the current page the admin page of this component or a Pods edit page?
116 if ( $this->admin_page === $page ) {
117 $is_component_page = true;
118 } elseif ( 'pods' === $page ) {
119 $is_pods_edit_page = true;
120 }
121 }
122
123 if ( $is_component_page ) {
124 // Do save action here because otherwise the loading of post_types get done first and labels aren't translated
125 if ( pods_is_admin( $this->capability ) && isset( $_POST['_nonce_i18n'] ) && wp_verify_nonce( $_POST['_nonce_i18n'], $this->nonce ) ) {
126 $this->admin_save();
127 }
128
129 add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
130 }
131
132 if ( $active ) {
133
134 /**
135 * PODS ADMIN UI.
136 */
137
138 // Pod.
139 add_filter( 'pods_admin_setup_edit_tabs', array( $this, 'translation_tab' ), 99, 1 );
140 add_filter( 'pods_admin_setup_edit_options', array( $this, 'translation_options' ), 99, 2 );
141 // Pod Groups.
142 add_filter( 'pods_admin_setup_edit_group_tabs', array( $this, 'translation_tab' ), 99, 1 );
143 add_filter( 'pods_admin_setup_edit_group_options', array( $this, 'translation_options' ), 99, 2 );
144 // Pod Fields.
145 add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'translation_tab' ), 99, 1 );
146 add_filter( 'pods_admin_setup_edit_field_options', array( $this, 'translation_options' ), 99, 2 );
147
148 /**
149 * REGISTERING OBJ LABELS.
150 */
151
152 // WP Object filters (post_type and taxonomy).
153 add_filter( 'pods_register_post_type', array( $this, 'translate_register_wp_object' ), 10, 2 );
154 add_filter( 'pods_register_taxonomy', array( $this, 'translate_register_wp_object' ), 10, 2 );
155
156 // ACT's
157 add_filter(
158 'pods_advanced_content_type_pod_data',
159 array( $this, 'translate_object_options' ),
160 10,
161 2
162 );
163
164 /**
165 * LABEL REPLACEMENT.
166 */
167
168 // Menu labels.
169 add_filter( 'pods_admin_menu_page_title', array( $this, 'translate_admin_menu_page_title' ), 10, 2 );
170 add_filter( 'pods_admin_menu_label', array( $this, 'translate_admin_menu_label' ), 10, 2 );
171
172 // Do not overwrite Whatsit object fields if we're editing Pods.
173 if ( ! $is_pods_edit_page && ! pods_doing_json() && ! wp_doing_ajax() ) {
174
175 // Pod Objects.
176 add_filter( 'pods_whatsit_get_label', array( $this, 'translate_label' ), 10, 2 );
177 add_filter( 'pods_whatsit_get_description', array( $this, 'translate_description' ), 10, 2 );
178 add_filter( 'pods_whatsit_get_arg', array( $this, 'translate_arg' ), 10, 3 );
179 add_filter( 'pods_whatsit_get_args', array( $this, 'translate_args' ), 10, 2 );
180
181 // Non DFV field UI.
182 foreach ( pods_form()->field_types() as $type => $data ) {
183 add_filter(
184 'pods_form_ui_field_' . $type . '_options',
185 array( $this, 'translate_field_options' ),
186 10,
187 5
188 );
189 }
190 }
191
192 }//end if
193 }
194
195 /**
196 * Load assets for this component
197 *
198 * @since 0.1.0
199 */
200 public function admin_assets() {
201
202 wp_enqueue_script(
203 'pods-admin-i18n',
204 PODS_URL . 'components/I18n/pods-admin-i18n.js',
205 array(
206 'jquery',
207 'pods-i18n',
208 ),
209 '1.0',
210 true
211 );
212 $localize_script = array();
213 if ( ! empty( $this->languages ) ) {
214 foreach ( $this->languages as $lang => $lang_data ) {
215 $lang_label = $this->create_lang_label( $lang_data );
216 if ( ! empty( $lang_label ) ) {
217 $lang_label = $lang . ' (' . $lang_label . ')';
218 } else {
219 $lang_label = $lang;
220 }
221 $localize_script[ $lang ] = $lang_label;
222 }
223 }
224 wp_localize_script( 'pods-admin-i18n', 'pods_admin_i18n_strings', $localize_script );
225
226 // Add strings to the i18n js object
227 add_filter( 'pods_localized_strings', array( $this, 'localize_assets' ) );
228 }
229
230 /**
231 * Localize the assets
232 *
233 * @param array $str Existing strings
234 *
235 * @return array
236 */
237 public function localize_assets( $str ) {
238
239 $str['Add translation'] = __( 'Add translation', 'pods' );
240 $str['Toggle translations'] = __( 'Toggle translations', 'pods' );
241 $str['Show translations'] = __( 'Show translations', 'pods' );
242 $str['Hide translations'] = __( 'Hide translations', 'pods' );
243 $str['Select'] = __( 'Select', 'pods' );
244
245 return $str;
246 }
247
248 /**
249 * Check is a field name is set for translation.
250 *
251 * @since 0.1.0
252 *
253 * @param string $name
254 *
255 * @return bool
256 */
257 public function is_translatable_field( $name ) {
258
259 // All fields that start with "label".
260 if ( strpos( $name, 'label' ) === 0 && false === strpos( $name, $this->locale ) ) {
261 return true;
262 }
263
264 // All translatable fields.
265 if ( in_array( $name, $this->get_translatable_fields( 'names' ), true ) ) {
266 return true;
267 }
268
269 return false;
270 }
271
272 /**
273 * Get a translated option for a field key if available.
274 *
275 * @since 0.1.0
276 *
277 * @param string $current Current value
278 * @param string $key The key / option name to search for
279 * @param array|Pods\Whatsit $data Pod data (can also be an options array of a pod or field)
280 *
281 * @return mixed
282 */
283 public function get_value_translation( $current, $key, $data ) {
284
285 $locale = $this->locale;
286 if ( ! array_key_exists( $locale, $this->languages ) ) {
287 return $current;
288 }
289
290 if ( $this->obj_is_language_enabled( $locale, $data ) ) {
291 $translation = pods_v( $key . '_' . $locale, $data, null );
292 if ( $translation ) {
293 return $translation;
294 }
295 }
296
297 return $current;
298 }
299
300 /**
301 * Page title for setting pages.
302 *
303 * @since 1.0.0
304 * @see PodsAdmin.php >> admin_menu()
305 * @see PodsAdmin.php >> admin_content_settings()
306 *
307 * @param string $page_title Current page title
308 * @param array $pod Pod data
309 *
310 * @return string
311 */
312 public function translate_admin_menu_page_title( $page_title, $pod ) {
313
314 return (string) $this->get_value_translation( $page_title, 'label', $pod );
315 }
316
317 /**
318 * Menu title for setting pages.
319 *
320 * @since 1.0.0
321 * @see PodsAdmin.php >> admin_menu()
322 *
323 * @param string $menu_label Current menu label
324 * @param array $pod Pod data
325 *
326 * @return string
327 */
328 public function translate_admin_menu_label( $menu_label, $pod ) {
329
330 return (string) $this->get_value_translation( $menu_label, 'menu_name', $pod );
331 }
332
333 /**
334 * Returns the translated label if available.
335 *
336 * @since 1.0.0
337 * @see \Pods\Whatsit >> 'pods_whatsit_get_label' (filter)
338 *
339 * @param string $label The default label.
340 * @param Pods\Whatsit $object The Pod Object.
341 *
342 * @return string
343 */
344 public function translate_label( $label, $object ) {
345
346 return (string) $this->get_value_translation( $label, 'label', $object );
347 }
348
349 /**
350 * Returns the translated description if available.
351 *
352 * @since 1.0.0
353 * @see \Pods\Whatsit >> 'pods_whatsit_get_description' (filter)
354 *
355 * @param string $description The default description.
356 * @param Pods\Whatsit $object The Pod Object.
357 *
358 * @return string
359 */
360 public function translate_description( $description, $object ) {
361
362 return (string) $this->get_value_translation( $description, 'description', $object );
363 }
364
365 /**
366 * Returns the translated argument if available.
367 *
368 * @since 2.8.4
369 * @see \Pods\Whatsit >> 'pods_whatsit_get_arg' (filter)
370 *
371 * @param mixed $arg The object argument.
372 * @param string $name The argument name.
373 * @param array|Pods\Whatsit $object The Pod Object.
374 *
375 * @return string
376 */
377 public function translate_arg( $arg, $name, $object ) {
378
379 if ( $this->is_translatable_field( $name ) ) {
380 return $this->get_value_translation( $arg, $name, $object );
381 }
382
383 return $arg;
384 }
385
386 /**
387 * Returns the translated arguments if available.
388 *
389 * @since 2.8.4
390 * @see \Pods\Whatsit >> 'pods_whatsit_get_args' (filter)
391 *
392 * @param array $args The object arguments.
393 * @param Pods\Whatsit $object The Pod Object.
394 *
395 * @return array
396 */
397 public function translate_args( $args, $object ) {
398
399 foreach ( $args as $name => $value ) {
400 if ( $this->is_translatable_field( $name ) ) {
401 $args[ $name ] = $this->translate_arg( $value, $name, $object );
402 }
403 }
404
405 return $args;
406 }
407
408 /**
409 * Replaces the default selected text with a translation if available.
410 *
411 * @since 1.0.0
412 * @see pick.php >> 'pods_field_pick_data' (filter)
413 *
414 * @param array $data The default data of the field
415 * @param string $name The field name
416 * @param string $value The field value
417 * @param array $options The field options
418 * @param array $pod The Pod
419 * @param int $id The field ID
420 *
421 * @return array
422 */
423 public function translate_field_pick_data( $data, $name, $value, $options, $pod, $id ) {
424
425 if ( isset( $data[''] ) && isset( $options['pick_select_text'] ) ) {
426 $locale = $this->locale;
427 if ( isset( $options[ 'pick_select_text_' . $locale ] ) && array_key_exists( $locale, $this->languages ) && $this->obj_is_language_enabled( $locale, $pod ) ) {
428 $data[''] = $options[ 'pick_select_text_' . $locale ];
429 }
430 }
431
432 return $data;
433 }
434
435 /**
436 * Replaces the default values with a translation if available.
437 *
438 * @since 1.0.0
439 * @see PodsForm.php >> 'pods_form_ui_field_' . $type . '_options' (filter)
440 *
441 * @param array $options The field options
442 * @param string $name The field name
443 * @param string $value The field value
444 * @param array $pod The Pod
445 * @param int $id The field ID
446 *
447 * @return array
448 */
449 public function translate_field_options( $options, $name, $value, $pod, $id ) {
450 $locale = $this->locale;
451 if ( ! array_key_exists( $locale, $this->languages ) || ! $this->obj_is_language_enabled( $locale, $pod ) ) {
452 return $options;
453 }
454
455 foreach ( $this->get_translatable_fields( 'names' ) as $field ) {
456 $translation = pods_v( $field . '_' . $locale, $options, null );
457 if ( $translation ) {
458 $options[ $field ] = $translation;
459 }
460 }
461
462 return $options;
463 }
464
465 /**
466 * Filter hook function to overwrite the labels and description with translations (if available)
467 *
468 * @since 1.0.0
469 * @see PodsInit.php >> setup_content_types()
470 *
471 * @param array $options The array of object options
472 * @param string $object The object type name/slug
473 *
474 * @return array
475 */
476 public function translate_register_wp_object( $options, $object ) {
477
478 $locale = $this->locale;
479
480 $pod = pods_api()->load_pod( $object );
481
482 if ( ! $this->obj_is_language_enabled( $locale, $pod ) ) {
483 return $options;
484 }
485
486 $labels = array(
487 // Default
488 'name' => 'label', // Different.
489 'singular_name' => 'label_singular', // Different.
490 'menu_name' => 'menu_name',
491 'add_new_item' => 'label_add_new_item',
492 'edit_item' => 'label_edit_item',
493 'view_item' => 'label_view_item',
494 'all_items' => 'label_all_items',
495 'search_items' => 'label_search_items',
496 'parent_item_colon' => 'label_parent_item_colon',
497 'not_found' => 'label_not_found',
498 'items_list_navigation' => 'label_items_list_navigation',
499 'items_list' => 'label_items_list',
500
501 // Post Types
502 'name_admin_bar' => 'name_admin_bar',
503 'add_new' => 'label_add_new',
504 'new_item' => 'label_new_item',
505 'edit' => 'label_edit',
506 'view' => 'label_view',
507 'view_items' => 'label_view_items',
508 'parent' => 'label_parent',
509 'not_found_in_trash' => 'label_not_found_in_trash',
510 'archives' => 'label_archives',
511 'attributes' => 'label_attributes',
512 'insert_into_item' => 'label_insert_into_item',
513 'uploaded_to_this_item' => 'label_uploaded_to_this_item',
514 'featured_image' => 'label_featured_image',
515 'set_featured_image' => 'label_set_featured_image',
516 'remove_featured_image' => 'label_remove_featured_image',
517 'use_featured_image' => 'label_use_featured_image',
518 'filter_items_list' => 'label_filter_items_list',
519 // Block Editor (WP 5.0+)
520 'item_published' => 'label_item_published',
521 'item_published_privately' => 'label_item_published_privately',
522 'item_reverted_to_draft' => 'label_item_reverted_to_draft',
523 'item_scheduled' => 'label_item_scheduled',
524 'item_updated' => 'label_item_updated',
525 'filter_by_date' => 'label_filter_by_date', // WP 5.7
526
527 // Taxonomies
528 'update_item' => 'label_update_item',
529 'popular_items' => 'label_popular_items',
530 'parent_item' => 'label_parent_item',
531 'new_item_name' => 'label_new_item_name',
532 'separate_items_with_commas' => 'label_separate_items_with_commas',
533 'add_or_remove_items' => 'label_add_or_remove_items',
534 'choose_from_most_used' => 'label_choose_from_the_most_used', // Different.
535 'no_terms' => 'label_no_terms',
536 'filter_by_item' => 'label_filter_by_item', // WP 5.7
537 );
538
539 if ( ! isset( $options['labels'] ) || ! is_array( $options['labels'] ) ) {
540 $options['labels'] = array();
541 } else {
542 // Try to find new labels.
543 foreach ( $options['labels'] as $key => $val ) {
544 if ( ! isset( $labels[ $key ] ) ) {
545 $labels[ $key ] = 'label_' . $key;
546 }
547 }
548 }
549
550 foreach ( $labels as $key => $pods_key ) {
551 $label = pods_v( $pods_key . '_' . $locale, $pod, '', true );
552 if ( $label ) {
553 $options['labels'][ $key ] = $label;
554 }
555 }
556
557 return $options;
558 }
559
560 /**
561 * Filter hook function to overwrite the labels and description with translations (if available)
562 *
563 * @since 1.0.0
564 * @see PodsInit.php >> admin_menu()
565 *
566 * @param array $options The array of object options
567 * @param string $object The object type name/slug
568 *
569 * @return array
570 */
571 public function translate_object_options( $options, $object ) {
572
573 /**
574 * @todo allow labels to be set even if the default language isn't
575 *
576 * - Find all keys that end with the current locale
577 * - Assign them to the keys without that locale
578 */
579
580 foreach ( $options as $key => $option ) {
581 if ( is_string( $option ) && $this->is_translatable_field( $key ) ) {
582 $options[ $key ] = $this->get_value_translation( $option, $key, $options );
583 }
584 }
585
586 if ( ! empty( $options['options'] ) ) {
587 foreach ( $options['options'] as $key => $option ) {
588 if ( is_string( $option ) && $this->is_translatable_field( $key ) ) {
589 $options['options'][ $key ] = $this->get_value_translation( $option, $key, $options['options'] );
590 }
591 }
592 }
593
594 return $options;
595 }
596
597 /**
598 * Save component settings
599 *
600 * @since 0.1.0
601 */
602 public function admin_save() {
603
604 $this->languages_available = get_available_languages();
605
606 /**
607 * format: array( language, version, updated, english_name, native_name, package, iso, strings )
608 */
609 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
610 $this->languages_translated = wp_get_available_translations();
611
612 $new_languages = array();
613
614 if ( isset( $_POST['pods_i18n_enabled_languages'] ) && is_array( $_POST['pods_i18n_enabled_languages'] ) ) {
615 foreach ( $_POST['pods_i18n_enabled_languages'] as $locale ) {
616 $locale = sanitize_text_field( $locale );
617
618 if ( in_array( $locale, $this->languages_available, true ) ) {
619 $new_languages[ $locale ] = array();
620
621 if ( isset( $this->languages_translated[ $locale ]['language'] ) ) {
622 $new_languages[ $locale ]['language'] = $this->languages_translated[ $locale ]['language'];
623 }
624
625 if ( isset( $this->languages_translated[ $locale ]['english_name'] ) ) {
626 $new_languages[ $locale ]['english_name'] = $this->languages_translated[ $locale ]['english_name'];
627 }
628
629 if ( isset( $this->languages_translated[ $locale ]['native_name'] ) ) {
630 $new_languages[ $locale ]['native_name'] = $this->languages_translated[ $locale ]['native_name'];
631 }
632 }
633 }
634 }//end if
635
636 $this->languages = $new_languages;
637 $this->settings['enabled_languages'] = $new_languages;
638
639 update_option( $this->option_key, $this->settings );
640
641 }
642
643 /**
644 * Build admin area
645 *
646 * @since 0.1.0
647 *
648 * @param $options
649 * @param $component
650 *
651 * @return void
652 */
653 public function admin( $options, $component ) {
654
655 $this->languages_available = get_available_languages();
656
657 /**
658 * format: array( language, version, updated, english_name, native_name, package, iso, strings )
659 */
660 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
661
662 $this->languages_translated = wp_get_available_translations();
663
664 // en_US is always installed (default locale of WP)
665 $data = array(
666 'en_US' => array(
667 'id' => 'en_US',
668 'locale' => 'en_US',
669 'lang' => 'English',
670 'lang_native' => 'English',
671 'enabled' => 'Default',
672 ),
673 );
674
675 foreach ( $this->languages_available as $locale ) {
676 $checked = checked( isset( $this->languages[ $locale ] ), true, false );
677
678 $enabled = sprintf( '<input type="checkbox" name="pods_i18n_enabled_languages[%s]" value="%s"%s />', esc_attr( $locale ), esc_attr( $locale ), $checked );
679
680 $data[ $locale ] = array(
681 'id' => $locale,
682 'locale' => $locale,
683 'lang' => $this->languages_translated[ $locale ]['english_name'],
684 'lang_native' => $this->languages_translated[ $locale ]['native_name'],
685 'enabled' => $enabled,
686 );
687 }
688
689 $ui = array(
690 'component' => $component,
691 // 'data' => $data,
692 // 'total' => count( $data ),
693 // 'total_found' => count( $data ),
694 'items' => __( 'Languages', 'pods' ),
695 'item' => __( 'Language', 'pods' ),
696 'fields' => array(
697 'manage' => array(
698 'enabled' => array(
699 'label' => __( 'Active', 'pods' ),
700 'type' => 'raw',
701 ),
702 'locale' => array(
703 'label' => __( 'Locale', 'pods' ),
704 'classes' => array( 'column-secondary' ),
705 ),
706 'lang' => array( 'label' => __( 'Language', 'pods' ) ),
707 'lang_native' => array( 'label' => __( 'Native name', 'pods' ) ),
708 /*
709 'fields' => array(
710 'label' => __( 'Fields', 'pods' ),
711 'type' => 'text',
712 'options' => array(
713 'text_allow_html' => 1,
714 'text_allowed_html_tags' => 'br code'
715 )
716 ),*/
717 ),
718 ),
719 'actions_disabled' => array( 'edit', 'add', 'delete', 'duplicate', 'view', 'export' ),
720 'actions_custom' => array(
721 // 'add' => array( $this, 'admin_add' ),
722 // 'edit' => array( $this, 'admin_edit' ),
723 // 'delete' => array( $this, 'admin_delete' )
724 ),
725 'search' => false,
726 'searchable' => false,
727 'sortable' => false,
728 'pagination' => false,
729 );
730
731 /**
732 * Filter the language data.
733 *
734 * @since 0.1.0
735 *
736 * @param array $data The language data.
737 */
738 $data = apply_filters( 'pods_component_i18n_admin_data', $data );
739
740 /**
741 * Filter the UI fields.
742 *
743 * @since 0.1.0
744 *
745 * @param array $fields The UI fields.
746 * @param array $data The language data.
747 */
748 $ui['fields'] = apply_filters( 'pods_component_i18n_admin_ui_fields', $ui['fields'], $data );
749
750 $ui['data'] = $data;
751 $ui['total'] = count( $data );
752 $ui['total_found'] = count( $data );
753
754 /*
755 if ( !pods_is_admin( array( 'pods_i18n_activate_lanuages' ) ) )
756 $ui[ 'actions_disabled' ][] = 'edit';*/
757
758 echo '<div id="pods_admin_i18n" class="pods-submittable-fields">';
759
760 // Do save action here because otherwise the loading of post_types get done first and labels aren't translated
761 if ( pods_is_admin( $this->capability ) && isset( $_POST['_nonce_i18n'] ) && wp_verify_nonce( $_POST['_nonce_i18n'], $this->nonce ) ) {
762 pods_message( __( 'Updated active languages.', 'pods' ) );
763 }
764
765 pods_ui( $ui );
766
767 // @todo Do this in pods_ui so we don't rely on javascript
768 echo '<div id="pods_i18n_settings_save">';
769 wp_nonce_field( $this->nonce, '_nonce_i18n', false );
770 submit_button();
771 echo '</div>';
772
773 echo '</div>';
774 }
775
776 /**
777 * The i18n option tab.
778 *
779 * @since 1.0.0
780 *
781 * @param array $tabs
782 *
783 * @return array
784 */
785 public function translation_tab( $tabs ) {
786
787 $tabs['i18n'] = __( 'Translations', 'pods' );
788
789 return $tabs;
790 }
791
792 /**
793 * The i18n options.
794 *
795 * @since 1.0.0
796 *
797 * @param array $options
798 * @param array|Pods\Whatsit $object
799 *
800 * @return array
801 */
802 public function translation_options( $options, $object ) {
803 $i18n_fields = [];
804
805 foreach ( $options as $tab => $fields ) {
806 foreach ( $fields as $name => $field ) {
807 if ( ! $this->is_translatable_field( $name ) ) {
808 continue;
809 }
810
811 $i18n_options = $this->get_translatable_field_options( $name );
812
813 // None of the i18n fields are required!
814 $field['required'] = false;
815
816 $heading_field = $field;
817 $heading_field['type'] = 'heading';
818 $heading_field['name'] = $name . '_i18n';
819
820 $i18n_fields[][ $name . '_i18n' ] = array_merge_recursive( $heading_field, $i18n_options );
821
822 $default_field = $field;
823 $default_field['type'] = 'html';
824 $default_field['name'] = $name . '_i18n_default';
825 $default_field['label'] = __( 'Default', 'pods' );
826 $default_field['html_content'] = '%s';
827 $default_field['html_content_param'] = $name;
828 $default_field['html_content_param_default'] = '-';
829
830 $i18n_fields[][ $name . '_i18n_default' ] = array_merge_recursive( $default_field, $i18n_options );
831
832 foreach ( $this->languages as $locale => $lang_data ) {
833 if ( ! $this->obj_is_language_enabled( $locale, $object ) ) {
834 continue;
835 }
836
837 $locale_name = $name . '_' . $locale;
838 $locale_field = $field;
839 $locale_field['name'] = $locale_name;
840 $locale_field['label'] = $locale;
841 $locale_field['default'] = '';
842
843 $i18n_fields[][ $locale_name ] = array_merge_recursive( $locale_field, $i18n_options );
844 }
845 }
846 }
847
848 $options['i18n'] = $i18n_fields;
849
850 // if ( $object['type'] === '' )
851 /*
852 $options[ 'pods-i18n' ] = array(
853 'enabled_languages' => array(
854 'label' => __( 'Enable/Disable languages for this Pod', 'pods' ),
855 'help' => __( 'This overwrites the defaults set in the component admin.', 'pods' ),
856 'group' => array(),
857 ),
858 );
859
860 foreach ( $this->languages as $locale => $lang_data ) {
861 $options['pods-i18n']['enabled_languages']['group']['enable_i18n'][ $locale ] = array(
862 'label' => $locale . ' (' . $this->create_lang_label( $lang_data ) . ')',
863 'default' => 1,
864 'type' => 'boolean',
865 );
866 }*/
867
868 return $options;
869 }
870
871 /**
872 * Check if a language is get to enabled for an object
873 *
874 * @since 0.1.0
875 *
876 * @param string $locale The locale to validate
877 * @param array $data Object data
878 *
879 * @return bool
880 */
881 public function obj_is_language_enabled( $locale, $data ) {
882
883 // If the locale isn't enabled in the global scope from the component it's always disabled
884 if ( ! array_key_exists( $locale, $this->languages ) ) {
885 return false;
886 }
887 if ( $data instanceof Pods\Whatsit ) {
888 $enable_i18n = $data->get_arg( 'enable_i18n' );
889 } else {
890 $options = pods_v( 'options', $data, $data );
891 $enable_i18n = pods_v( 'enable_i18n', $options, null );
892 }
893
894 if ( null === $enable_i18n ) {
895 // If there are no i18n settings in the object data then assume it's enabled.
896 return true;
897 }
898
899 return (bool) pods_v( $locale, $enable_i18n, true );
900 }
901
902 /**
903 * Create a label with the english and native name combined
904 *
905 * @since 0.1.0
906 *
907 * @param array $lang_data
908 *
909 * @return string
910 */
911 public function create_lang_label( $lang_data ) {
912
913 $label = pods_v( 'english_name', $lang_data, '' );
914 $native_name = pods_v( 'native_name', $lang_data, '' );
915
916 if ( ! empty( $native_name ) && $label !== $native_name ) {
917 $label .= ' / ' . $native_name;
918 }
919
920 return $label;
921 }
922
923 /**
924 * @param string $return Return type (supports 'names').
925 * @return array
926 */
927 public function get_translatable_fields( $return = '' ) {
928
929 /**
930 * Overwrite translatable fields.
931 *
932 * @since 2.8.4
933 *
934 * @param string[] $fields The translatable fields.
935 */
936 $fields = apply_filters( 'pods_translatable_fields', $this->translatable_fields );
937
938 // Backwards compatibility: Before v1.1 this was a list of field names instead of options.
939 foreach ( $fields as $name => $value ) {
940 if ( is_string( $value ) ) {
941 unset( $fields[ $name ] );
942 if ( ! isset( $fields[ $value ] ) ) {
943 $fields[ $value ] = [];
944 }
945 }
946 }
947
948 if ( 'names' === $return ) {
949 return array_keys( $fields );
950 }
951
952 return $fields;
953 }
954
955 /**
956 * @since 2.8.4
957 * @return array[]
958 */
959 public function get_translatable_field_options( $key ) {
960
961 $field_options = pods_v( $key, $this->get_translatable_fields(), array() );
962
963 /**
964 * Overwrite translatable field options.
965 *
966 * @since 2.8.4
967 *
968 * @param array $field_options The translatable field options.
969 * @param string $key The field name.
970 */
971 return apply_filters( 'pods_translatable_field_options', $field_options, $key );
972 }
973 }
974