1<?php 2 3namespace Drupal\Core\Field\Plugin\Field\FieldType; 4 5use Drupal\Core\Field\FieldDefinitionInterface; 6use Drupal\Core\Field\FieldStorageDefinitionInterface; 7use Drupal\Core\Field\FieldItemBase; 8use Drupal\Core\Language\LanguageInterface; 9use Drupal\Core\Session\AccountInterface; 10use Drupal\Core\TypedData\DataDefinition; 11use Drupal\Core\TypedData\DataReferenceDefinition; 12use Drupal\Core\TypedData\OptionsProviderInterface; 13 14/** 15 * Defines the 'language' entity field item. 16 * 17 * @FieldType( 18 * id = "language", 19 * label = @Translation("Language"), 20 * description = @Translation("An entity field referencing a language."), 21 * default_widget = "language_select", 22 * default_formatter = "language", 23 * no_ui = TRUE, 24 * constraints = { 25 * "ComplexData" = { 26 * "value" = { 27 * "Length" = {"max" = 12} 28 * } 29 * } 30 * } 31 * ) 32 */ 33class LanguageItem extends FieldItemBase implements OptionsProviderInterface { 34 35 /** 36 * {@inheritdoc} 37 */ 38 public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { 39 $properties['value'] = DataDefinition::create('string') 40 ->setLabel(t('Language code')) 41 ->setRequired(TRUE); 42 43 $properties['language'] = DataReferenceDefinition::create('language') 44 ->setLabel(t('Language object')) 45 ->setDescription(t('The referenced language')) 46 // The language object is retrieved via the language code. 47 ->setComputed(TRUE) 48 ->setReadOnly(FALSE); 49 50 return $properties; 51 } 52 53 /** 54 * {@inheritdoc} 55 */ 56 public static function schema(FieldStorageDefinitionInterface $field_definition) { 57 return [ 58 'columns' => [ 59 'value' => [ 60 'type' => 'varchar_ascii', 61 'length' => 12, 62 ], 63 ], 64 ]; 65 } 66 67 /** 68 * {@inheritdoc} 69 */ 70 public function setValue($values, $notify = TRUE) { 71 // Treat the values as property value of the language property, if no array 72 // is given as this handles language codes and objects. 73 if (isset($values) && !is_array($values)) { 74 $this->set('language', $values, $notify); 75 } 76 else { 77 // Make sure that the 'language' property gets set as 'value'. 78 if (isset($values['value']) && !isset($values['language'])) { 79 $values['language'] = $values['value']; 80 } 81 parent::setValue($values, $notify); 82 } 83 } 84 85 /** 86 * {@inheritdoc} 87 */ 88 public function applyDefaultValue($notify = TRUE) { 89 // Default to the site's default language. When language module is enabled, 90 // this behavior is configurable, see language_field_info_alter(). 91 $this->setValue(['value' => \Drupal::languageManager()->getDefaultLanguage()->getId()], $notify); 92 return $this; 93 } 94 95 /** 96 * {@inheritdoc} 97 */ 98 public function onChange($property_name, $notify = TRUE) { 99 // Make sure that the value and the language property stay in sync. 100 if ($property_name == 'value') { 101 $this->writePropertyValue('language', $this->value); 102 } 103 elseif ($property_name == 'language') { 104 $this->writePropertyValue('value', $this->get('language')->getTargetIdentifier()); 105 } 106 parent::onChange($property_name, $notify); 107 } 108 109 /** 110 * {@inheritdoc} 111 */ 112 public static function generateSampleValue(FieldDefinitionInterface $field_definition) { 113 // Defer to the callback in the item definition as it can be overridden. 114 $constraint = $field_definition->getItemDefinition()->getConstraint('ComplexData'); 115 if (isset($constraint['value']['AllowedValues']['callback'])) { 116 $languages = call_user_func($constraint['value']['AllowedValues']['callback']); 117 } 118 else { 119 $languages = array_keys(\Drupal::languageManager()->getLanguages(LanguageInterface::STATE_ALL)); 120 } 121 $values['value'] = $languages[array_rand($languages)]; 122 return $values; 123 } 124 125 /** 126 * {@inheritdoc} 127 */ 128 public function getPossibleValues(AccountInterface $account = NULL) { 129 return array_keys(\Drupal::languageManager()->getLanguages(LanguageInterface::STATE_ALL)); 130 } 131 132 /** 133 * {@inheritdoc} 134 */ 135 public function getPossibleOptions(AccountInterface $account = NULL) { 136 $languages = \Drupal::languageManager()->getLanguages(LanguageInterface::STATE_ALL); 137 return array_map(function (LanguageInterface $language) { 138 return $language->getName(); 139 }, $languages); 140 } 141 142 /** 143 * {@inheritdoc} 144 */ 145 public function getSettableValues(AccountInterface $account = NULL) { 146 return $this->getPossibleValues($account); 147 } 148 149 /** 150 * {@inheritdoc} 151 */ 152 public function getSettableOptions(AccountInterface $account = NULL) { 153 return $this->getPossibleValues($account); 154 } 155 156} 157