You are here

yamlform_test.module in YAML Form 8

Support module for form related testing.

File

tests/modules/yamlform_test/yamlform_test.module
View source
<?php

/**
 * @file
 * Support module for form related testing.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Serialization\Yaml;

/**
 * Implements hook_theme().
 */
function yamlform_test_theme() {
  return [
    'yamlform_handler_test_summary' => [
      'variables' => [
        'settings' => NULL,
        'handler' => [],
      ],
    ],
  ];
}

/******************************************************************************/

// Alter options.

/******************************************************************************/

/**
 * Implements hook_yamlform_options_YAMLFORM_OPTIONS_ID_alter().
 */
function yamlform_test_yamlform_options_test_alter(array &$options, array &$element) {
  $options = [
    'one' => t('One'),
    'two' => t('Two'),
    'three' => t('Three'),
  ];
}

/******************************************************************************/

// Alter forms.

/******************************************************************************/

/**
 * Implements hook_yamlform_form_FORM_ID_alter().
 */
function yamlform_test_form_yamlform_submission_test_form_wizard_custom_form_alter(array &$form, FormStateInterface $form_state) {
  $form['#validate'][] = '_yamlform_test_form_yamlform_submission_test_form_wizard_custom_form_validate';
}

/**
 * Validate handler for 'test_form_wizard_custom'.
 */
function _yamlform_test_form_yamlform_submission_test_form_wizard_custom_form_validate(array &$form, FormStateInterface $form_state) {
  if ($form_state
    ->hasAnyErrors()) {
    return;
  }

  // Ge submitted values.
  $values = $form_state
    ->getValues();

  // Alter pages based on selected 'pages'.
  $pages = $form_state
    ->get('pages');
  foreach ($pages as $page_key => &$page) {
    if (isset($form['elements'][$page_key])) {
      $page['#access'] = in_array($page_key, $values['pages']);
    }
  }
  $form_state
    ->set('pages', $pages);
}

/**
 * Implements hook_yamlform_form_FORM_ID_alter().
 */
function yamlform_test_form_yamlform_submission_test_form_validate_form_alter(array &$form, FormStateInterface $form_state) {
  $form['elements']['custom']['#description'] = t('Field is <b>required</b> using custom validation handler.');
  $form['#validate'][] = 'yamlform_test_form_yamlform_submission_test_form_validate_form_validate';
}

/**
 * Implements hook_form_validate().
 */
function yamlform_test_form_yamlform_submission_test_form_validate_form_validate($form, FormStateInterface $form_state) {
  if (!$form_state
    ->getValue('custom')) {
    $form_state
      ->setErrorByName('custom', t('Custom element is required.'));
  }
}

/******************************************************************************/

// Generate elements.

/******************************************************************************/

/**
 * Implements hook_yamlform_load().
 */
function yamlform_test_yamlform_load(array $entities) {

  // If ?generate is passed to the current pages URL the test form's elements
  // will get rebuilt.
  if (!isset($_GET['generate'])) {
    return;
  }
  $include_base_path = drupal_get_path('module', 'yamlform_test') . '/includes';
  foreach ($entities as $id => $entity) {
    if (preg_match('/^(test_form_(?:wizard_)?long)_\\d+$/', $id, $match)) {
      $name = $match[1];
    }
    else {
      $name = $id;
    }
    if (file_exists("{$include_base_path}/yamlform_test.{$name}.inc")) {
      module_load_include('inc', 'yamlform_test', 'includes/yamlform_test.' . $name);
      $function = 'yamlform_test_' . $name;
      $elements = $function($entity);
      $entity
        ->setElements($elements);

      // Issue: Unable to execute YamlForm::save().
      // $entity->save();
      // Workaround: Write the elements directory to yamlform config.
      \Drupal::configFactory()
        ->getEditable('yamlform.yamlform.' . $id)
        ->set('elements', Yaml::encode($elements))
        ->save();

      // Display message.
      drupal_set_message(t('Generated elements for %title form', [
        '%title' => $entity
          ->label(),
      ]));
    }
  }
}

/**
 * Get issues related to elements #states API.
 *
 * @return array
 *   Associative array containing issues related to elements #states API.
 */
function _yamlform_test_issues() {
  return [
    'submit' => [
      '1671190' => 'Use <button /> form element type instead of <input type="submit" />',
    ],
    'datetime' => [
      '2419131' => '#states attribute does not work on #type datetime',
    ],
    'details' => [
      '2348851' => 'Regression: Allow HTML tags inside detail summary',
    ],
    'entity_autocomplete' => [
      '2826451' => 'TermSelection returning HTML characters in select list',
    ],
    'item' => [
      '783438' => '#states doesn\'t work for #type item',
    ],
    'managed_file' => [
      '2705471' => 'Form states managed file fields',
      '2113931' => 'File Field design update',
    ],
    'password_confirm' => [
      '1427838' => 'password and password_confirm children do not pick up #states or #attributes',
    ],
    'select' => [
      '1426646' => '"-Select-" option is lost when form elements uses \'#states\'',
      '1149078' => 'States API doesn\'t work with multiple select fields',
      '2791741' => 'FAPI states: fields aren\'t hidden initially when depending on multi-value selection',
    ],
    'radios' => [
      '2731991' => 'Setting required on radios marks all options required',
      '994360' => '#states cannot disable/enable radios and checkboxes',
      '2836364' => 'Wrapper attributes are not supported by composite elements, this includes radios, checkboxes, and buttons.',
    ],
    'checkboxes' => [
      '994360' => '#states cannot disable/enable radios and checkboxes',
      '2836364' => 'Wrapper attributes are not supported by composite elements, this includes radios, checkboxes, and buttons.',
    ],
    'text_format' => [
      '997826' => '#states doesn\'t work correctly with type text_format',
      '2625128' => 'Text format selection stays visible when using editor and a hidden form state',
      '1954968' => 'Required CKEditor fields always fail HTML5 validation',
    ],
    'yamlform_markup' => [
      '2700667' => 'Notice: Undefined index: #type in drupal_process_states()',
    ],
    'yamlform_message' => [
      '77245' => 'A place for JavaScript status messages',
    ],
    'yamlform_time' => [
      '1838234' => 'Add jQuery Timepicker for the Time element of the datetime field',
    ],
  ];
}

/**
 * Generate an example of a specified element type.
 *
 * @param string $type
 *   An element type.
 *
 * @return array|bool
 *   An example element or FALSE if the element type can't have an example.
 */
function _yamlform_test_get_example_element($type) {
  static $skipped_elements;
  static $default_elements;

  // Elements to be ignored.
  if (!isset($skipped_elements)) {
    $skipped_elements = [
      'hidden',
      'table',
      'yamlform_element',
      'yamlform_flexbox',
      'yamlform_test',
      'yamlform_wizard_page',
    ];

    // Some tests don't install the filter.module so we should skip elements
    // that is depend on the filter.module.
    if (!\Drupal::moduleHandler()
      ->moduleExists('filter')) {
      $skipped_elements[] = 'processed_text';
      $skipped_elements[] = 'text_format';
    }
  }

  // Default element properties.
  if (!isset($default_elements)) {
    $yaml = file_get_contents(drupal_get_path('module', 'yamlform_test') . '/includes/yamlform_test.example_elements.yml');
    $default_elements = Yaml::decode($yaml);
  }
  if (isset($skipped_elements[$type])) {
    return FALSE;
  }

  /** @var \Drupal\yamlform\YamlFormElementManagerInterface $element_manager */
  $element_manager = \Drupal::service('plugin.manager.yamlform.element');
  $yamlform_element = $element_manager
    ->createInstance($type);
  $element = [
    '#type' => (string) $yamlform_element
      ->getTypeName(),
    '#title' => (string) $yamlform_element
      ->getPluginLabel(),
  ];

  // Add known issues to #description.
  $issues = _yamlform_test_issues();
  if (isset($issues[$type])) {
    $items = [];
    foreach ($issues[$type] as $issue_number => $issue_title) {
      $items[$issue_number] = "<a href=\"https://www.drupal.org/node/{$issue_number}\">Issue #{$issue_number}: {$issue_title}</a>";
    }
    $element['#description'] = '<b>' . t('Known Issues:') . '</b><br/>' . implode('<br/>', $items);
  }

  // Set default element properties.
  if (isset($default_elements[$type])) {
    $element += $default_elements[$type];
  }

  // Set default options.
  if ($yamlform_element
    ->hasProperty('options')) {
    $element['#options'] = [
      'One' => 'One',
      'Two' => 'Two',
      'Three' => 'Three',
    ];
  }

  // Set default container content.
  if ($yamlform_element
    ->isContainer($element)) {
    if (!in_array($type, [
      'captcha',
    ])) {
      $element[$type . '_content'] = [
        '#markup' => 'This is a ' . $yamlform_element
          ->getPluginLabel() . ' container.',
      ];
    }
  }

  // Add known issues to #description.
  if (isset($issues[$type])) {
    $items = [];
    foreach ($issues[$type] as $issue_number => $issue_title) {
      $items[$issue_number] = "<a href=\"https://www.drupal.org/node/{$issue_number}\">Issue #{$issue_number}: {$issue_title}</a>";
    }
    $element['#description'] = '<b>' . t('Known Issues:') . '</b><br/>' . implode('<br/>', $items);
  }

  // Set default element properties.
  if (isset($default_elements[$type])) {
    $element += $default_elements[$type];
  }

  // Set default options.
  if ($yamlform_element
    ->hasProperty('options')) {
    $element['#options'] = [
      'One' => 'One',
      'Two' => 'Two',
      'Three' => 'Three',
    ];
  }

  // Set default container content.
  if ($yamlform_element
    ->isContainer($element)) {
    if (!in_array($type, [
      'captcha',
    ])) {
      $element[$type . '_content'] = [
        '#markup' => 'This is a ' . $yamlform_element
          ->getPluginLabel() . ' container.',
      ];
    }
  }
  return $element;
}

Functions

Namesort descending Description
yamlform_test_form_yamlform_submission_test_form_validate_form_alter Implements hook_yamlform_form_FORM_ID_alter().
yamlform_test_form_yamlform_submission_test_form_validate_form_validate Implements hook_form_validate().
yamlform_test_form_yamlform_submission_test_form_wizard_custom_form_alter Implements hook_yamlform_form_FORM_ID_alter().
yamlform_test_theme Implements hook_theme().
yamlform_test_yamlform_load Implements hook_yamlform_load().
yamlform_test_yamlform_options_test_alter Implements hook_yamlform_options_YAMLFORM_OPTIONS_ID_alter().
_yamlform_test_form_yamlform_submission_test_form_wizard_custom_form_validate Validate handler for 'test_form_wizard_custom'.
_yamlform_test_get_example_element Generate an example of a specified element type.
_yamlform_test_issues Get issues related to elements #states API.