
| Current Path : /var/www/html/c12park/web/modules/contrib/webform/src/Plugin/WebformElement/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/html/c12park/web/modules/contrib/webform/src/Plugin/WebformElement/Address.php |
<?php
namespace Drupal\webform\Plugin\WebformElement;
use CommerceGuys\Addressing\AddressFormat\FieldOverride;
use Drupal\address\FieldHelper;
use Drupal\address\LabelHelper;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Mail\MailFormatHelper;
use Drupal\webform\Utility\WebformElementHelper;
use Drupal\webform\WebformInterface;
use Drupal\webform\WebformSubmissionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a 'address' element.
*
* @WebformElement(
* id = "address",
* label = @Translation("Advanced address"),
* description = @Translation("Provides advanced element for storing, validating and displaying international postal addresses."),
* category = @Translation("Composite elements"),
* composite = TRUE,
* multiline = TRUE,
* states_wrapper = TRUE,
* dependencies = {
* "address",
* }
* )
*
* @see \Drupal\address\Element\Address
*/
class Address extends WebformCompositeBase {
/**
* The language manager service.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* The address format repository service.
*
* @var \CommerceGuys\Addressing\AddressFormat\AddressFormatRepositoryInterfacey
*/
protected $addressFormatRepository;
/**
* The address county repository service.
*
* @var \CommerceGuys\Addressing\Country\CountryRepositoryInterface
*/
protected $addressCountryRepository;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->languageManager = $container->get('language_manager');
$instance->renderer = $container->get('renderer');
$instance->addressFormatRepository = $container->get('address.address_format_repository');
$instance->addressCountryRepository = $container->get('address.country_repository');
return $instance;
}
/**
* {@inheritdoc}
*/
protected function defineDefaultProperties() {
$properties = [
// Element settings.
'title' => '',
'default_value' => [],
// Description/Help.
'help' => '',
'help_title' => '',
'description' => '',
'more' => '',
'more_title' => '',
// Form display.
'title_display' => 'invisible',
'description_display' => '',
'help_display' => '',
// Form validation.
'required' => FALSE,
// Submission display.
'format' => $this->getItemDefaultFormat(),
'format_html' => '',
'format_text' => '',
'format_items' => $this->getItemsDefaultFormat(),
'format_items_html' => '',
'format_items_text' => '',
// Address settings.
'available_countries' => [],
'field_overrides' => [],
'langcode_override' => '',
] + $this->defineDefaultBaseProperties()
+ $this->defineDefaultMultipleProperties();
unset($properties['multiple__header']);
return $properties;
}
/* ************************************************************************ */
/**
* {@inheritdoc}
*/
public function prepare(array &$element, ?WebformSubmissionInterface $webform_submission = NULL) {
parent::prepare($element, $webform_submission);
$element['#theme_wrappers'] = [];
// #title display defaults to invisible.
$element += [
'#title_display' => 'invisible',
];
}
/**
* {@inheritdoc}
*/
protected function prepareElementValidateCallbacks(array &$element, ?WebformSubmissionInterface $webform_submission = NULL) {
parent::prepareElementValidateCallbacks($element, $webform_submission);
$element['#element_validate'][] = [get_class($this), 'validateAddress'];
}
/**
* {@inheritdoc}
*/
protected function prepareElementPreRenderCallbacks(array &$element, ?WebformSubmissionInterface $webform_submission = NULL) {
parent::prepareElementPreRenderCallbacks($element, $webform_submission);
// Replace 'form_element' theme wrapper with composite form element.
// @see \Drupal\Core\Render\Element\PasswordConfirm
$element['#pre_render'] = [[get_called_class(), 'preRenderWebformCompositeFormElement']];
}
/**
* {@inheritdoc}
*/
public function getCompositeElements() {
return [];
}
/**
* {@inheritdoc}
*
* @see \Drupal\address\Plugin\Field\FieldType\AddressItem::schema
*/
public function initializeCompositeElements(array &$element) {
$element['#webform_composite_elements'] = [
'given_name' => [
'#title' => $this->t('Given name'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'family_name' => [
'#title' => $this->t('Family name'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'additional_name' => [
'#title' => $this->t('Additional name'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'organization' => [
'#title' => $this->t('Organization'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'address_line1' => [
'#title' => $this->t('Address line 1'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'address_line2' => [
'#title' => $this->t('Address line 2'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'postal_code' => [
'#title' => $this->t('Postal code'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'locality' => [
'#title' => $this->t('Locality'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'dependent_locality' => [
'#title' => $this->t('Dependent_locality'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'administrative_area' => [
'#title' => $this->t('Administrative area'),
'#type' => 'textfield',
'#maxlength' => 255,
],
'country_code' => [
'#title' => $this->t('Country code'),
'#type' => 'textfield',
'#maxlength' => 2,
],
'langcode' => [
'#title' => $this->t('Language code'),
'#type' => 'textfield',
'#maxlength' => 32,
],
'sorting_code' => [
'#title' => $this->t('Sorting code'),
'#type' => 'textfield',
'#maxlength' => 255,
],
];
}
/**
* {@inheritdoc}
*/
protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
$format = $this->getItemFormat($element);
if ($format === 'value') {
return $this->buildAddress($element, $webform_submission, $options);
}
else {
return parent::formatHtmlItem($element, $webform_submission, $options);
}
}
/**
* {@inheritdoc}
*/
protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
$format = $this->getItemFormat($element);
if ($format === 'value') {
$build = $this->buildAddress($element, $webform_submission, $options);
$html = $this->renderer->renderPlain($build);
return trim(MailFormatHelper::htmlToText($html));
}
else {
return parent::formatTextItem($element, $webform_submission, $options);
}
}
/**
* Build formatted address.
*
* The below code is copied form the protected
* AddressDefaultFormatter::viewElements method.
*
* @param array $element
* An element.
* @param \Drupal\webform\WebformSubmissionInterface $webform_submission
* A webform submission.
* @param array $options
* An array of options.
*
* @return array
* A render array containing the formatted address.
*
* @see \Drupal\address\Plugin\Field\FieldFormatter\AddressDefaultFormatter::viewElements
* @see \Drupal\address\Plugin\Field\FieldFormatter\AddressDefaultFormatter::viewElement
*/
protected function buildAddress(array $element, WebformSubmissionInterface $webform_submission, array $options) {
$value = $this->getValue($element, $webform_submission, $options);
// Skip if value or country code is empty.
if (empty($value) || empty($value['country_code'])) {
return [];
}
// @see \Drupal\address\Plugin\Field\FieldFormatter\AddressDefaultFormatter::viewElements
$build = [
'#prefix' => '<div class="address" translate="no">',
'#suffix' => '</div>',
'#post_render' => [
['\Drupal\address\Plugin\Field\FieldFormatter\AddressDefaultFormatter', 'postRender'],
],
'#cache' => [
'contexts' => [
'languages:' . LanguageInterface::TYPE_INTERFACE,
],
],
];
// @see \Drupal\address\Plugin\Field\FieldFormatter\AddressDefaultFormatter::viewElement
$country_code = $value['country_code'];
$countries = $this->addressCountryRepository->getList();
$address_format = $this->addressFormatRepository->get($country_code);
$build += [
'#address_format' => $address_format,
'#locale' => 'und',
];
$build['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);
$build[$property] = [
'#type' => 'html_tag',
'#tag' => 'span',
'#attributes' => ['class' => [$class]],
'#value' => (!empty($value[$property])) ? Html::escape($value[$property]) : '',
'#placeholder' => '%' . $field,
];
}
return $build;
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
// Get field overrider from element properties.
$element_properties = $form_state->get('element_properties');
$field_overrides = $element_properties['field_overrides'];
unset($element_properties['field_overrides']);
$form_state->set('element_properties', $element_properties);
$form['address'] = [
'#type' => 'fieldset',
'#title' => $this->t('Address settings'),
];
/* ********************************************************************** */
// Copied from: AddressItem::fieldSettingsForm.
// @see \Drupal\address\Plugin\Field\FieldType\AddressItem::fieldSettingsForm
/* ********************************************************************** */
$languages = $this->languageManager->getLanguages(LanguageInterface::STATE_ALL);
$language_options = [];
foreach ($languages as $langcode => $language) {
if (!$language->isLocked()) {
$language_options[$langcode] = $language->getName();
}
}
$form['address']['available_countries'] = [
'#type' => 'select',
'#title' => $this->t('Available countries'),
'#description' => $this->t('If no countries are selected, all countries will be available.'),
'#options' => $this->addressCountryRepository->getList(),
'#multiple' => TRUE,
'#size' => 10,
'#select2' => TRUE,
];
WebformElementHelper::process($form['address']['available_countries']);
$form['address']['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,
'#empty_option' => $this->t('- No override -'),
'#access' => $this->languageManager->isMultilingual(),
];
$form['address']['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 fields to always be hidden, optional, or required.'),
'#access' => TRUE,
];
$form['address']['field_overrides'] = [
'#type' => 'table',
'#header' => [
$this->t('Field'),
$this->t('Override'),
],
'#access' => TRUE,
];
foreach (LabelHelper::getGenericFieldLabels() as $field_name => $label) {
$override = $field_overrides[$field_name] ?? '';
$form['address']['field_overrides'][$field_name] = [
'#access' => TRUE,
'field_label' => [
'#access' => TRUE,
'#type' => 'markup',
'#markup' => $label,
],
'override' => [
'#access' => TRUE,
'#type' => 'select',
'#default_value' => $override,
'#options' => [
FieldOverride::HIDDEN => $this->t('Hidden'),
FieldOverride::OPTIONAL => $this->t('Optional'),
FieldOverride::REQUIRED => $this->t('Required'),
],
'#empty_option' => $this->t('- No override -'),
'#parents' => ['properties', 'field_overrides', $field_name],
],
];
}
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$values['field_overrides'] = array_filter($values['field_overrides']);
$form_state->setValues($values);
parent::validateConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function getTestValues(array $element, WebformInterface $webform, array $options = []) {
return [
[
'given_name' => 'John',
'family_name' => 'Smith',
'organization' => 'Google Inc.',
'address_line1' => '1098 Alta Ave',
'postal_code' => '94043',
'locality' => 'Mountain View',
'administrative_area' => 'CA',
'country_code' => 'US',
'langcode' => 'en',
],
];
}
/**
* Form API callback. Make sure address element value includes a country code.
*/
public static function validateAddress(array &$element, FormStateInterface $form_state, array &$completed_form) {
$value = $element['#value'];
if (empty($element['#multiple'])) {
if (empty($value['country_code'])) {
$form_state->setValueForElement($element, NULL);
}
}
else {
foreach ($value as $index => $item) {
if (empty($item['country_code'])) {
unset($value[$index]);
}
}
$value = array_values($value);
$form_state->setValueForElement($element, $value ?: NULL);
}
}
}