You are here

WebformOptions.php in Webform 8.5

Same filename in this branch
  1. 8.5 src/Element/WebformOptions.php
  2. 8.5 src/Entity/WebformOptions.php
Same filename and directory in other branches
  1. 6.x src/Entity/WebformOptions.php

File

src/Entity/WebformOptions.php
View source
<?php

namespace Drupal\webform\Entity;

use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\webform\Utility\WebformOptionsHelper;
use Drupal\webform\Utility\WebformYaml;
use Drupal\webform\WebformOptionsInterface;

/**
 * Defines the webform options entity.
 *
 * @ConfigEntityType(
 *   id = "webform_options",
 *   label = @Translation("Webform options"),
 *   label_collection = @Translation("Webform options"),
 *   label_singular = @Translation("webform options"),
 *   label_plural = @Translation("webform options"),
 *   label_count = @PluralTranslation(
 *     singular = "@count webform options",
 *     plural = "@count webform options",
 *   ),
 *   handlers = {
 *     "storage" = "\Drupal\webform\WebformOptionsStorage",
 *     "access" = "Drupal\webform\WebformOptionsAccessControlHandler",
 *     "list_builder" = "Drupal\webform\WebformOptionsListBuilder",
 *     "form" = {
 *       "add" = "Drupal\webform\WebformOptionsForm",
 *       "edit" = "Drupal\webform\WebformOptionsForm",
 *       "duplicate" = "Drupal\webform\WebformOptionsForm",
 *       "delete" = "Drupal\webform\WebformOptionsDeleteForm",
 *     }
 *   },
 *   admin_permission = "administer webform",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label",
 *   },
 *   links = {
 *     "add-form" = "/admin/structure/webform/config/options/manage/add",
 *     "edit-form" = "/admin/structure/webform/config/options/manage/{webform_options}/edit",
 *     "duplicate-form" = "/admin/structure/webform/config/options/manage/{webform_options}/duplicate",
 *     "delete-form" = "/admin/structure/webform/config/options/manage/{webform_options}/delete",
 *     "collection" = "/admin/structure/webform/config/options/manage",
 *   },
 *   config_export = {
 *     "id",
 *     "uuid",
 *     "label",
 *     "category",
 *     "likert",
 *     "options",
 *   }
 * )
 */
class WebformOptions extends ConfigEntityBase implements WebformOptionsInterface {
  use StringTranslationTrait;

  /**
   * The webform options ID.
   *
   * @var string
   */
  protected $id;

  /**
   * The webform options UUID.
   *
   * @var string
   */
  protected $uuid;

  /**
   * The webform options label.
   *
   * @var string
   */
  protected $label;

  /**
   * The webform options category.
   *
   * @var string
   */
  protected $category;

  /**
   * Flag to used options as likert answers.
   *
   * @var bool
   */
  protected $likert = FALSE;

  /**
   * The webform options options.
   *
   * @var string
   */
  protected $options;

  /**
   * The webform options decoded.
   *
   * @var string
   */
  protected $optionsDecoded;

  /**
   * {@inheritdoc}
   */
  public function isLikert() {
    return $this->likert;
  }

  /**
   * {@inheritdoc}
   */
  public function set($property_name, $value) {

    // Make sure to reset decoded options when options are updated.
    if ($property_name === 'options') {
      $this->optionsDecoded = NULL;
    }
    return parent::set($property_name, $value);
  }

  /**
   * {@inheritdoc}
   */
  public function getOptions() {
    if (!isset($this->optionsDecoded)) {
      try {
        $options = WebformYaml::decode($this->options);

        // Since YAML supports simple values.
        $options = is_array($options) ? $options : [];
      } catch (\Exception $exception) {
        $link = $this
          ->toLink($this
          ->t('Edit'), 'edit-form')
          ->toString();
        \Drupal::logger('webform')
          ->notice('%title options are not valid. @message', [
          '%title' => $this
            ->label(),
          '@message' => $exception
            ->getMessage(),
          'link' => $link,
        ]);
        $options = FALSE;
      }
      $this->optionsDecoded = $options;
    }
    return $this->optionsDecoded;
  }

  /**
   * {@inheritdoc}
   */
  public function setOptions(array $options) {
    $this->options = WebformYaml::encode($options);
    $this->optionsDecoded = NULL;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function hasAlterHooks() {
    $hook_name = 'webform_options_' . $this
      ->id() . '_alter';
    $alter_hooks = \Drupal::moduleHandler()
      ->getImplementations($hook_name);
    return count($alter_hooks) ? TRUE : FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage) {
    parent::preSave($storage);

    // If the submitted options match the altered options clear the submission
    // options.
    $altered_options = [];
    $temp_element = [];
    \Drupal::moduleHandler()
      ->alter('webform_options_' . $this
      ->id(), $altered_options, $temp_element);
    $altered_options = WebformOptionsHelper::convertOptionsToString($altered_options);
    if ($altered_options === $this
      ->getOptions()) {
      $this->options = '';
    }
  }

  /**
   * {@inheritdoc}
   */
  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
    parent::postSave($storage, $update);

    // Clear cached properties.
    $this->optionsDecoded = NULL;
  }

  /**
   * {@inheritdoc}
   */
  public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) {
    $a_label = $a
      ->get('category') . $a
      ->label();
    $b_label = $b
      ->get('category') . $b
      ->label();
    return strnatcasecmp($a_label, $b_label);
  }

  /**
   * {@inheritdoc}
   */
  public static function getElementOptions(array &$element, $property_name = '#options') {

    // If element already has #options array just call alter hook with
    // a NULL id.
    if (is_array($element[$property_name])) {
      $options = $element[$property_name];
      \Drupal::moduleHandler()
        ->alter('webform_options', $options, $element);
      return $options;
    }

    // Return empty options if element does not define an options id.
    if (empty($element[$property_name]) || !is_string($element[$property_name])) {
      return [];
    }

    // If options have been set return them.
    // This allows dynamic options to be overridden.
    $id = $element[$property_name];
    if ($webform_options = WebformOptions::load($id)) {
      $options = $webform_options
        ->getOptions() ?: [];
    }
    else {
      $options = [];
    }

    // Alter options using hook_webform_options_alter()
    // and/or hook_webform_options_WEBFORM_OPTIONS_ID_alter() hook.
    // @see webform.api.php
    \Drupal::moduleHandler()
      ->alter('webform_options_' . $id, $options, $element);
    \Drupal::moduleHandler()
      ->alter('webform_options', $options, $element, $id);

    // Log empty options.
    if (empty($options)) {
      \Drupal::logger('webform')
        ->notice('Options %id do not exist.', [
        '%id' => $id,
      ]);
    }
    return $options;
  }

}

Classes

Namesort descending Description
WebformOptions Defines the webform options entity.