1<?php 2 3namespace Drupal\config_translation\FormElement; 4 5use Drupal\Core\Config\Config; 6use Drupal\Core\Language\LanguageInterface; 7use Drupal\config_translation\Form\ConfigTranslationFormBase; 8use Drupal\Core\StringTranslation\StringTranslationTrait; 9use Drupal\Core\TypedData\DataDefinitionInterface; 10use Drupal\Core\TypedData\TraversableTypedDataInterface; 11use Drupal\Core\TypedData\TypedDataInterface; 12use Drupal\language\Config\LanguageConfigOverride; 13 14/** 15 * Defines the list element for the configuration translation interface. 16 */ 17class ListElement implements ElementInterface { 18 19 use StringTranslationTrait; 20 21 /** 22 * The schema element this form is for. 23 * 24 * @var \Drupal\Core\TypedData\TraversableTypedDataInterface 25 */ 26 protected $element; 27 28 /** 29 * Constructs a ListElement. 30 * 31 * @param \Drupal\Core\TypedData\TraversableTypedDataInterface $element 32 * The schema element this form element is for. 33 */ 34 public function __construct(TraversableTypedDataInterface $element) { 35 $this->element = $element; 36 } 37 38 /** 39 * {@inheritdoc} 40 */ 41 public static function create(TypedDataInterface $schema) { 42 return new static($schema); 43 } 44 45 /** 46 * {@inheritdoc} 47 */ 48 public function getTranslationBuild(LanguageInterface $source_language, LanguageInterface $translation_language, $source_config, $translation_config, array $parents, $base_key = NULL) { 49 $build = []; 50 foreach ($this->element as $key => $element) { 51 $sub_build = []; 52 $element_key = isset($base_key) ? "$base_key.$key" : $key; 53 $definition = $element->getDataDefinition(); 54 55 if ($form_element = ConfigTranslationFormBase::createFormElement($element)) { 56 $element_parents = array_merge($parents, [$key]); 57 $sub_build += $form_element->getTranslationBuild($source_language, $translation_language, $source_config[$key], $translation_config[$key], $element_parents, $element_key); 58 59 if (empty($sub_build)) { 60 continue; 61 } 62 63 // Build the sub-structure and include it with a wrapper in the form if 64 // there are any translatable elements there. 65 $build[$key] = []; 66 if ($element instanceof TraversableTypedDataInterface) { 67 $build[$key] = [ 68 '#type' => 'details', 69 '#title' => $this->getGroupTitle($definition, $sub_build), 70 '#open' => empty($base_key), 71 ]; 72 } 73 $build[$key] += $sub_build; 74 } 75 } 76 77 return $build; 78 } 79 80 /** 81 * {@inheritdoc} 82 */ 83 public function setConfig(Config $base_config, LanguageConfigOverride $config_translation, $config_values, $base_key = NULL) { 84 foreach ($this->element as $key => $element) { 85 $element_key = isset($base_key) ? "$base_key.$key" : $key; 86 if ($form_element = ConfigTranslationFormBase::createFormElement($element)) { 87 // Traverse into the next level of the configuration. 88 $value = isset($config_values[$key]) ? $config_values[$key] : NULL; 89 $form_element->setConfig($base_config, $config_translation, $value, $element_key); 90 } 91 } 92 } 93 94 /** 95 * Returns the title for the 'details' element of a group of schema elements. 96 * 97 * For some configuration elements the same element structure can be repeated 98 * multiple times (for example views displays, filters, etc.). Thus, we try to 99 * find a more usable title for the details summary. First check if there is 100 * an element which is called title or label and use its value. Then check if 101 * there is an element which contains these words and use those. Fall back 102 * to the generic definition label if no such element is found. 103 * 104 * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition 105 * The definition of the schema element. 106 * @param array $group_build 107 * The renderable array for the group of schema elements. 108 * 109 * @return string 110 * The title for the group of schema elements. 111 */ 112 protected function getGroupTitle(DataDefinitionInterface $definition, array $group_build) { 113 $title = ''; 114 if (isset($group_build['title']['source'])) { 115 $title = $group_build['title']['source']['#markup']; 116 } 117 elseif (isset($group_build['label']['source'])) { 118 $title = $group_build['label']['source']['#markup']; 119 } 120 else { 121 foreach (array_keys($group_build) as $title_key) { 122 if (isset($group_build[$title_key]['source']) && (strpos($title_key, 'title') !== FALSE || strpos($title_key, 'label') !== FALSE)) { 123 $title = $group_build[$title_key]['source']['#markup']; 124 break; 125 } 126 } 127 } 128 return (!empty($title) ? (strip_tags($title) . ' ') : '') . $this->t($definition['label']); 129 } 130 131} 132