You are here

WebformUiElementTestForm.php in Webform 8.5

Same filename and directory in other branches
  1. 6.x modules/webform_ui/src/Form/WebformUiElementTestForm.php

File

modules/webform_ui/src/Form/WebformUiElementTestForm.php
View source
<?php

namespace Drupal\webform_ui\Form;

use Drupal\Core\Serialization\Yaml;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\webform\Entity\Webform;
use Drupal\webform\Entity\WebformSubmission;
use Drupal\webform\WebformInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Provides a test webform for webform elements.
 *
 * This webform is only visible if the webform_devel.module is enabled.
 *
 * @see \Drupal\webform\Controller\WebformPluginElementController::index
 */
class WebformUiElementTestForm extends WebformUiElementFormBase {

  /**
   * {@inheritdoc}
   */
  protected $operation = 'test';

  /**
   * Type of webform element being tested.
   *
   * @var string
   */
  protected $type;

  /**
   * A webform element.
   *
   * @var \Drupal\webform\Plugin\WebformElementInterface
   */
  protected $webformElement;

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'webform_ui_element_test_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL, $key = NULL, $parent_key = NULL, $type = NULL) {

    // Create a temp webform.
    $this->webform = Webform::create([
      'id' => '_webform_ui_temp_form',
    ]);
    $this->type = $type;
    if (!$this->elementManager
      ->hasDefinition($type)) {
      throw new NotFoundHttpException();
    }
    if ($element = \Drupal::request()
      ->getSession()
      ->get('webform_ui_test_element_' . $type)) {
      $this->element = $element;
    }
    else {
      $element = [
        '#type' => $type,
      ] + $this
        ->getWebformElementPlugin()
        ->preview();
      $this->element = $element;
    }
    $webform_element = $this
      ->getWebformElementPlugin();
    $form['#title'] = $this
      ->t('Test %type element', [
      '%type' => $type,
    ]);
    if ($element) {
      $webform_submission = WebformSubmission::create([
        'webform' => $this->webform,
      ]);
      $webform_element
        ->initialize($this->element);
      $webform_element
        ->prepare($this->element, $webform_submission);
      $form['test'] = [
        '#type' => 'details',
        '#title' => $this
          ->t('Element test'),
        '#open' => TRUE,
        '#attributes' => [
          'style' => 'background-color: #f5f5f2',
        ],
        'element' => $this->element,
        'hr' => [
          '#markup' => '<hr />',
        ],
      ];
      if (isset($element['#default_value'])) {
        $html = $webform_element
          ->formatHtml($element + [
          '#value' => $element['#default_value'],
        ], $webform_submission);
        $form['test']['html'] = [
          '#type' => 'item',
          '#title' => $this
            ->t('HTML'),
          '#markup' => is_array($html) ? $this->renderer
            ->render($html) : $html,
          '#allowed_tag' => Xss::getAdminTagList(),
        ];
        $form['test']['text'] = [
          '#type' => 'item',
          '#title' => $this
            ->t('Plain text'),
          '#markup' => '<pre>' . $webform_element
            ->formatText($element + [
            '#value' => $element['#default_value'],
          ], $webform_submission) . '</pre>',
          '#allowed_tag' => Xss::getAdminTagList(),
        ];
      }
      $form['test']['code'] = [
        '#type' => 'item',
        '#title' => $this
          ->t('Source'),
        'source' => [
          '#theme' => 'webform_codemirror',
          '#type' => 'yaml',
          '#code' => Yaml::encode($this
            ->convertTranslatableMarkupToStringRecursive($element)),
        ],
      ];
      $form['test']['render_array'] = [
        '#type' => 'details',
        '#title' => $this
          ->t('Render array'),
        '#desciption' => $this
          ->t("Below is the element's final render array."),
        'source' => [
          '#theme' => 'webform_codemirror',
          '#type' => 'yaml',
          '#code' => Yaml::encode($this
            ->convertTranslatableMarkupToStringRecursive($this->element)),
        ],
      ];
    }
    $form['key'] = [
      '#type' => 'value',
      '#value' => 'element',
    ];
    $form['parent_key'] = [
      '#type' => 'value',
      '#value' => '',
    ];
    $form['properties'] = $webform_element
      ->buildConfigurationForm([
      '#tabs' => FALSE,
    ], $form_state);
    $form['properties']['#tree'] = TRUE;
    $form['properties']['custom']['#open'] = TRUE;
    $form['properties']['element']['type'] = [
      '#type' => 'item',
      '#title' => $this
        ->t('Type'),
      '#markup' => $type,
      '#weight' => -100,
      '#parents' => [
        'type',
      ],
    ];
    $form['actions'] = [
      '#type' => 'actions',
    ];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Test'),
      '#button_type' => 'primary',
    ];
    if (\Drupal::request()
      ->getSession()
      ->get('webform_ui_test_element_' . $type)) {
      $form['actions']['reset'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Reset'),
        '#limit_validation_errors' => [],
        '#submit' => [
          '::reset',
        ],
      ];
    }

    // Clear all messages including 'Unable to display this webform…' which is
    // generated because we are using a temp webform.
    // drupal_get_messages();
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function reset(array &$form, FormStateInterface $form_state) {
    \Drupal::request()
      ->getSession()
      ->remove('webform_ui_test_element_' . $this->type);
    $this
      ->messenger()
      ->addStatus($this
      ->t('Webform element %type test has been reset.', [
      '%type' => $this->type,
    ]));
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    // Rebuild is throwing the below error.
    // LogicException: Settings can not be serialized.
    // $form_state->setRebuild();
    // @todo Determine what object is being serialized with webform
    //
    // The webform element configuration is stored in the 'properties' key in
    // the webform, pass that through for submission.
    $element_form_state = clone $form_state;
    $element_form_state
      ->setValues($form_state
      ->getValue('properties'));
    $properties = $this
      ->getWebformElementPlugin()
      ->getConfigurationFormProperties($form, $element_form_state);

    // Set #default_value using 'test' element value.
    if ($element_value = $form_state
      ->getValue('element')) {
      $properties['#default_value'] = $element_value;
    }
    \Drupal::request()
      ->getSession()
      ->set('webform_ui_test_element_' . $this->type, $properties);
    $this
      ->messenger()
      ->addStatus($this
      ->t('Webform element %type test has been updated.', [
      '%type' => $this->type,
    ]));
  }

  /**
   * Determines if the webform element key already exists.
   *
   * @param string $key
   *   The webform element key.
   *
   * @return bool
   *   TRUE if the webform element key, FALSE otherwise.
   */
  public function exists($key) {
    return FALSE;
  }

  /**
   * Convert all translatable markup to strings.
   *
   * This allows element to be serialized.
   *
   * @param array $element
   *   An element.
   *
   * @return array
   *   The element with all translatable markup converted to strings.
   */
  protected function convertTranslatableMarkupToStringRecursive(array $element) {
    foreach ($element as $key => $value) {
      if ($value instanceof TranslatableMarkup) {
        $element[$key] = (string) $value;
      }
      elseif (is_array($value)) {
        $element[$key] = $this
          ->convertTranslatableMarkupToStringRecursive($value);
      }
    }
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function getWebformElementPlugin() {
    if (empty($this->element)) {
      return $this->elementManager
        ->getElementInstance([
        '#type' => $this->type,
      ]);
    }
    else {
      return parent::getWebformElementPlugin();
    }
  }

}

Classes

Namesort descending Description
WebformUiElementTestForm Provides a test webform for webform elements.