Commit 5a6a1317 authored by bojanz's avatar bojanz
Browse files

Hide the default values form, implement the 'initial values' functionality...

Hide the default values form, implement the 'initial values' functionality (same as in addressfield 7.x-1.x)
parent 7a136150
......@@ -6,6 +6,7 @@
*/
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_ENTITY_TYPE_insert() for 'address_format'.
......@@ -15,3 +16,16 @@ function address_configurable_language_insert(ConfigurableLanguage $language) {
$importer = \Drupal::service('address.address_format_importer');
$importer->importTranslations([$language->getId()]);
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*
* Removes the default values form from the field settings page.
* Users expect to use the default value form to predefine only certain values
* on the widget, but Drupal expects the default value to be complete, and used
* whenever an actual address isn't provided. Therefore it's preferable to
* hide this functionality and implement our own via custom widget settings.
*/
function address_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state) {
$form['default_value']['#access'] = FALSE;
}
......@@ -56,3 +56,6 @@ field.widget.settings.address_default:
label: 'Available countries'
sequence:
- type: string
default_country:
type: string
label: 'Default country'
......@@ -21,4 +21,13 @@ final class AddressEvents {
*/
const WIDGET_SETTINGS = 'address.widget.settings';
/**
* Name of the event fired when altering initial values.
*
* @Event
*
* @see \Drupal\address\Event\InitialValuesEvent
*/
const INITIAL_VALUES = 'address.widget.initial_values';
}
<?php
/**
* @file
* Contains \Drupal\address\Event\InitialValuesEvent.
*/
namespace Drupal\address\Event;
use Drupal\Core\Field\FieldDefinitionInterface;
use Symfony\Component\EventDispatcher\Event;
/**
* Defines the initial values event.
*
* @see \Drupal\address\Event\AddressEvents
* @see \Drupal\address\Plugin\Field\FieldWidget\AddressDefaultWidget::getInitialValues()
*/
class InitialValuesEvent extends Event {
/**
* The initial values.
*
* @var array
*/
protected $initialValues;
/**
* The field definition.
*
* @var \Drupal\Core\Field\FieldDefinitionInterface
*/
protected $fieldDefinition;
/**
* Constructs a new InitialValuesEvent object.
*
* @param array $initialValues
* The initial values.
* @param \Drupal\Core\Field\FieldDefinitionInterface $fieldDefinition
* The field definition.
*/
public function __construct(array $initialValues, FieldDefinitionInterface $fieldDefinition) {
$this->initialValues = $initialValues;
$this->fieldDefinition = $fieldDefinition;
}
/**
* Gets the initial values.
*
* @return array
* The initial values.
*/
public function getInitialValues() {
return $this->initialValues;
}
/**
* Sets the initial values.
*
* @return $this
*/
public function setInitialValues(array $initialValues) {
$this->initialValues = $initialValues;
return $this;
}
/**
* Gets the field definition.
*
* @return \Drupal\Core\Field\FieldDefinitionInterface
* The field definition.
*/
public function getFieldDefinition() {
return $this->fieldDefinition;
}
}
......@@ -12,11 +12,13 @@ use CommerceGuys\Addressing\Repository\AddressFormatRepositoryInterface;
use CommerceGuys\Addressing\Repository\CountryRepositoryInterface;
use CommerceGuys\Addressing\Repository\SubdivisionRepositoryInterface;
use Drupal\address\Event\AddressEvents;
use Drupal\address\Event\InitialValuesEvent;
use Drupal\address\Event\WidgetSettingsEvent;
use Drupal\address\FieldHelper;
use Drupal\address\LabelHelper;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
......@@ -67,6 +69,13 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
*/
protected $eventDispatcher;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The altered settings.
*
......@@ -108,14 +117,17 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
* The subdivision repository.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
* The event dispatcher.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
*/
public function __construct($pluginId, $pluginDefinition, FieldDefinitionInterface $fieldDefinition, array $settings, array $thirdPartySettings, AddressFormatRepositoryInterface $addressFormatRepository, CountryRepositoryInterface $countryRepository, SubdivisionRepositoryInterface $subdivisionRepository, EventDispatcherInterface $eventDispatcher) {
public function __construct($pluginId, $pluginDefinition, FieldDefinitionInterface $fieldDefinition, array $settings, array $thirdPartySettings, AddressFormatRepositoryInterface $addressFormatRepository, CountryRepositoryInterface $countryRepository, SubdivisionRepositoryInterface $subdivisionRepository, EventDispatcherInterface $eventDispatcher, ConfigFactoryInterface $configFactory) {
parent::__construct($pluginId, $pluginDefinition, $fieldDefinition, $settings, $thirdPartySettings);
$this->addressFormatRepository = $addressFormatRepository;
$this->countryRepository = $countryRepository;
$this->subdivisionRepository = $subdivisionRepository;
$this->eventDispatcher = $eventDispatcher;
$this->configFactory = $configFactory;
}
/**
......@@ -132,7 +144,8 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
$container->get('address.address_format_repository'),
$container->get('address.country_repository'),
$container->get('address.subdivision_repository'),
$container->get('event_dispatcher')
$container->get('event_dispatcher'),
$container->get('config.factory')
);
}
......@@ -142,6 +155,7 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
public static function defaultSettings() {
return [
'available_countries' => [],
'default_country' => NULL,
] + parent::defaultSettings();
}
......@@ -149,16 +163,25 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$countryList = $this->countryRepository->getList();
$element = [];
$element['available_countries'] = [
'#type' => 'select',
'#title' => $this->t('Available countries'),
'#description' => $this->t('If no countries are selected, all countries will be available.'),
'#options' => $this->countryRepository->getList(),
'#options' => $countryList,
'#default_value' => $this->getSetting('available_countries'),
'#multiple' => TRUE,
'#size' => 10,
];
$element['default_country'] = array(
'#type' => 'select',
'#title' => $this->t('Default country'),
'#options' => ['site_default' => $this->t('- Site default -')] + $countryList,
'#default_value' => $this->getSetting('default_country'),
'#empty_value' => '',
);
return $element;
}
......@@ -194,6 +217,70 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
return isset($this->alteredSettings[$key]) ? $this->alteredSettings[$key] : NULL;
}
/**
* Gets the initial values for the widget.
*
* This is a replacement for the disabled default values functionality.
*
* @see address_form_field_config_edit_form_alter()
*
* @return array
* The initial values, keyed by property.
*/
protected function getInitialValues() {
$availableCountries = $this->getAvailableCountries();
$defaultCountry = $this->getAlteredSetting('default_country');
// Resolve the special site_default option.
if ($defaultCountry == 'site_default') {
$defaultCountry = $this->configFactory->get('system.date')->get('country.default');
}
// Fallback to the first country in the list if the default country is not
// available, or is empty even though the field is required.
$notAvailable = $defaultCountry && !isset($availableCountries[$defaultCountry]);
$emptyButRequired = empty($defaultCountry) && $this->fieldDefinition->isRequired();
if ($notAvailable || $emptyButRequired) {
$defaultCountry = key($availableCountries);
}
$initialValues = [
'country_code' => $defaultCountry,
'administrative_area' => '',
'locality' => '',
'dependent_locality' => '',
'postal_code' => '',
'sorting_code' => '',
'address_line1' => '',
'address_line2' => '',
'organization' => '',
'recipient' => '',
];
// Allow other modules to alter the values.
$event = new InitialValuesEvent($initialValues, $this->fieldDefinition);
$this->eventDispatcher->dispatch(AddressEvents::INITIAL_VALUES, $event);
$initialValues = $event->getInitialValues();
return $initialValues;
}
/**
* Gets the available countries.
*
* @return array
* The available countries (countryCode => name).
*/
protected function getAvailableCountries() {
$countryList = $this->countryRepository->getList();
$availableCountries = array_filter($this->getAlteredSetting('available_countries'));
if (empty($availableCountries)) {
$availableCountries = $countryList;
}
else {
$availableCountries = array_intersect_key($countryList, $availableCountries);
}
return $availableCountries;
}
/**
* {@inheritdoc}
*/
......@@ -207,16 +294,8 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
$parents = array_merge($element['#field_parents'], [$fieldName, $delta]);
$values = NestedArray::getValue($formState->getUserInput(), $parents, $hasInput);
if (!$hasInput) {
$values = $items[$delta]->toArray();
}
// Prepare the filtered country list.
$countryList = $this->countryRepository->getList();
$availableCountries = array_filter($this->getAlteredSetting('available_countries'));
if (empty($availableCountries)) {
$countries = $countryList;
}
else {
$countries = array_intersect_key($countryList, $availableCountries);
$item = $items[$delta];
$values = $item->isEmpty() ? $this->getInitialValues() : $item->toArray();
}
$element += [
......@@ -239,7 +318,7 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
$element['country_code'] = [
'#type' => 'select',
'#title' => $this->t('Country'),
'#options' => $countries,
'#options' => $this->getAvailableCountries(),
'#default_value' => $values['country_code'],
'#empty_value' => '',
'#limit_validation_errors' => [],
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment