You are here

class AddressItem in Address 8

Plugin implementation of the 'address' field type.

Plugin annotation


@FieldType(
  id = "address",
  label = @Translation("Address"),
  description = @Translation("An entity field containing a postal address"),
  category = @Translation("Address"),
  default_widget = "address_default",
  default_formatter = "address_default",
  list_class = "\Drupal\address\Plugin\Field\FieldType\AddressFieldItemList"
)

Hierarchy

Expanded class hierarchy of AddressItem

File

src/Plugin/Field/FieldType/AddressItem.php, line 30

Namespace

Drupal\address\Plugin\Field\FieldType
View source
class AddressItem extends FieldItemBase implements AddressInterface {
  use AvailableCountriesTrait;

  /**
   * {@inheritdoc}
   */
  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,
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public static function mainPropertyName() {
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  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;
  }

  /**
   * {@inheritdoc}
   */
  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;
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultFieldSettings() {
    return self::defaultCountrySettings() + [
      'langcode_override' => '',
      'field_overrides' => [],
      // Replaced by field_overrides.
      'fields' => [],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
    $languages = \Drupal::languageManager()
      ->getLanguages(LanguageInterface::STATE_ALL);
    $language_options = [];
    foreach ($languages as $langcode => $language) {

      // Only list real languages (English, French, but not "Not specified").
      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;
  }

  /**
   * Form element validation handler: Removes empty field overrides.
   *
   * @param array $element
   *   The field overrides form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state of the entire form.
   */
  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);
  }

  /**
   * Gets the field overrides for the current field.
   *
   * @return array
   *   FieldOverride constants keyed by AddressField constants.
   */
  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;
  }

  /**
   * Initializes and returns the langcode property for the current field.
   *
   * Some countries use separate address formats for the local language VS
   * other languages. For example, China uses major-to-minor ordering
   * when the address is entered in Chinese, and minor-to-major when the
   * address is entered in other languages.
   * This means that the address must remember which language it was
   * entered in, to ensure consistent formatting later on.
   *
   * - For translatable entities this information comes from the field langcode.
   * - Non-translatable entities have no way to provide this information, since
   *   the field langcode never changes. In this case the field must store
   *   the interface language at the time of address creation.
   * - It is also possible to override the used language via field settings,
   *   in case the language is always known (e.g. a field storing the "english
   *   address" on a chinese article).
   *
   * The langcode property is interpreted by getLocale(), and in case it's NULL,
   * the field langcode is returned instead (indicating a non-multilingual site
   * or a translatable parent entity).
   *
   * @return string|null
   *   The langcode, or NULL if the field langcode should be used instead.
   */
  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()) {

      // The getCurrentLanguage fallback is a workaround for core bug #2684873.
      $language = $language_manager
        ->getConfigOverrideLanguage() ?: $language_manager
        ->getCurrentLanguage();
      $this->langcode = $language
        ->getId();
    }
    return $this->langcode;
  }

  /**
   * {@inheritdoc}
   */
  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;
  }

  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    $value = $this->country_code;
    return $value === NULL || $value === '';
  }

  /**
   * {@inheritdoc}
   */
  public function getLocale() {
    $langcode = $this->langcode;
    if (!$langcode) {

      // If no langcode was stored, fallback to the field langcode.
      // Documented in initializeLangcode().
      $langcode = $this
        ->getLangcode();
    }
    return $langcode;
  }

  /**
   * {@inheritdoc}
   */
  public function getCountryCode() {
    return $this->country_code;
  }

  /**
   * {@inheritdoc}
   */
  public function getAdministrativeArea() {
    return $this->administrative_area;
  }

  /**
   * {@inheritdoc}
   */
  public function getLocality() {
    return $this->locality;
  }

  /**
   * {@inheritdoc}
   */
  public function getDependentLocality() {
    return $this->dependent_locality;
  }

  /**
   * {@inheritdoc}
   */
  public function getPostalCode() {
    return $this->postal_code;
  }

  /**
   * {@inheritdoc}
   */
  public function getSortingCode() {
    return $this->sorting_code;
  }

  /**
   * {@inheritdoc}
   */
  public function getAddressLine1() {
    return $this->address_line1;
  }

  /**
   * {@inheritdoc}
   */
  public function getAddressLine2() {
    return $this->address_line2;
  }

  /**
   * {@inheritdoc}
   */
  public function getOrganization() {
    return $this->organization;
  }

  /**
   * {@inheritdoc}
   */
  public function getGivenName() {
    return $this->given_name;
  }

  /**
   * {@inheritdoc}
   */
  public function getAdditionalName() {
    return $this->additional_name;
  }

  /**
   * {@inheritdoc}
   */
  public function getFamilyName() {
    return $this->family_name;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AddressItem::defaultFieldSettings public static function Defines the field-level settings for this plugin. Overrides FieldItemBase::defaultFieldSettings
AddressItem::fieldOverridesValidate public static function Form element validation handler: Removes empty field overrides.
AddressItem::fieldSettingsForm public function Returns a form for the field-level settings. Overrides FieldItemBase::fieldSettingsForm
AddressItem::getAdditionalName public function
AddressItem::getAddressLine1 public function
AddressItem::getAddressLine2 public function
AddressItem::getAdministrativeArea public function
AddressItem::getConstraints public function Gets a list of validation constraints. Overrides TypedData::getConstraints
AddressItem::getCountryCode public function
AddressItem::getDependentLocality public function
AddressItem::getFamilyName public function
AddressItem::getFieldOverrides public function Gets the field overrides for the current field.
AddressItem::getGivenName public function
AddressItem::getLocale public function
AddressItem::getLocality public function
AddressItem::getOrganization public function
AddressItem::getPostalCode public function
AddressItem::getProperties public function Gets an array of property objects. Overrides Map::getProperties
AddressItem::getSortingCode public function
AddressItem::initializeLangcode public function Initializes and returns the langcode property for the current field.
AddressItem::isEmpty public function Determines whether the data structure is empty. Overrides Map::isEmpty
AddressItem::mainPropertyName public static function Returns the name of the main property, if any. Overrides FieldItemBase::mainPropertyName
AddressItem::propertyDefinitions public static function Defines field item properties. Overrides FieldItemInterface::propertyDefinitions
AddressItem::schema public static function Returns the schema for the field. Overrides FieldItemInterface::schema
AvailableCountriesTrait::$availableCountries protected static property An altered list of available countries.
AvailableCountriesTrait::countrySettingsForm public function Builds the field settings form.
AvailableCountriesTrait::defaultCountrySettings public static function Defines the default field-level settings.
AvailableCountriesTrait::getAvailableCountries public function Gets the available countries for the current field.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FieldItemBase::calculateDependencies public static function Calculates dependencies for field items. Overrides FieldItemInterface::calculateDependencies 2
FieldItemBase::calculateStorageDependencies public static function Calculates dependencies for field items on the storage level. Overrides FieldItemInterface::calculateStorageDependencies 1
FieldItemBase::defaultStorageSettings public static function Defines the storage-level settings for this plugin. Overrides FieldItemInterface::defaultStorageSettings 10
FieldItemBase::delete public function Defines custom delete behavior for field values. Overrides FieldItemInterface::delete 2
FieldItemBase::deleteRevision public function Defines custom revision delete behavior for field values. Overrides FieldItemInterface::deleteRevision
FieldItemBase::fieldSettingsFromConfigData public static function Returns a settings array in the field type's canonical representation. Overrides FieldItemInterface::fieldSettingsFromConfigData 1
FieldItemBase::fieldSettingsToConfigData public static function Returns a settings array that can be stored as a configuration value. Overrides FieldItemInterface::fieldSettingsToConfigData 1
FieldItemBase::generateSampleValue public static function Generates placeholder field values. Overrides FieldItemInterface::generateSampleValue 18
FieldItemBase::getEntity public function Gets the entity that field belongs to. Overrides FieldItemInterface::getEntity
FieldItemBase::getFieldDefinition public function Gets the field definition. Overrides FieldItemInterface::getFieldDefinition
FieldItemBase::getLangcode public function Gets the langcode of the field values held in the object. Overrides FieldItemInterface::getLangcode
FieldItemBase::getSetting protected function Returns the value of a field setting.
FieldItemBase::getSettings protected function Returns the array of field settings.
FieldItemBase::onDependencyRemoval public static function Informs the plugin that a dependency of the field will be deleted. Overrides FieldItemInterface::onDependencyRemoval 1
FieldItemBase::postSave public function Defines custom post-save behavior for field values. Overrides FieldItemInterface::postSave 2
FieldItemBase::preSave public function Defines custom presave behavior for field values. Overrides FieldItemInterface::preSave 7
FieldItemBase::setValue public function Sets the data value. Overrides Map::setValue 4
FieldItemBase::storageSettingsForm public function Returns a form for the storage-level settings. Overrides FieldItemInterface::storageSettingsForm 8
FieldItemBase::storageSettingsFromConfigData public static function Returns a settings array in the field type's canonical representation. Overrides FieldItemInterface::storageSettingsFromConfigData 2
FieldItemBase::storageSettingsToConfigData public static function Returns a settings array that can be stored as a configuration value. Overrides FieldItemInterface::storageSettingsToConfigData 2
FieldItemBase::view public function Returns a renderable array for a single field item. Overrides FieldItemInterface::view
FieldItemBase::writePropertyValue protected function Different to the parent Map class, we avoid creating property objects as far as possible in order to optimize performance. Thus we just update $this->values if no property object has been created yet. Overrides Map::writePropertyValue
FieldItemBase::__construct public function Constructs a TypedData object given its definition and context. Overrides TypedData::__construct 1
FieldItemBase::__get public function Magic method: Gets a property value. Overrides FieldItemInterface::__get 2
FieldItemBase::__isset public function Magic method: Determines whether a property is set. Overrides FieldItemInterface::__isset
FieldItemBase::__set public function Magic method: Sets a property value. Overrides FieldItemInterface::__set 1
FieldItemBase::__unset public function Magic method: Unsets a property. Overrides FieldItemInterface::__unset
Map::$definition protected property The data definition. Overrides TypedData::$definition
Map::$properties protected property The array of properties.
Map::$values protected property An array of values for the contained properties.
Map::applyDefaultValue public function Applies the default value. Overrides TypedData::applyDefaultValue 4
Map::get public function Gets a property object. Overrides ComplexDataInterface::get
Map::getIterator public function
Map::getString public function Returns a string representation of the data. Overrides TypedData::getString
Map::getValue public function Gets the data value. Overrides TypedData::getValue 1
Map::onChange public function Overrides TraversableTypedDataInterface::onChange 4
Map::set public function Sets a property value. Overrides ComplexDataInterface::set
Map::toArray public function Returns an array of all property values. Overrides ComplexDataInterface::toArray 1
Map::__clone public function Magic method: Implements a deep clone.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
TypedData::$name protected property The property name.
TypedData::$parent protected property The parent typed data object.
TypedData::createInstance public static function Constructs a TypedData object given its definition and context. Overrides TypedDataInterface::createInstance
TypedData::getDataDefinition public function Gets the data definition. Overrides TypedDataInterface::getDataDefinition
TypedData::getName public function Returns the name of a property or item. Overrides TypedDataInterface::getName
TypedData::getParent public function Returns the parent data structure; i.e. either complex data or a list. Overrides TypedDataInterface::getParent
TypedData::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition
TypedData::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
TypedData::getPropertyPath public function Returns the property path of the data. Overrides TypedDataInterface::getPropertyPath
TypedData::getRoot public function Returns the root of the typed data tree. Overrides TypedDataInterface::getRoot
TypedData::setContext public function Sets the context of a property or item via a context aware parent. Overrides TypedDataInterface::setContext
TypedData::validate public function Validates the currently set data value. Overrides TypedDataInterface::validate
TypedDataTrait::$typedDataManager protected property The typed data manager used for creating the data types.
TypedDataTrait::getTypedDataManager public function Gets the typed data manager. 2
TypedDataTrait::setTypedDataManager public function Sets the typed data manager. 2