diff --git a/modules/oe_whitelabel_event/config/install/core.entity_view_display.node.oe_event.full.yml b/modules/oe_whitelabel_event/config/install/core.entity_view_display.node.oe_event.full.yml index dee4b7f05..c09a38323 100755 --- a/modules/oe_whitelabel_event/config/install/core.entity_view_display.node.oe_event.full.yml +++ b/modules/oe_whitelabel_event/config/install/core.entity_view_display.node.oe_event.full.yml @@ -61,9 +61,10 @@ content: view_mode: default third_party_settings: { } oe_location: - type: address_default + type: oe_whitelabel_helper_address_inline label: inline - settings: { } + settings: + delimiter: ', ' third_party_settings: { } weight: 5 region: content diff --git a/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml b/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml new file mode 100644 index 000000000..a965f7179 --- /dev/null +++ b/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml @@ -0,0 +1,7 @@ +field.formatter.settings.oe_whitelabel_helper_address_inline: + type: mapping + label: 'Address inline formatter settings' + mapping: + delimiter: + type: string + label: 'Delimiter for address items.' diff --git a/modules/oe_whitelabel_helper/oe_whitelabel_helper.module b/modules/oe_whitelabel_helper/oe_whitelabel_helper.module index 6874592cc..576702473 100644 --- a/modules/oe_whitelabel_helper/oe_whitelabel_helper.module +++ b/modules/oe_whitelabel_helper/oe_whitelabel_helper.module @@ -13,3 +13,18 @@ declare(strict_types = 1); function oe_whitelabel_helper_locale_translation_projects_alter(&$projects) { $projects['oe_whitelabel_helper']['info']['interface translation server pattern'] = drupal_get_path('module', 'oe_whitelabel_helper') . '/translations/%project-%language.po'; } + +/** + * Implements hook_theme(). + */ +function oe_whitelabel_helper_theme($existing, $type, $theme, $path) { + return [ + 'oe_whitelabel_helper_address_inline' => [ + 'variables' => [ + 'address' => NULL, + 'address_items' => [], + 'address_delimiter' => NULL, + ], + ], + ]; +} diff --git a/modules/oe_whitelabel_helper/src/Plugin/Field/FieldFormatter/AddressInlineFormatter.php b/modules/oe_whitelabel_helper/src/Plugin/Field/FieldFormatter/AddressInlineFormatter.php new file mode 100644 index 000000000..a080a0eac --- /dev/null +++ b/modules/oe_whitelabel_helper/src/Plugin/Field/FieldFormatter/AddressInlineFormatter.php @@ -0,0 +1,157 @@ + ', ', + ]; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + + $form['delimiter'] = [ + '#type' => 'textfield', + '#title' => $this->t('Delimiter'), + '#default_value' => $this->getSetting('delimiter'), + '#description' => $this->t('Specify delimiter between address items.'), + '#required' => TRUE, + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + return [ + $this->t('Delimiter: @delimiter', [ + '@delimiter' => $this->getSetting('delimiter'), + ]), + ]; + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items, $langcode) { + $elements = []; + foreach ($items as $delta => $item) { + $elements[$delta] = $this->viewElement($item, $langcode); + } + + return $elements; + } + + /** + * Builds a renderable array for a single address item. + * + * @param \Drupal\address\AddressInterface $address + * The address. + * @param string $langcode + * The language that should be used to render the field. + * + * @return array + * A renderable array. + */ + protected function viewElement(AddressInterface $address, $langcode) { + $country_code = $address->getCountryCode(); + $countries = $this->countryRepository->getList($langcode); + $address_format = $this->addressFormatRepository->get($country_code); + $values = $this->getValues($address, $address_format); + + $address_elements['%country'] = $countries[$country_code]; + foreach ($address_format->getUsedFields() as $field) { + $address_elements['%' . $field] = $values[$field]; + } + + if (Locale::matchCandidates($address_format->getLocale(), $address->getLocale())) { + $format_string = '%country' . "\n" . $address_format->getLocalFormat(); + } + else { + $format_string = $address_format->getFormat() . "\n" . '%country'; + } + /* + * Remove extra characters from address format since address fields are + * optional. + * + * @see \CommerceGuys\Addressing\AddressFormat\AddressFormatRepository::getDefinitions() + */ + $format_string = str_replace([',', ' - ', '/'], "\n", $format_string); + + $items = $this->extractAddressItems($format_string, $address_elements); + + return [ + '#theme' => 'oe_whitelabel_helper_address_inline', + '#address' => $address, + '#address_items' => $items, + '#address_delimiter' => $this->getSetting('delimiter'), + '#cache' => [ + 'contexts' => [ + 'languages:' . LanguageInterface::TYPE_INTERFACE, + ], + ], + ]; + } + + /** + * Extract address items from a format string and replace placeholders. + * + * @param string $string + * The address format string, containing placeholders. + * @param array $replacements + * An array of address items. + * + * @return array + * The exploded lines. + */ + protected function extractAddressItems(string $string, array $replacements): array { + // Make sure the replacements don't have any unneeded newlines. + $replacements = array_map('trim', $replacements); + $string = strtr($string, $replacements); + // Remove noise caused by empty placeholders. + $lines = explode("\n", $string); + foreach ($lines as $index => $line) { + // Remove leading punctuation, excess whitespace. + $line = trim(preg_replace('/^[-,]+/', '', $line, 1)); + $line = preg_replace('/\s\s+/', ' ', $line); + $lines[$index] = $line; + } + // Remove empty lines. + $lines = array_filter($lines); + + return $lines; + } + +} diff --git a/modules/oe_whitelabel_helper/templates/oe-whitelabel-helper-address-inline.html.twig b/modules/oe_whitelabel_helper/templates/oe-whitelabel-helper-address-inline.html.twig new file mode 100644 index 000000000..5359af844 --- /dev/null +++ b/modules/oe_whitelabel_helper/templates/oe-whitelabel-helper-address-inline.html.twig @@ -0,0 +1,16 @@ +{# +/** + * @file + * Default template for the 'oe_whitelabel_helper_address_inline' address formatter. + * + * Available variables: + * - address: Address object. + * - address_items: Address items. + * - address_delimiter: Delimiter between address items. + * + * @ingroup themeable + */ +#} + + {{ address_items|join(address_delimiter) }} + diff --git a/modules/oe_whitelabel_helper/tests/src/Kernel/Plugin/Field/FieldFormatter/AddressInlineFormatterTest.php b/modules/oe_whitelabel_helper/tests/src/Kernel/Plugin/Field/FieldFormatter/AddressInlineFormatterTest.php new file mode 100644 index 000000000..ff3038e09 --- /dev/null +++ b/modules/oe_whitelabel_helper/tests/src/Kernel/Plugin/Field/FieldFormatter/AddressInlineFormatterTest.php @@ -0,0 +1,121 @@ +createField('address', 'oe_whitelabel_helper_address_inline'); + } + + /** + * Tests formatting of address. + */ + public function testInlineFormatterAddress(): void { + $entity = EntityTest::create([]); + foreach ($this->addressFieldTestData() as $data) { + $cloned_entity = clone $entity; + $cloned_entity->{$this->fieldName} = $data['address']; + $this->renderEntityFields($cloned_entity, $this->display); + $this->assertRaw($data['expected']); + unset($cloned_entity); + } + } + + /** + * Test data for testInlineFormatterAddress. + * + * @return array[] + * An array of test data arrays with expected result. + */ + public function addressFieldTestData(): array { + return [ + 'Brussels Belgium' => [ + 'address' => [ + 'country_code' => 'BE', + 'locality' => 'Brussels ', + 'postal_code' => '1000', + 'address_line1' => 'Rue de la Loi, 56 <123>', + 'address_line2' => 'or \'Wetstraat\' (Dutch), meaning "Law Street"', + ], + 'expected' => 'Rue de la Loi, 56 <123>, or 'Wetstraat' (Dutch), meaning "Law Street", 1000 Brussels <Bruxelles>, Belgium', + ], + 'Mexico' => [ + 'address' => [ + 'country_code' => 'MX', + ], + 'expected' => 'Mexico', + ], + 'Mexico Ciudad de Mexico' => [ + 'address' => [ + 'country_code' => 'MX', + 'administrative_area' => 'CDMX', + ], + 'expected' => 'CDMX, Mexico', + ], + 'Mexico Baja California Tijuana' => [ + 'address' => [ + 'country_code' => 'MX', + 'administrative_area' => 'B.C.', + 'locality' => 'Tijuana', + ], + 'expected' => 'Tijuana, B.C., Mexico', + ], + 'Mexico Baja California Tijuana 22000' => [ + 'address' => [ + 'country_code' => 'MX', + 'administrative_area' => 'B.C.', + 'locality' => 'Tijuana', + 'postal_code' => '22000', + ], + 'expected' => '22000 Tijuana, B.C., Mexico', + ], + 'Mexico Baja California Tijuana 22000 Street' => [ + 'address' => [ + 'country_code' => 'MX', + 'administrative_area' => 'B.C.', + 'locality' => 'Tijuana', + 'postal_code' => '22000', + 'address_line1' => 'Street', + ], + 'expected' => 'Street, 22000 Tijuana, B.C., Mexico', + ], + 'Bangladesh Dhaka' => [ + 'address' => [ + 'country_code' => 'BD', + 'locality' => 'Dhaka', + ], + 'expected' => 'Dhaka, Bangladesh', + ], + 'Bangladesh Dhaka 1100' => [ + 'address' => [ + 'country_code' => 'BD', + 'locality' => 'Dhaka', + 'postal_code' => '1100', + ], + 'expected' => 'Dhaka, 1100, Bangladesh', + ], + ]; + } + +}