diff --git a/config/schema/address.schema.yml b/config/schema/address.schema.yml index abc39d3..1e2c5b8 100644 --- a/config/schema/address.schema.yml +++ b/config/schema/address.schema.yml @@ -157,6 +157,17 @@ field.widget.settings.address_zone_default: type: boolean label: 'Show the zone label field' +field.formatter.settings.address_default: + type: mapping + label: 'Default address formatter settings' + mapping: + skip_domestic_country: + type: boolean + label: 'Skip country for domestic addresses' + domestic_country: + type: string + label: 'Domestic addresses country' + views.field.country_code: type: views_field label: 'Country code' diff --git a/src/Plugin/Field/FieldFormatter/AddressDefaultFormatter.php b/src/Plugin/Field/FieldFormatter/AddressDefaultFormatter.php index 936f251..afd1920 100644 --- a/src/Plugin/Field/FieldFormatter/AddressDefaultFormatter.php +++ b/src/Plugin/Field/FieldFormatter/AddressDefaultFormatter.php @@ -11,9 +11,11 @@ use CommerceGuys\Addressing\Subdivision\SubdivisionRepositoryInterface; use Drupal\address\AddressInterface; use Drupal\address\FieldHelper; use Drupal\Component\Utility\Html; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Field\FormatterBase; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Render\Element; @@ -32,6 +34,11 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryPluginInterface { + /** + * Site default country + */ + const SITE_DEFAULT = 'site_default'; + /** * The address format repository. * @@ -53,6 +60,13 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP */ protected $subdivisionRepository; + /** + * The configuration factory. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + /** * Constructs an AddressDefaultFormatter object. * @@ -76,13 +90,23 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP * The country repository. * @param \CommerceGuys\Addressing\Subdivision\SubdivisionRepositoryInterface $subdivision_repository * The subdivision repository. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AddressFormatRepositoryInterface $address_format_repository, CountryRepositoryInterface $country_repository, SubdivisionRepositoryInterface $subdivision_repository) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AddressFormatRepositoryInterface $address_format_repository, CountryRepositoryInterface $country_repository, SubdivisionRepositoryInterface $subdivision_repository, ConfigFactoryInterface $config_factory = NULL) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); $this->addressFormatRepository = $address_format_repository; $this->countryRepository = $country_repository; $this->subdivisionRepository = $subdivision_repository; + + if (!$config_factory instanceof ConfigFactoryInterface) { + @trigger_error('AddressDefaultFormatter now takes an additional argument ConfigFactoryInterface $config_factory. Use without $config_factory is deprecated. Classes extending this formatter will fail starting with address 9.x-1.x.', E_USER_DEPRECATED); + $this->configFactory = \Drupal::configFactory(); + } + else { + $this->configFactory = $config_factory; + } } /** @@ -100,10 +124,81 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP $configuration['third_party_settings'], $container->get('address.address_format_repository'), $container->get('address.country_repository'), - $container->get('address.subdivision_repository') + $container->get('address.subdivision_repository'), + $container->get('config.factory') ); } + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + return [ + 'skip_domestic_country' => FALSE, + 'domestic_country' => self::SITE_DEFAULT, + ] + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $country_list = $this->countryRepository->getList(); + $site_default = $this->t('- Site default (@country) -', [ + '@country' => $country_list[$this->configFactory->get('system.date')->get('country.default')] + ]); + + $element = []; + $element['skip_domestic_country'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Skip country for domestic addresses'), + '#default_value' => $this->getSetting('skip_domestic_country'), + ]; + + $states_prefix = 'fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings]'; + $element['domestic_country'] = [ + '#type' => 'select', + '#title' => $this->t('Domestic addresses country'), + '#options' => [self::SITE_DEFAULT => $site_default] + $country_list, + '#default_value' => $this->getSetting('domestic_country'), + '#empty_value' => NULL, + '#description' => $this->t("Addresses within this country are considered domestic."), + '#states' => [ + 'visible' => [ + ':input[name="' . $states_prefix . '[skip_domestic_country]"]' => ['checked' => TRUE], + ], + ], + ]; + + return $element; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + + if (!empty($this->getSetting('skip_domestic_country'))) { + $domestic_country = $this->getSetting('domestic_country'); + $country_list = $this->countryRepository->getList(); + if ($domestic_country === self::SITE_DEFAULT) { + $domestic_country = $this->t('Site default (@country)', [ + '@country' => $country_list[$this->configFactory->get('system.date')->get('country.default')] + ]); + } + else { + $domestic_country = $country_list[$domestic_country]; + } + $summary['domestic_country'] = $this->t('Skip country for addresses in: @country', ['@country' => $domestic_country]); + } + else { + $summary['domestic_country'] = $this->t('Always display country.'); + } + + return $summary; + } + /** * {@inheritdoc} */ @@ -141,7 +236,6 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP */ protected function viewElement(AddressInterface $address, $langcode) { $country_code = $address->getCountryCode(); - $countries = $this->countryRepository->getList(); $address_format = $this->addressFormatRepository->get($country_code); $values = $this->getValues($address, $address_format); @@ -149,13 +243,22 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP '#address_format' => $address_format, '#locale' => $address->getLocale(), ]; - $element['country'] = [ - '#type' => 'html_tag', - '#tag' => 'span', - '#attributes' => ['class' => ['country']], - '#value' => Html::escape($countries[$country_code]), - '#placeholder' => '%country', - ]; + if ($this->getSetting('skip_domestic_country')) { + $domestic_country = $this->getSetting('domestic_country'); + if ($domestic_country == self::SITE_DEFAULT) { + $domestic_country = $this->configFactory->get('system.date')->get('country.default'); + } + } + if (!isset($domestic_country) || $country_code != $domestic_country) { + $countries = $this->countryRepository->getList(); + $element['country'] = [ + '#type' => 'html_tag', + '#tag' => 'span', + '#attributes' => ['class' => ['country']], + '#value' => Html::escape($countries[$country_code]), + '#placeholder' => '%country', + ]; + } foreach ($address_format->getUsedFields() as $field) { $property = FieldHelper::getPropertyName($field); $class = str_replace('_', '-', $property); @@ -188,13 +291,17 @@ class AddressDefaultFormatter extends FormatterBase implements ContainerFactoryP /** @var \CommerceGuys\Addressing\AddressFormat\AddressFormat $address_format */ $address_format = $element['#address_format']; $locale = $element['#locale']; - // Add the country to the bottom or the top of the format string, - // depending on whether the format is minor-to-major or major-to-minor. - if (Locale::matchCandidates($address_format->getLocale(), $locale)) { - $format_string = '%country' . "\n" . $address_format->getLocalFormat(); - } - else { - $format_string = $address_format->getFormat() . "\n" . '%country'; + + $format_string = $address_format->getFormat(); + if (!empty($element['country'])) { + // Add the country to the bottom or the top of the format string, + // depending on whether the format is minor-to-major or major-to-minor. + if (Locale::matchCandidates($address_format->getLocale(), $locale)) { + $format_string = '%country' . "\n" . $address_format->getLocalFormat(); + } + else { + $format_string = $address_format->getFormat() . "\n" . '%country'; + } } $replacements = [];