You are here

public static function WebformOptionsCustom::setTemplateOptions in Webform 6.x

Same name and namespace in other branches
  1. 8.5 modules/webform_options_custom/src/Element/WebformOptionsCustom.php \Drupal\webform_options_custom\Element\WebformOptionsCustom::setTemplateOptions()

Set a custom options element #options property.

Parameters

array $element: A custom options element.

Overrides WebformOptionsCustomInterface::setTemplateOptions

3 calls to WebformOptionsCustom::setTemplateOptions()
WebformOptionsCustom::getTemplateOptions in modules/webform_options_custom/src/Entity/WebformOptionsCustom.php
Get template custom options.
WebformOptionsCustom::processWebformOptionsCustom in modules/webform_options_custom/src/Element/WebformOptionsCustom.php
Processes an 'other' element.
WebformOptionsCustomEntity::setTemplateOptions in modules/webform_options_custom/src/Element/WebformOptionsCustomEntity.php
Set a custom options element #options property.
1 method overrides WebformOptionsCustom::setTemplateOptions()
WebformOptionsCustomEntity::setTemplateOptions in modules/webform_options_custom/src/Element/WebformOptionsCustomEntity.php
Set a custom options element #options property.

File

modules/webform_options_custom/src/Element/WebformOptionsCustom.php, line 268

Class

WebformOptionsCustom
Provides an element for a selecting custom options from HTML or SVG markup.

Namespace

Drupal\webform_options_custom\Element

Code

public static function setTemplateOptions(array &$element) {
  if (isset($element['#_options_custom'])) {
    return;
  }
  $element['#_options_custom'] = TRUE;

  // Set options. Used by entity references.
  static::setOptions($element);

  // Load custom options from config entity.
  if (!empty($element['#options_custom'])) {
    $webform_option_custom = WebformOptionsCustomEntity::load($element['#options_custom']);
    if ($webform_option_custom) {
      $custom_element = $webform_option_custom
        ->getElement();
      $element += $custom_element;
      $element['#options'] += $custom_element['#options'];
    }
  }

  // Set default properties.
  $element += [
    '#options' => [],
    '#value_attributes' => 'data-option-value,data-value,data-id,id',
    '#text_attributes' => 'data-option-text,data-text,data-name,name,title',
  ];

  // Get options.
  $options =& $element['#options'];

  // Build options by text look up.
  $options_by_text = [];
  foreach ($options as $option_value => $option_text) {
    $option_description = '';
    if (WebformOptionsHelper::hasOptionDescription($option_text)) {
      list($option_text, $option_description) = WebformOptionsHelper::splitOption($option_text);
    }
    $options_by_text[$option_text] = [
      'value' => $option_value,
      'text' => $option_text,
      'description' => $option_description,
    ];
  }

  // Get option value and text attributes.
  $value_attribute_name = NULL;
  if ($element['#value_attributes']) {
    $value_attributes = preg_split('/\\s*,\\s*/', trim($element['#value_attributes']));
    foreach ($value_attributes as $value_attribute) {
      if (strpos($element['#template'], $value_attribute) !== FALSE) {
        $value_attribute_name = $value_attribute;
        break;
      }
    }
  }
  $text_attribute_name = NULL;
  if ($element['#text_attributes']) {
    $text_attributes = preg_split('/\\s*,\\s*/', trim($element['#text_attributes']));
    foreach ($text_attributes as $text_attribute) {
      if (strpos($element['#template'], $text_attribute) !== FALSE) {
        $text_attribute_name = $text_attribute;
        break;
      }
    }
  }
  $custom_attributes = [];
  if ($value_attribute_name) {
    $custom_attributes[] = $value_attribute_name;
  }
  if ($text_attribute_name) {
    $custom_attributes[] = $text_attribute_name;
  }
  if (empty($custom_attributes)) {
    return;
  }

  // Combine text and value attributes into an Xpath query that finds all
  // DOM element which contain any of the attributes.
  $css_attributes = array_map(function ($value) {
    return 'descendant-or-self::*[@' . $value . ']';
  }, $custom_attributes);
  $xpath_expression = implode(' | ', $css_attributes);

  // Remove XML tag from SVG file.
  $xml_tag = NULL;
  $template = $element['#template'];
  if (preg_match('/<\\?xml[^>]+\\?>\\s+/', $element['#template'], $match)) {
    $xml_tag = $match[0];
    $template = str_replace($xml_tag, '', $template);
  }
  $dom = Html::load($template);
  $xpath = new \DOMXPath($dom);
  foreach ($xpath
    ->query($xpath_expression) as $dom_node) {
    if (in_array($dom_node->tagName, [
      'svg',
    ])) {
      continue;
    }
    $dom_attributes = [];
    foreach ($dom_node->attributes as $attribute_name => $attribute_node) {

      /** @var \DOMNode $attribute_node */
      $dom_attributes[$attribute_name] = $attribute_node->nodeValue;
    }
    $dom_attributes += [
      $value_attribute_name => '',
      $text_attribute_name => '',
    ];

    // Get value and text attribute.
    $option_value = $dom_attributes[$value_attribute_name];
    $option_text = $dom_attributes[$text_attribute_name];

    // Set missing options value based on options text.
    if ($option_value === '' && $option_text !== '') {

      // Look up options value using the option's text.
      if (isset($options_by_text[$option_text])) {
        $option_value = $options_by_text[$option_text]['value'];
      }
      else {
        $option_value = $option_text;
      }
    }

    // Append value and text to the options array.
    $options += [
      $option_value => $option_text ?: $option_value,
    ];

    // Always set the data-option-value attribute.
    // Note: The select menu's option text is the canonical source for
    // the option text.
    $dom_node
      ->setAttribute('data-option-value', $option_value);
  }

  // Set template with tweaked or additional attributes.
  $element['#template'] = $xml_tag . Html::serialize($dom);
}