View source
<?php
namespace Drupal\address\Plugin\Field\FieldType;
use CommerceGuys\Addressing\AddressFormat\AddressField;
use CommerceGuys\Addressing\AddressFormat\FieldOverride;
use CommerceGuys\Addressing\AddressFormat\FieldOverrides;
use Drupal\address\AddressInterface;
use Drupal\address\FieldHelper;
use Drupal\address\LabelHelper;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\TypedData\DataDefinition;
class AddressItem extends FieldItemBase implements AddressInterface {
use AvailableCountriesTrait;
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'langcode' => [
'type' => 'varchar',
'length' => 32,
],
'country_code' => [
'type' => 'varchar',
'length' => 2,
],
'administrative_area' => [
'type' => 'varchar',
'length' => 255,
],
'locality' => [
'type' => 'varchar',
'length' => 255,
],
'dependent_locality' => [
'type' => 'varchar',
'length' => 255,
],
'postal_code' => [
'type' => 'varchar',
'length' => 255,
],
'sorting_code' => [
'type' => 'varchar',
'length' => 255,
],
'address_line1' => [
'type' => 'varchar',
'length' => 255,
],
'address_line2' => [
'type' => 'varchar',
'length' => 255,
],
'organization' => [
'type' => 'varchar',
'length' => 255,
],
'given_name' => [
'type' => 'varchar',
'length' => 255,
],
'additional_name' => [
'type' => 'varchar',
'length' => 255,
],
'family_name' => [
'type' => 'varchar',
'length' => 255,
],
],
];
}
public static function mainPropertyName() {
return NULL;
}
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties = [];
$properties['langcode'] = DataDefinition::create('string')
->setLabel(t('The language code'));
$properties['country_code'] = DataDefinition::create('string')
->setLabel(t('The two-letter country code'));
$properties['administrative_area'] = DataDefinition::create('string')
->setLabel(t('The top-level administrative subdivision of the country'));
$properties['locality'] = DataDefinition::create('string')
->setLabel(t('The locality (i.e. city)'));
$properties['dependent_locality'] = DataDefinition::create('string')
->setLabel(t('The dependent locality (i.e. neighbourhood)'));
$properties['postal_code'] = DataDefinition::create('string')
->setLabel(t('The postal code'));
$properties['sorting_code'] = DataDefinition::create('string')
->setLabel(t('The sorting code'));
$properties['address_line1'] = DataDefinition::create('string')
->setLabel(t('The first line of the address block'));
$properties['address_line2'] = DataDefinition::create('string')
->setLabel(t('The second line of the address block'));
$properties['organization'] = DataDefinition::create('string')
->setLabel(t('The organization'));
$properties['given_name'] = DataDefinition::create('string')
->setLabel(t('The given name'));
$properties['additional_name'] = DataDefinition::create('string')
->setLabel(t('The additional name'));
$properties['family_name'] = DataDefinition::create('string')
->setLabel(t('The family name'));
return $properties;
}
public function getProperties($include_computed = FALSE) {
$properties = parent::getProperties($include_computed);
$parsed_overrides = new FieldOverrides($this
->getFieldOverrides());
$hidden_properties = array_map(static function ($name) {
return FieldHelper::getPropertyName($name);
}, $parsed_overrides
->getHiddenFields());
foreach ($hidden_properties as $hidden_property) {
unset($properties[$hidden_property]);
}
return $properties;
}
public static function defaultFieldSettings() {
return self::defaultCountrySettings() + [
'langcode_override' => '',
'field_overrides' => [],
'fields' => [],
];
}
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$languages = \Drupal::languageManager()
->getLanguages(LanguageInterface::STATE_ALL);
$language_options = [];
foreach ($languages as $langcode => $language) {
if (!$language
->isLocked()) {
$language_options[$langcode] = $language
->getName();
}
}
$element = $this
->countrySettingsForm($form, $form_state);
$element['langcode_override'] = [
'#type' => 'select',
'#title' => $this
->t('Language override'),
'#description' => $this
->t('Ensures entered addresses are always formatted in the same language.'),
'#options' => $language_options,
'#default_value' => $this
->getSetting('langcode_override'),
'#empty_option' => $this
->t('- No override -'),
'#access' => \Drupal::languageManager()
->isMultilingual(),
];
$element['field_overrides_title'] = [
'#type' => 'item',
'#title' => $this
->t('Field overrides'),
'#description' => $this
->t('Use field overrides to override the country-specific address format, forcing specific properties to always be hidden, optional, or required.'),
];
$element['field_overrides'] = [
'#type' => 'table',
'#header' => [
$this
->t('Property'),
$this
->t('Override'),
],
'#element_validate' => [
[
get_class($this),
'fieldOverridesValidate',
],
],
];
$field_overrides = $this
->getFieldOverrides();
foreach (LabelHelper::getGenericFieldLabels() as $field_name => $label) {
$override = isset($field_overrides[$field_name]) ? $field_overrides[$field_name] : '';
$element['field_overrides'][$field_name] = [
'field_label' => [
'#type' => 'markup',
'#markup' => $label,
],
'override' => [
'#type' => 'select',
'#options' => [
FieldOverride::HIDDEN => $this
->t('Hidden'),
FieldOverride::OPTIONAL => $this
->t('Optional'),
FieldOverride::REQUIRED => $this
->t('Required'),
],
'#default_value' => $override,
'#empty_option' => $this
->t('- No override -'),
],
];
}
return $element;
}
public static function fieldOverridesValidate(array $element, FormStateInterface $form_state) {
$overrides = $form_state
->getValue($element['#parents']);
$overrides = array_filter($overrides, function ($data) {
return !empty($data['override']);
});
$form_state
->setValue($element['#parents'], $overrides);
}
public function getFieldOverrides() {
$field_overrides = [];
if ($fields = $this
->getSetting('fields')) {
$unused_fields = array_diff(AddressField::getAll(), $fields);
foreach ($unused_fields as $field) {
$field_overrides[$field] = FieldOverride::HIDDEN;
}
}
elseif ($overrides = $this
->getSetting('field_overrides')) {
foreach ($overrides as $field => $data) {
$field_overrides[$field] = $data['override'];
}
}
return $field_overrides;
}
public function initializeLangcode() {
$this->langcode = NULL;
$language_manager = \Drupal::languageManager();
if (!$language_manager
->isMultilingual()) {
return;
}
if ($override = $this
->getSetting('langcode_override')) {
$this->langcode = $override;
}
elseif (!$this
->getEntity()
->isTranslatable()) {
$language = $language_manager
->getConfigOverrideLanguage() ?: $language_manager
->getCurrentLanguage();
$this->langcode = $language
->getId();
}
return $this->langcode;
}
public function getConstraints() {
$constraints = parent::getConstraints();
$constraint_manager = $this
->getTypedDataManager()
->getValidationConstraintManager();
$field_overrides = new FieldOverrides($this
->getFieldOverrides());
$constraints[] = $constraint_manager
->create('ComplexData', [
'country_code' => [
'Country' => [
'availableCountries' => $this
->getAvailableCountries(),
],
],
]);
$constraints[] = $constraint_manager
->create('AddressFormat', [
'fieldOverrides' => $field_overrides,
]);
return $constraints;
}
public function isEmpty() {
$value = $this->country_code;
return $value === NULL || $value === '';
}
public function getLocale() {
$langcode = $this->langcode;
if (!$langcode) {
$langcode = $this
->getLangcode();
}
return $langcode;
}
public function getCountryCode() {
return $this->country_code;
}
public function getAdministrativeArea() {
return $this->administrative_area;
}
public function getLocality() {
return $this->locality;
}
public function getDependentLocality() {
return $this->dependent_locality;
}
public function getPostalCode() {
return $this->postal_code;
}
public function getSortingCode() {
return $this->sorting_code;
}
public function getAddressLine1() {
return $this->address_line1;
}
public function getAddressLine2() {
return $this->address_line2;
}
public function getOrganization() {
return $this->organization;
}
public function getGivenName() {
return $this->given_name;
}
public function getAdditionalName() {
return $this->additional_name;
}
public function getFamilyName() {
return $this->family_name;
}
}