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