PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / trunk
Pods – Custom Content Types and Fields vtrunk
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
975 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 $name = (string) $name;
259
260 // All fields that start with "label".
261 if ( strpos( $name, 'label' ) === 0 && false === strpos( $name, $this->locale ) ) {
262 return true;
263 }
264
265 // All translatable fields.
266 if ( in_array( $name, $this->get_translatable_fields( 'names' ), true ) ) {
267 return true;
268 }
269
270 return false;
271 }
272
273 /**
274 * Get a translated option for a field key if available.
275 *
276 * @since 0.1.0
277 *
278 * @param string $current Current value
279 * @param string $key The key / option name to search for
280 * @param array|Pods\Whatsit $data Pod data (can also be an options array of a pod or field)
281 *
282 * @return mixed
283 */
284 public function get_value_translation( $current, $key, $data ) {
285
286 $locale = $this->locale;
287 if ( ! array_key_exists( $locale, $this->languages ) ) {
288 return $current;
289 }
290
291 if ( $this->obj_is_language_enabled( $locale, $data ) ) {
292 $translation = pods_v( $key . '_' . $locale, $data, null );
293 if ( $translation ) {
294 return $translation;
295 }
296 }
297
298 return $current;
299 }
300
301 /**
302 * Page title for setting pages.
303 *
304 * @since 1.0.0
305 * @see PodsAdmin.php >> admin_menu()
306 * @see PodsAdmin.php >> admin_content_settings()
307 *
308 * @param string $page_title Current page title
309 * @param array $pod Pod data
310 *
311 * @return string
312 */
313 public function translate_admin_menu_page_title( $page_title, $pod ) {
314
315 return (string) $this->get_value_translation( $page_title, 'label', $pod );
316 }
317
318 /**
319 * Menu title for setting pages.
320 *
321 * @since 1.0.0
322 * @see PodsAdmin.php >> admin_menu()
323 *
324 * @param string $menu_label Current menu label
325 * @param array $pod Pod data
326 *
327 * @return string
328 */
329 public function translate_admin_menu_label( $menu_label, $pod ) {
330
331 return (string) $this->get_value_translation( $menu_label, 'menu_name', $pod );
332 }
333
334 /**
335 * Returns the translated label if available.
336 *
337 * @since 1.0.0
338 * @see \Pods\Whatsit >> 'pods_whatsit_get_label' (filter)
339 *
340 * @param string $label The default label.
341 * @param Pods\Whatsit $object The Pod Object.
342 *
343 * @return string
344 */
345 public function translate_label( $label, $object ) {
346
347 return (string) $this->get_value_translation( $label, 'label', $object );
348 }
349
350 /**
351 * Returns the translated description if available.
352 *
353 * @since 1.0.0
354 * @see \Pods\Whatsit >> 'pods_whatsit_get_description' (filter)
355 *
356 * @param string $description The default description.
357 * @param Pods\Whatsit $object The Pod Object.
358 *
359 * @return string
360 */
361 public function translate_description( $description, $object ) {
362
363 return (string) $this->get_value_translation( $description, 'description', $object );
364 }
365
366 /**
367 * Returns the translated argument if available.
368 *
369 * @since 2.8.4
370 * @see \Pods\Whatsit >> 'pods_whatsit_get_arg' (filter)
371 *
372 * @param mixed $arg The object argument.
373 * @param string $name The argument name.
374 * @param array|Pods\Whatsit $object The Pod Object.
375 *
376 * @return string
377 */
378 public function translate_arg( $arg, $name, $object ) {
379
380 if ( $this->is_translatable_field( $name ) ) {
381 return $this->get_value_translation( $arg, $name, $object );
382 }
383
384 return $arg;
385 }
386
387 /**
388 * Returns the translated arguments if available.
389 *
390 * @since 2.8.4
391 * @see \Pods\Whatsit >> 'pods_whatsit_get_args' (filter)
392 *
393 * @param array $args The object arguments.
394 * @param Pods\Whatsit $object The Pod Object.
395 *
396 * @return array
397 */
398 public function translate_args( $args, $object ) {
399
400 foreach ( $args as $name => $value ) {
401 if ( $this->is_translatable_field( $name ) ) {
402 $args[ $name ] = $this->translate_arg( $value, $name, $object );
403 }
404 }
405
406 return $args;
407 }
408
409 /**
410 * Replaces the default selected text with a translation if available.
411 *
412 * @since 1.0.0
413 * @see pick.php >> 'pods_field_pick_data' (filter)
414 *
415 * @param array $data The default data of the field
416 * @param string $name The field name
417 * @param string $value The field value
418 * @param array $options The field options
419 * @param array $pod The Pod
420 * @param int $id The field ID
421 *
422 * @return array
423 */
424 public function translate_field_pick_data( $data, $name, $value, $options, $pod, $id ) {
425
426 if ( isset( $data[''] ) && isset( $options['pick_select_text'] ) ) {
427 $locale = $this->locale;
428 if ( isset( $options[ 'pick_select_text_' . $locale ] ) && array_key_exists( $locale, $this->languages ) && $this->obj_is_language_enabled( $locale, $pod ) ) {
429 $data[''] = $options[ 'pick_select_text_' . $locale ];
430 }
431 }
432
433 return $data;
434 }
435
436 /**
437 * Replaces the default values with a translation if available.
438 *
439 * @since 1.0.0
440 * @see PodsForm.php >> 'pods_form_ui_field_' . $type . '_options' (filter)
441 *
442 * @param array $options The field options
443 * @param string $name The field name
444 * @param string $value The field value
445 * @param array $pod The Pod
446 * @param int $id The field ID
447 *
448 * @return array
449 */
450 public function translate_field_options( $options, $name, $value, $pod, $id ) {
451 $locale = $this->locale;
452 if ( ! array_key_exists( $locale, $this->languages ) || ! $this->obj_is_language_enabled( $locale, $pod ) ) {
453 return $options;
454 }
455
456 foreach ( $this->get_translatable_fields( 'names' ) as $field ) {
457 $translation = pods_v( $field . '_' . $locale, $options, null );
458 if ( $translation ) {
459 $options[ $field ] = $translation;
460 }
461 }
462
463 return $options;
464 }
465
466 /**
467 * Filter hook function to overwrite the labels and description with translations (if available)
468 *
469 * @since 1.0.0
470 * @see PodsInit.php >> setup_content_types()
471 *
472 * @param array $options The array of object options
473 * @param string $object The object type name/slug
474 *
475 * @return array
476 */
477 public function translate_register_wp_object( $options, $object ) {
478
479 $locale = $this->locale;
480
481 $pod = pods_api()->load_pod( $object );
482
483 if ( ! $this->obj_is_language_enabled( $locale, $pod ) ) {
484 return $options;
485 }
486
487 $labels = array(
488 // Default
489 'name' => 'label', // Different.
490 'singular_name' => 'label_singular', // Different.
491 'menu_name' => 'menu_name',
492 'add_new_item' => 'label_add_new_item',
493 'edit_item' => 'label_edit_item',
494 'view_item' => 'label_view_item',
495 'all_items' => 'label_all_items',
496 'search_items' => 'label_search_items',
497 'parent_item_colon' => 'label_parent_item_colon',
498 'not_found' => 'label_not_found',
499 'items_list_navigation' => 'label_items_list_navigation',
500 'items_list' => 'label_items_list',
501
502 // Post Types
503 'name_admin_bar' => 'name_admin_bar',
504 'add_new' => 'label_add_new',
505 'new_item' => 'label_new_item',
506 'edit' => 'label_edit',
507 'view' => 'label_view',
508 'view_items' => 'label_view_items',
509 'parent' => 'label_parent',
510 'not_found_in_trash' => 'label_not_found_in_trash',
511 'archives' => 'label_archives',
512 'attributes' => 'label_attributes',
513 'insert_into_item' => 'label_insert_into_item',
514 'uploaded_to_this_item' => 'label_uploaded_to_this_item',
515 'featured_image' => 'label_featured_image',
516 'set_featured_image' => 'label_set_featured_image',
517 'remove_featured_image' => 'label_remove_featured_image',
518 'use_featured_image' => 'label_use_featured_image',
519 'filter_items_list' => 'label_filter_items_list',
520 // Block Editor (WP 5.0+)
521 'item_published' => 'label_item_published',
522 'item_published_privately' => 'label_item_published_privately',
523 'item_reverted_to_draft' => 'label_item_reverted_to_draft',
524 'item_scheduled' => 'label_item_scheduled',
525 'item_updated' => 'label_item_updated',
526 'filter_by_date' => 'label_filter_by_date', // WP 5.7
527
528 // Taxonomies
529 'update_item' => 'label_update_item',
530 'popular_items' => 'label_popular_items',
531 'parent_item' => 'label_parent_item',
532 'new_item_name' => 'label_new_item_name',
533 'separate_items_with_commas' => 'label_separate_items_with_commas',
534 'add_or_remove_items' => 'label_add_or_remove_items',
535 'choose_from_most_used' => 'label_choose_from_the_most_used', // Different.
536 'no_terms' => 'label_no_terms',
537 'filter_by_item' => 'label_filter_by_item', // WP 5.7
538 );
539
540 if ( ! isset( $options['labels'] ) || ! is_array( $options['labels'] ) ) {
541 $options['labels'] = array();
542 } else {
543 // Try to find new labels.
544 foreach ( $options['labels'] as $key => $val ) {
545 if ( ! isset( $labels[ $key ] ) ) {
546 $labels[ $key ] = 'label_' . $key;
547 }
548 }
549 }
550
551 foreach ( $labels as $key => $pods_key ) {
552 $label = pods_v( $pods_key . '_' . $locale, $pod, '', true );
553 if ( $label ) {
554 $options['labels'][ $key ] = $label;
555 }
556 }
557
558 return $options;
559 }
560
561 /**
562 * Filter hook function to overwrite the labels and description with translations (if available)
563 *
564 * @since 1.0.0
565 * @see PodsInit.php >> admin_menu()
566 *
567 * @param array $options The array of object options
568 * @param string $object The object type name/slug
569 *
570 * @return array
571 */
572 public function translate_object_options( $options, $object ) {
573
574 /**
575 * @todo allow labels to be set even if the default language isn't
576 *
577 * - Find all keys that end with the current locale
578 * - Assign them to the keys without that locale
579 */
580
581 foreach ( $options as $key => $option ) {
582 if ( is_string( $option ) && $this->is_translatable_field( $key ) ) {
583 $options[ $key ] = $this->get_value_translation( $option, $key, $options );
584 }
585 }
586
587 if ( ! empty( $options['options'] ) ) {
588 foreach ( $options['options'] as $key => $option ) {
589 if ( is_string( $option ) && $this->is_translatable_field( $key ) ) {
590 $options['options'][ $key ] = $this->get_value_translation( $option, $key, $options['options'] );
591 }
592 }
593 }
594
595 return $options;
596 }
597
598 /**
599 * Save component settings
600 *
601 * @since 0.1.0
602 */
603 public function admin_save() {
604
605 $this->languages_available = get_available_languages();
606
607 /**
608 * format: array( language, version, updated, english_name, native_name, package, iso, strings )
609 */
610 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
611 $this->languages_translated = wp_get_available_translations();
612
613 $new_languages = array();
614
615 if ( isset( $_POST['pods_i18n_enabled_languages'] ) && is_array( $_POST['pods_i18n_enabled_languages'] ) ) {
616 foreach ( $_POST['pods_i18n_enabled_languages'] as $locale ) {
617 $locale = sanitize_text_field( $locale );
618
619 if ( in_array( $locale, $this->languages_available, true ) ) {
620 $new_languages[ $locale ] = array();
621
622 if ( isset( $this->languages_translated[ $locale ]['language'] ) ) {
623 $new_languages[ $locale ]['language'] = $this->languages_translated[ $locale ]['language'];
624 }
625
626 if ( isset( $this->languages_translated[ $locale ]['english_name'] ) ) {
627 $new_languages[ $locale ]['english_name'] = $this->languages_translated[ $locale ]['english_name'];
628 }
629
630 if ( isset( $this->languages_translated[ $locale ]['native_name'] ) ) {
631 $new_languages[ $locale ]['native_name'] = $this->languages_translated[ $locale ]['native_name'];
632 }
633 }
634 }
635 }//end if
636
637 $this->languages = $new_languages;
638 $this->settings['enabled_languages'] = $new_languages;
639
640 update_option( $this->option_key, $this->settings );
641
642 }
643
644 /**
645 * Build admin area
646 *
647 * @since 0.1.0
648 *
649 * @param $options
650 * @param $component
651 *
652 * @return void
653 */
654 public function admin( $options, $component ) {
655
656 $this->languages_available = get_available_languages();
657
658 /**
659 * format: array( language, version, updated, english_name, native_name, package, iso, strings )
660 */
661 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
662
663 $this->languages_translated = wp_get_available_translations();
664
665 // en_US is always installed (default locale of WP)
666 $data = array(
667 'en_US' => array(
668 'id' => 'en_US',
669 'locale' => 'en_US',
670 'lang' => 'English',
671 'lang_native' => 'English',
672 'enabled' => 'Default',
673 ),
674 );
675
676 foreach ( $this->languages_available as $locale ) {
677 $checked = checked( isset( $this->languages[ $locale ] ), true, false );
678
679 $enabled = sprintf( '<input type="checkbox" name="pods_i18n_enabled_languages[%s]" value="%s"%s />', esc_attr( $locale ), esc_attr( $locale ), $checked );
680
681 $data[ $locale ] = array(
682 'id' => $locale,
683 'locale' => $locale,
684 'lang' => $this->languages_translated[ $locale ]['english_name'],
685 'lang_native' => $this->languages_translated[ $locale ]['native_name'],
686 'enabled' => $enabled,
687 );
688 }
689
690 $ui = array(
691 'component' => $component,
692 // 'data' => $data,
693 // 'total' => count( $data ),
694 // 'total_found' => count( $data ),
695 'items' => __( 'Languages', 'pods' ),
696 'item' => __( 'Language', 'pods' ),
697 'fields' => array(
698 'manage' => array(
699 'enabled' => array(
700 'label' => __( 'Active', 'pods' ),
701 'type' => 'raw',
702 ),
703 'locale' => array(
704 'label' => __( 'Locale', 'pods' ),
705 'classes' => array( 'column-secondary' ),
706 ),
707 'lang' => array( 'label' => __( 'Language', 'pods' ) ),
708 'lang_native' => array( 'label' => __( 'Native name', 'pods' ) ),
709 /*
710 'fields' => array(
711 'label' => __( 'Fields', 'pods' ),
712 'type' => 'text',
713 'options' => array(
714 'text_allow_html' => 1,
715 'text_allowed_html_tags' => 'br code'
716 )
717 ),*/
718 ),
719 ),
720 'actions_disabled' => array( 'edit', 'add', 'delete', 'duplicate', 'view', 'export' ),
721 'actions_custom' => array(
722 // 'add' => array( $this, 'admin_add' ),
723 // 'edit' => array( $this, 'admin_edit' ),
724 // 'delete' => array( $this, 'admin_delete' )
725 ),
726 'search' => false,
727 'searchable' => false,
728 'sortable' => false,
729 'pagination' => false,
730 );
731
732 /**
733 * Filter the language data.
734 *
735 * @since 0.1.0
736 *
737 * @param array $data The language data.
738 */
739 $data = apply_filters( 'pods_component_i18n_admin_data', $data );
740
741 /**
742 * Filter the UI fields.
743 *
744 * @since 0.1.0
745 *
746 * @param array $fields The UI fields.
747 * @param array $data The language data.
748 */
749 $ui['fields'] = apply_filters( 'pods_component_i18n_admin_ui_fields', $ui['fields'], $data );
750
751 $ui['data'] = $data;
752 $ui['total'] = count( $data );
753 $ui['total_found'] = count( $data );
754
755 /*
756 if ( !pods_is_admin( array( 'pods_i18n_activate_lanuages' ) ) )
757 $ui[ 'actions_disabled' ][] = 'edit';*/
758
759 echo '<div id="pods_admin_i18n" class="pods-submittable-fields">';
760
761 // Do save action here because otherwise the loading of post_types get done first and labels aren't translated
762 if ( pods_is_admin( $this->capability ) && isset( $_POST['_nonce_i18n'] ) && wp_verify_nonce( $_POST['_nonce_i18n'], $this->nonce ) ) {
763 pods_message( __( 'Updated active languages.', 'pods' ) );
764 }
765
766 pods_ui( $ui );
767
768 // @todo Do this in pods_ui so we don't rely on javascript
769 echo '<div id="pods_i18n_settings_save">';
770 wp_nonce_field( $this->nonce, '_nonce_i18n', false );
771 submit_button();
772 echo '</div>';
773
774 echo '</div>';
775 }
776
777 /**
778 * The i18n option tab.
779 *
780 * @since 1.0.0
781 *
782 * @param array $tabs
783 *
784 * @return array
785 */
786 public function translation_tab( $tabs ) {
787
788 $tabs['i18n'] = __( 'Translations', 'pods' );
789
790 return $tabs;
791 }
792
793 /**
794 * The i18n options.
795 *
796 * @since 1.0.0
797 *
798 * @param array $options
799 * @param array|Pods\Whatsit $object
800 *
801 * @return array
802 */
803 public function translation_options( $options, $object ) {
804 $i18n_fields = [];
805
806 foreach ( $options as $tab => $fields ) {
807 foreach ( $fields as $name => $field ) {
808 if ( ! $this->is_translatable_field( $name ) ) {
809 continue;
810 }
811
812 $i18n_options = $this->get_translatable_field_options( $name );
813
814 // None of the i18n fields are required!
815 $field['required'] = false;
816
817 $heading_field = $field;
818 $heading_field['type'] = 'heading';
819 $heading_field['name'] = $name . '_i18n';
820
821 $i18n_fields[][ $name . '_i18n' ] = array_merge_recursive( $heading_field, $i18n_options );
822
823 $default_field = $field;
824 $default_field['type'] = 'html';
825 $default_field['name'] = $name . '_i18n_default';
826 $default_field['label'] = __( 'Default', 'pods' );
827 $default_field['html_content'] = '%s';
828 $default_field['html_content_param'] = $name;
829 $default_field['html_content_param_default'] = '-';
830
831 $i18n_fields[][ $name . '_i18n_default' ] = array_merge_recursive( $default_field, $i18n_options );
832
833 foreach ( $this->languages as $locale => $lang_data ) {
834 if ( ! $this->obj_is_language_enabled( $locale, $object ) ) {
835 continue;
836 }
837
838 $locale_name = $name . '_' . $locale;
839 $locale_field = $field;
840 $locale_field['name'] = $locale_name;
841 $locale_field['label'] = $locale;
842 $locale_field['default'] = '';
843
844 $i18n_fields[][ $locale_name ] = array_merge_recursive( $locale_field, $i18n_options );
845 }
846 }
847 }
848
849 $options['i18n'] = $i18n_fields;
850
851 // if ( $object['type'] === '' )
852 /*
853 $options[ 'pods-i18n' ] = array(
854 'enabled_languages' => array(
855 'label' => __( 'Enable/Disable languages for this Pod', 'pods' ),
856 'help' => __( 'This overwrites the defaults set in the component admin.', 'pods' ),
857 'group' => array(),
858 ),
859 );
860
861 foreach ( $this->languages as $locale => $lang_data ) {
862 $options['pods-i18n']['enabled_languages']['group']['enable_i18n'][ $locale ] = array(
863 'label' => $locale . ' (' . $this->create_lang_label( $lang_data ) . ')',
864 'default' => 1,
865 'type' => 'boolean',
866 );
867 }*/
868
869 return $options;
870 }
871
872 /**
873 * Check if a language is get to enabled for an object
874 *
875 * @since 0.1.0
876 *
877 * @param string $locale The locale to validate
878 * @param array $data Object data
879 *
880 * @return bool
881 */
882 public function obj_is_language_enabled( $locale, $data ) {
883
884 // If the locale isn't enabled in the global scope from the component it's always disabled
885 if ( ! array_key_exists( $locale, $this->languages ) ) {
886 return false;
887 }
888 if ( $data instanceof Pods\Whatsit ) {
889 $enable_i18n = $data->get_arg( 'enable_i18n' );
890 } else {
891 $options = pods_v( 'options', $data, $data );
892 $enable_i18n = pods_v( 'enable_i18n', $options, null );
893 }
894
895 if ( null === $enable_i18n ) {
896 // If there are no i18n settings in the object data then assume it's enabled.
897 return true;
898 }
899
900 return (bool) pods_v( $locale, $enable_i18n, true );
901 }
902
903 /**
904 * Create a label with the english and native name combined
905 *
906 * @since 0.1.0
907 *
908 * @param array $lang_data
909 *
910 * @return string
911 */
912 public function create_lang_label( $lang_data ) {
913
914 $label = pods_v( 'english_name', $lang_data, '' );
915 $native_name = pods_v( 'native_name', $lang_data, '' );
916
917 if ( ! empty( $native_name ) && $label !== $native_name ) {
918 $label .= ' / ' . $native_name;
919 }
920
921 return $label;
922 }
923
924 /**
925 * @param string $return Return type (supports 'names').
926 * @return array
927 */
928 public function get_translatable_fields( $return = '' ) {
929
930 /**
931 * Overwrite translatable fields.
932 *
933 * @since 2.8.4
934 *
935 * @param string[] $fields The translatable fields.
936 */
937 $fields = apply_filters( 'pods_translatable_fields', $this->translatable_fields );
938
939 // Backwards compatibility: Before v1.1 this was a list of field names instead of options.
940 foreach ( $fields as $name => $value ) {
941 if ( is_string( $value ) ) {
942 unset( $fields[ $name ] );
943 if ( ! isset( $fields[ $value ] ) ) {
944 $fields[ $value ] = [];
945 }
946 }
947 }
948
949 if ( 'names' === $return ) {
950 return array_keys( $fields );
951 }
952
953 return $fields;
954 }
955
956 /**
957 * @since 2.8.4
958 * @return array[]
959 */
960 public function get_translatable_field_options( $key ) {
961
962 $field_options = pods_v( $key, $this->get_translatable_fields(), array() );
963
964 /**
965 * Overwrite translatable field options.
966 *
967 * @since 2.8.4
968 *
969 * @param array $field_options The translatable field options.
970 * @param string $key The field name.
971 */
972 return apply_filters( 'pods_translatable_field_options', $field_options, $key );
973 }
974 }
975