Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/address
  • issue/address-3189074
  • issue/address-3195984
  • issue/address-3200084
  • issue/address-3200808
  • issue/address-3173870
  • issue/address-2929046
  • issue/address-3186888
  • issue/address-3091072
  • issue/address-3065026
  • issue/address-3226235
  • issue/address-3226772
  • issue/address-2882589
  • issue/address-2812659
  • issue/address-3281819
  • issue/address-3248889
  • issue/address-2890007
  • issue/address-3252472
  • issue/address-2921585
  • issue/address-3258096
  • issue/address-3257718
  • issue/address-3291035
  • issue/address-3178980
  • issue/address-3296144
  • issue/address-3230992
  • issue/address-3302484
  • issue/address-3317776
  • issue/address-2995992
  • issue/address-3322810
  • issue/address-3337571
  • issue/address-3333975
  • issue/address-2870159
  • issue/address-3144823
  • issue/address-3322797
  • issue/address-3346844
  • issue/address-3112487
  • issue/address-3350959
  • issue/address-3357838
  • issue/address-3357837
  • issue/address-3045575
  • issue/address-3362128
  • issue/address-3369161
  • issue/address-3401422
  • issue/address-3401959
  • issue/address-2857593
  • issue/address-3409803
  • issue/address-2753899
  • issue/address-3413017
  • issue/address-3413295
  • issue/address-3413640
  • issue/address-3413859
  • issue/address-3414148
  • issue/address-3419334
  • issue/address-3412241
  • issue/address-3419634
  • issue/address-2868049
  • issue/address-3425922
  • issue/address-3428737
  • issue/address-3443604
  • issue/address-3438123
  • issue/address-2626982
  • issue/address-3467623
  • issue/address-2819251
  • issue/address-2995680
  • issue/address-3486993
  • issue/address-3492425
  • issue/address-3494191
  • issue/address-3495167
  • issue/address-3495659
  • issue/address-3495694
  • issue/address-3495973
  • issue/address-3495975
  • issue/address-3497225
  • issue/address-3454405
  • issue/address-3499837
75 results
Show changes
Commits on Source (16)
Showing
with 170 additions and 358 deletions
......@@ -5,11 +5,8 @@
* Requirements and update functions for the address module.
*/
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
use Drupal\Core\Entity\Sql\SqlContentEntityStorageException;
use Drupal\Core\Utility\UpdateException;
use Drupal\field\Entity\FieldConfig;
/**
* Implements hook_requirements().
......@@ -28,7 +25,6 @@ function address_requirements($phase) {
return $requirements;
}
/**
* Add the address_line3 field.
*/
......
......@@ -5,6 +5,7 @@
* Provides functionality for handling postal addresses.
*/
use Drupal\address\AddressInterface;
use Drupal\Core\Entity\EntityInterface;
/**
......@@ -39,18 +40,20 @@ function address_theme() {
*/
function address_theme_suggestions_address_plain(array $variables) {
$suggestions = [];
$original = $variables['theme_hook_original'] . '__';
$field = $variables['address']->getFieldDefinition();
$entity_type_id = $field->getTargetEntityTypeId();
$bundle = $field->getTargetBundle();
$sanitized_view_mode = strtr($variables['view_mode'], '.', '_');
if (!empty($variables['address']) && $variables['address'] instanceof AddressInterface) {
$original = $variables['theme_hook_original'] . '__';
$field = $variables['address']->getFieldDefinition();
$entity_type_id = $field->getTargetEntityTypeId();
$bundle = $field->getTargetBundle();
$sanitized_view_mode = strtr($variables['view_mode'], '.', '_');
$suggestions[] = $original . $entity_type_id . '__' . $sanitized_view_mode;
$suggestions[] = $original . $entity_type_id . '__' . $bundle;
$suggestions[] = $original . $entity_type_id . '__' . $bundle . '__' . $sanitized_view_mode;
$suggestions[] = $original . $field->getName();
$suggestions[] = $original . $entity_type_id . '__' . $field->getName();
$suggestions[] = $original . $entity_type_id . '__' . $field->getName() . '__' . $bundle;
$suggestions[] = $original . $entity_type_id . '__' . $sanitized_view_mode;
$suggestions[] = $original . $entity_type_id . '__' . $bundle;
$suggestions[] = $original . $entity_type_id . '__' . $bundle . '__' . $sanitized_view_mode;
$suggestions[] = $original . $field->getName();
$suggestions[] = $original . $entity_type_id . '__' . $field->getName();
$suggestions[] = $original . $entity_type_id . '__' . $field->getName() . '__' . $bundle;
}
return $suggestions;
}
......@@ -65,7 +68,7 @@ function address_theme_suggestions_address_plain(array $variables) {
*/
function _address_update_entity(EntityInterface $entity, $field_name) {
$update_helper = '\CommerceGuys\Addressing\UpdateHelper';
foreach ($entity->{$field_name} as $delta => $address) {
foreach ($entity->{$field_name} as $address) {
$names = $update_helper::splitRecipient($address->given_name, $address->country_code);
$address->given_name = $names['givenName'];
$address->family_name = $names['familyName'];
......
<?php
/**
* @file
* Contains post-update hooks for Address.
*/
declare(strict_types = 1);
use Drupal\Core\Config\Entity\ConfigEntityUpdater;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
/**
* Add the "Wrapper type" setting to the default widget.
*/
function address_post_update_default_widget_wrapper(array &$sandbox = NULL): void {
\Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'entity_form_display', function (EntityFormDisplayInterface $form_display): bool {
$changed = FALSE;
foreach ($form_display->getComponents() as $field => $component) {
if (array_key_exists('type', $component)
&& ($component['type'] === 'address_default')
&& !array_key_exists('wrapper_type', $component['settings'])) {
$component['settings']['wrapper_type'] = 'details';
$form_display->setComponent($field, $component);
$changed = TRUE;
}
}
return $changed;
});
}
......@@ -5,8 +5,8 @@
* Provides Token integration for Address.
*/
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Render\BubbleableMetadata;
/**
* Implements hook_token_info().
......
......@@ -7,16 +7,9 @@
"require": {
"php": "^8.0",
"drupal/core": "^9.5 || ^10",
"commerceguys/addressing": "^2.1.0"
"commerceguys/addressing": "^2.1.1"
},
"require-dev": {
"drupal/token": "^1.0"
},
"extra": {
"drush": {
"services": {
"drush.services.yml": "^11"
}
}
}
}
......@@ -56,7 +56,7 @@ address_zone:
type: sequence
label: 'Territories'
sequence:
- type: address_zone_territory
type: address_zone_territory
address_zone_territory:
type: mapping
......@@ -104,7 +104,7 @@ field.field_settings.address:
type: sequence
label: 'Available countries'
sequence:
- type: string
type: string
langcode_override:
type: string
label: 'Language override'
......@@ -122,7 +122,7 @@ field.field_settings.address:
type: sequence
label: 'Used fields'
sequence:
- type: string
type: string
field.field_settings.address_country:
type: mapping
......@@ -132,7 +132,7 @@ field.field_settings.address_country:
type: sequence
label: 'Available countries'
sequence:
- type: string
type: string
field.field_settings.address_zone:
type: mapping
......@@ -142,11 +142,15 @@ field.field_settings.address_zone:
type: sequence
label: 'Available countries'
sequence:
- type: string
type: string
field.widget.settings.address_default:
type: mapping
label: 'Default address widget settings'
mapping:
wrapper_type:
type: string
label: Wrapper type
field.widget.settings.address_zone_default:
type: mapping
......
services:
address.commands.sanitize:
class: Drupal\address\Commands\SanitizeAddress
arguments:
- '@database'
- '@entity_field.manager'
- '@entity_type.manager'
tags:
- { name: drush.command }
......@@ -9,8 +9,8 @@
"url": "https://github.com/doctrine/deprecations/archive/v1.1.1.zip"
},
"commerceguys/addressing": {
"version": "v2.1.0",
"url": "https://github.com/commerceguys/addressing/archive/v2.1.0.zip"
"version": "v2.1.1",
"url": "https://github.com/commerceguys/addressing/archive/v2.1.1.zip"
}
}
}
<?php
namespace Drupal\address\Commands;
use Consolidation\AnnotatedCommand\CommandData;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Sql\DefaultTableMapping;
use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
use Drush\Commands\DrushCommands;
use Drush\Drupal\Commands\sql\SanitizePluginInterface;
use Symfony\Component\Console\Input\InputInterface;
/**
* Provides a drush sql:sanitize plugin for address fields.
*
* It overwrites key columns with fixed data.
*/
class SanitizeAddress extends DrushCommands implements SanitizePluginInterface {
/**
* The address field columns to be sanitized.
*
* @var string[]
*/
const FIELD_COLUMNS = [
'country_code',
'administrative_area',
'locality',
'dependent_locality',
'postal_code',
'sorting_code',
'address_line1',
'address_line2',
'address_line3',
'organization',
'given_name',
'additional_name',
'family_name',
];
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Creates the address field sanitizer.
*
* @param \Drupal\Core\Database\Connection $database
* The database connection.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(Connection $database, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct();
$this->database = $database;
$this->entityFieldManager = $entity_field_manager;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*
* Overwrites address field columns.
*
* @hook post-command sql-sanitize
*/
public function sanitize($result, CommandData $commandData) {
$address_fields = $this->getAddressFields($commandData->options());
foreach ($address_fields as $entity_type_id => $field_names) {
$context = ['@entity_type_id' => $entity_type_id];
try {
$storage = $this->entityTypeManager->getStorage($entity_type_id);
$mapping = $this->getTableMapping($entity_type_id);
foreach ($field_names as $field_name) {
$column_names = $mapping->getColumnNames($field_name);
foreach ($this->getAllFieldTableNames($entity_type_id, $field_name) as $field_table) {
foreach (static::FIELD_COLUMNS as $field_column) {
$this->sanitizeColumn($field_table, $column_names[$field_column], $field_column);
}
}
}
$storage->resetCache();
$this->logger()
->success(dt('Sanitized @entity_type_id address fields.', $context));
}
catch (\Exception $e) {
$context += ['@message' => $e->getMessage()];
$this->logger()->warning(dt("Unable to sanitize @enitity_type_id address fields: @message", $context));
}
}
}
/**
* {@inheritdoc}
*
* @hook on-event sql-sanitize-confirms
*/
public function messages(&$messages, InputInterface $input) {
$messages[] = dt('Sanitize address fields.');
}
/**
* Returns the names of address fields to be sanitized.
*
* @return string[][]
* An associative array keyed by entity type ID of arrays of field names.
*/
protected function getAddressFields(array $options) {
// Get an array of arrays of address field names, keyed by entity type ID.
$fields = array_map(function (array $field_bundle_data) {
return array_keys($field_bundle_data);
}, $this->entityFieldManager->getFieldMapByFieldType('address'));
// Filter out allowed fields.
$allowed = $this->getAllowedFields($options);
$filtered = array_map(function (array $field_names) use ($allowed) {
return array_diff($field_names, $allowed);
}, $fields);
// Filter out entity types that no longer have any fields to be sanitized.
return array_filter($filtered);
}
/**
* Returns the fields that have been explicitly allowed via an option.
*
* It supports the 'allowlist-fields' and deprecated 'whitelist-fields'
* options.
*
* @param array $options
* The options array.
*
* @return string[]
* An array of allowed field names.
*
* @see \Drush\Drupal\Commands\sql\SanitizeUserFieldsCommands::options()
*/
protected function getAllowedFields(array $options) {
/** @deprecated Use $options['allowlist-fields'] instead. */
$allowed = explode(',', $options['whitelist-fields']);
$allowed = array_merge($allowed, explode(',', $options['allowlist-fields']));
return array_filter($allowed);
}
/**
* Update a table column with sanitized data.
*
* @param string $table
* The table name to update.
* @param string $column
* The database column name to update.
* @param string $field_name
* The field name to update.
*/
protected function sanitizeColumn(string $table, string $column, string $field_name) {
$not_empty = $this->database->condition('AND')
->condition($column, NULL, 'IS NOT NULL')
->condition($column, '', '<>');
$replacement = '[' . dt('Sanitized') . ']';
// Certain fields have expected formatting.
if ($field_name == 'country_code') {
$replacement = 'US';
}
elseif ($field_name == 'administrative_area') {
$replacement = 'DC';
}
elseif ($field_name == 'postal_code') {
$replacement = '20500';
}
$this->database->update($table)
->condition($not_empty)
->fields([$column => $replacement])
->execute();
}
/**
* Gets all the table names in which an entity field is stored.
*
* When there's no need to support Drupal 8 switch to
* Drupal\Core\Entity\Sql\TableMappingInterface::getAllFieldTableNames().
*
* @param string $entity_type_id
* The ID of the entity type the field's attached to.
* @param string $field_name
* The name of the entity field to return the tables names for.
*
* @return string[]
* An indexed array of table names.
*/
protected function getAllFieldTableNames($entity_type_id, $field_name) {
$mapping = $this->getDefaultTableMapping($entity_type_id);
$entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
$definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type_id);
$definition = $definitions[$field_name];
$tables = [$mapping->getFieldTableName($field_name)];
// Ensure we get both the main table and revision table where appropriate.
if ($entity_type->isRevisionable()) {
if ($mapping->requiresDedicatedTableStorage($definition)) {
$tables[] = $mapping->getDedicatedRevisionTableName($definition);
}
else {
$tables[] = $entity_type->getRevisionDataTable();
}
}
return $tables;
}
/**
* Returns the table mapping for a given entity type backed by SQL storage.
*
* @param string $entity_type_id
* The entity type ID to get the table mapping for.
*
* @return \Drupal\Core\Entity\Sql\TableMappingInterface
* The table mapping object.
*
* @throws \RuntimeException
* If the entity storage doesn't implement \Drupal\Core\Entity\Sql\SqlEntityStorageInterface.
*/
protected function getTableMapping($entity_type_id) {
$storage = $this->entityTypeManager->getStorage($entity_type_id);
if (!$storage instanceof SqlEntityStorageInterface) {
$context = ['!entity_type_id' => $entity_type_id];
throw new \RuntimeException(dt("Unable to get table mapping from !entity_type_id entity storage service.", $context));
}
return $storage->getTableMapping();
}
/**
* Returns the table mapping for an entity type.
*
* In Drupal 8 the table mapping interface didn't provide sufficient methods
* for some kinds of low-level operations and we need to tightly couple to the
* core default table mapping class rather than an interface.
*
* @param string $entity_type_id
* The entity type to get the table mapping for.
*
* @return \Drupal\Core\Entity\Sql\DefaultTableMapping
* The table mapping object.
*
* @throws \RuntimeException
* If the entity type storage doesn't use or expose the default table
* mapping.
*
* @see https://www.drupal.org/project/drupal/issues/2960147
*/
protected function getDefaultTableMapping($entity_type_id) {
$mapping = $this->getTableMapping($entity_type_id);
if (!$mapping instanceof DefaultTableMapping) {
throw new \RuntimeException(dt("Table mapping class must be instance of DefaultTableMapping"));
}
return $mapping;
}
}
......@@ -61,8 +61,6 @@ class Address extends FormElement {
'#available_countries' => [],
// FieldOverride constants keyed by AddressField constants.
'#field_overrides' => [],
// Deprecated. Use #field_overrides instead.
'#used_fields' => [],
'#input' => TRUE,
'#multiple' => FALSE,
......@@ -151,18 +149,9 @@ class Address extends FormElement {
* The processed element.
*
* @throws \InvalidArgumentException
* Thrown when #used_fields is malformed.
* Thrown when #field_overrides is malformed.
*/
public static function processAddress(array &$element, FormStateInterface $form_state, array &$complete_form) {
// Convert #used_fields into #field_overrides.
if (!empty($element['#used_fields']) && is_array($element['#used_fields'])) {
$unused_fields = array_diff(AddressField::getAll(), $element['#used_fields']);
$element['#field_overrides'] = [];
foreach ($unused_fields as $field) {
$element['#field_overrides'][$field] = FieldOverride::HIDDEN;
}
unset($element['#used_fields']);
}
// Validate and parse #field_overrides.
if (!is_array($element['#field_overrides'])) {
throw new \InvalidArgumentException('The #field_overrides property must be an array.');
......@@ -251,7 +240,7 @@ class Address extends FormElement {
];
}
foreach ($line_fields as $field_index => $field) {
foreach ($line_fields as $field) {
$property = FieldHelper::getPropertyName($field);
$class = str_replace('_', '-', $property);
......
......@@ -141,6 +141,11 @@ class Country extends FormElement {
}
$default_country = key($country_list);
$site_country = \Drupal::config('system.date')->get('country.default');
if ($site_country && isset($country_list[$site_country])) {
$default_country = $site_country;
}
return $default_country;
}
......
......@@ -2,10 +2,10 @@
namespace Drupal\address\Element;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
/**
* Provides a zone form element.
......
......@@ -2,14 +2,14 @@
namespace Drupal\address\Element;
use CommerceGuys\Addressing\AddressFormat\AddressFormat;
use CommerceGuys\Addressing\AddressFormat\AddressField;
use CommerceGuys\Addressing\AddressFormat\AddressFormat;
use Drupal\address\FieldHelper;
use Drupal\address\LabelHelper;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
/**
* Provides a zone territory form element.
......@@ -118,9 +118,6 @@ class ZoneTerritory extends FormElement {
*
* @return array
* The processed element.
*
* @throws \InvalidArgumentException
* Thrown when #available_countries or #used_fields is malformed.
*/
public static function processTerritory(array &$element, FormStateInterface $form_state, array &$complete_form) {
$id_prefix = implode('-', $element['#parents']);
......
......@@ -3,11 +3,11 @@
namespace Drupal\address;
use CommerceGuys\Addressing\AddressFormat\AddressField;
use CommerceGuys\Addressing\AddressFormat\AddressFormat;
use CommerceGuys\Addressing\AddressFormat\AdministrativeAreaType;
use CommerceGuys\Addressing\AddressFormat\DependentLocalityType;
use CommerceGuys\Addressing\AddressFormat\LocalityType;
use CommerceGuys\Addressing\AddressFormat\PostalCodeType;
use CommerceGuys\Addressing\AddressFormat\AddressFormat;
/**
* Provides translated labels for the library enums.
......@@ -63,7 +63,8 @@ class LabelHelper {
AddressField::FAMILY_NAME => t('Last name', [], ['context' => 'Address label']),
AddressField::ORGANIZATION => t('Organization', [], ['context' => 'Address label']),
AddressField::ADDRESS_LINE1 => t('Street address', [], ['context' => 'Address label']),
// The address line 2 and 3 labels are usually shown only to screen-reader users.
// The address line 2 and 3 labels are
// usually shown only to screen-reader users.
AddressField::ADDRESS_LINE2 => t('Street address line 2', [], ['context' => 'Address label']),
AddressField::ADDRESS_LINE3 => t('Street address line 3', [], ['context' => 'Address label']),
AddressField::POSTAL_CODE => self::getPostalCodeLabel($postal_code_type),
......
......@@ -11,9 +11,9 @@ use CommerceGuys\Addressing\Subdivision\SubdivisionRepositoryInterface;
use Drupal\address\AddressInterface;
use Drupal\address\FieldHelper;
use Drupal\Component\Utility\Html;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Element;
......@@ -120,6 +120,7 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP
'#cache' => [
'contexts' => [
'languages:' . LanguageInterface::TYPE_INTERFACE,
'languages:' . LanguageInterface::TYPE_CONTENT,
],
],
];
......@@ -141,8 +142,12 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP
* A renderable array.
*/
protected function viewElement(AddressInterface $address, $langcode) {
// If the parent entity is non-translatable, $address->getLocale() contains
// the interface language at the time of address creation, while $langcode
// contains the current interface language. Our goal is to have the country
// name be recognizable by all users, making $langcode a safer bet.
$countries = $this->countryRepository->getList($langcode);
$country_code = $address->getCountryCode();
$countries = $this->countryRepository->getList();
$address_format = $this->addressFormatRepository->get($country_code);
$values = $this->getValues($address, $address_format);
......
......@@ -9,9 +9,9 @@ use CommerceGuys\Addressing\Country\CountryRepositoryInterface;
use CommerceGuys\Addressing\Locale;
use CommerceGuys\Addressing\Subdivision\SubdivisionRepositoryInterface;
use Drupal\address\AddressInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -125,8 +125,12 @@ class AddressPlainFormatter extends FormatterBase implements ContainerFactoryPlu
* A renderable array.
*/
protected function viewElement(AddressInterface $address, $langcode) {
// If the parent entity is non-translatable, $address->getLocale() contains
// the interface language at the time of address creation, while $langcode
// contains the current interface language. Our goal is to have the country
// name be recognizable by all users, making $langcode a safer bet.
$countries = $this->countryRepository->getList($langcode);
$country_code = $address->getCountryCode();
$countries = $this->countryRepository->getList();
$address_format = $this->addressFormatRepository->get($country_code);
$values = $this->getValues($address, $address_format);
......@@ -153,6 +157,7 @@ class AddressPlainFormatter extends FormatterBase implements ContainerFactoryPlu
'#cache' => [
'contexts' => [
'languages:' . LanguageInterface::TYPE_INTERFACE,
'languages:' . LanguageInterface::TYPE_CONTENT,
],
],
];
......@@ -190,13 +195,17 @@ class AddressPlainFormatter extends FormatterBase implements ContainerFactoryPlu
];
if (empty($value)) {
// This level is empty, so there can be no sublevels.
break;
// This level is empty, but it might be optional so check sublevels.
continue;
}
$parents[] = $index ? $original_values[$subdivision_fields[$index - 1]] : $address->getCountryCode();
$parents[] = ($index > 0 && !empty($original_values[$subdivision_fields[$index - 1]]))
? $original_values[$subdivision_fields[$index - 1]]
: $address->getCountryCode();
$subdivision = $this->subdivisionRepository->get($value, $parents);
if (!$subdivision) {
break;
continue;
}
// Remember the original value so that it can be used for $parents.
......
......@@ -3,9 +3,9 @@
namespace Drupal\address\Plugin\Field\FieldFormatter;
use CommerceGuys\Addressing\Country\CountryRepositoryInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -76,14 +76,14 @@ class CountryDefaultFormatter extends FormatterBase implements ContainerFactoryP
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$countries = $this->countryRepository->getList();
$countries = $this->countryRepository->getList($langcode);
$elements = [];
foreach ($items as $delta => $item) {
$elements[$delta] = [
'#plain_text' => $countries[$item->value] ?? $item->value,
'#cache' => [
'contexts' => [
'languages:' . LanguageInterface::TYPE_INTERFACE,
'languages:' . LanguageInterface::TYPE_CONTENT,
],
],
];
......
......@@ -109,7 +109,7 @@ class ZoneDefaultFormatter extends FormatterBase implements ContainerFactoryPlug
'#type' => 'container',
'#cache' => [
'contexts' => [
'languages:' . LanguageInterface::TYPE_INTERFACE,
'languages:' . LanguageInterface::TYPE_CONTENT,
],
],
];
......@@ -133,7 +133,7 @@ class ZoneDefaultFormatter extends FormatterBase implements ContainerFactoryPlug
* A renderable array.
*/
protected function viewElement(Zone $zone, $langcode) {
$countries = $this->countryRepository->getList();
$countries = $this->countryRepository->getList($langcode);
$element = [
'#type' => 'container',
'#attributes' => [
......@@ -185,7 +185,10 @@ class ZoneDefaultFormatter extends FormatterBase implements ContainerFactoryPlug
];
}
if ($locality = $territory->getLocality()) {
$localities = $this->subdivisionRepository->getList([$country_code, $administrative_area]);
$localities = $this->subdivisionRepository->getList([
$country_code,
$administrative_area,
]);
$locality_name = $locality;
if (isset($localities[$locality])) {
$locality_name = $localities[$locality];
......@@ -201,7 +204,11 @@ class ZoneDefaultFormatter extends FormatterBase implements ContainerFactoryPlug
];
}
if ($dependent_locality = $territory->getDependentLocality()) {
$dependent_localities = $this->subdivisionRepository->getList([$country_code, $administrative_area, $locality]);
$dependent_localities = $this->subdivisionRepository->getList([
$country_code,
$administrative_area,
$locality,
]);
$dependent_locality_name = $dependent_locality;
if (isset($dependent_localities[$dependent_locality])) {
$dependent_locality_name = $dependent_localities[$dependent_locality];
......
......@@ -25,7 +25,65 @@ use Drupal\Core\TypedData\DataDefinition;
* category = @Translation("Address"),
* default_widget = "address_default",
* default_formatter = "address_default",
* list_class = "\Drupal\address\Plugin\Field\FieldType\AddressFieldItemList"
* list_class = "\Drupal\address\Plugin\Field\FieldType\AddressFieldItemList",
* column_groups = {
* "langcode" = {
* "label" = @Translation("Langcode"),
* "translatable" = TRUE
* },
* "country_code" = {
* "label" = @Translation("Country code"),
* "translatable" = TRUE
* },
* "administrative_area" = {
* "label" = @Translation("Administrative area"),
* "translatable" = TRUE
* },
* "locality" = {
* "label" = @Translation("Locality"),
* "translatable" = TRUE
* },
* "dependent_locality" = {
* "label" = @Translation("Dependent locality"),
* "translatable" = TRUE
* },
* "postal_code" = {
* "label" = @Translation("Postal code"),
* "translatable" = TRUE
* },
* "sorting_code" = {
* "label" = @Translation("Sorting code"),
* "translatable" = TRUE
* },
* "address_line1" = {
* "label" = @Translation("Address line 1"),
* "translatable" = TRUE
* },
* "address_line2" = {
* "label" = @Translation("Address line 2"),
* "translatable" = TRUE
* },
* "address_line3" = {
* "label" = @Translation("Address line 3"),
* "translatable" = TRUE
* },
* "organization" = {
* "label" = @Translation("Organization"),
* "translatable" = TRUE
* },
* "given_name" = {
* "label" = @Translation("Given name"),
* "translatable" = TRUE
* },
* "additional_name" = {
* "label" = @Translation("Additional name"),
* "translatable" = TRUE
* },
* "family_name" = {
* "label" = @Translation("Family name"),
* "translatable" = TRUE
* },
* },
* )
*/
class AddressItem extends FieldItemBase implements AddressInterface {
......
......@@ -3,9 +3,9 @@
namespace Drupal\address\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
/**
* Plugin implementation of the 'address_country' field type.
......