Version 1
[yaffs-website] / web / core / modules / filter / src / FilterFormatFormBase.php
diff --git a/web/core/modules/filter/src/FilterFormatFormBase.php b/web/core/modules/filter/src/FilterFormatFormBase.php
new file mode 100644 (file)
index 0000000..cbcb632
--- /dev/null
@@ -0,0 +1,237 @@
+<?php
+
+namespace Drupal\filter;
+
+use Drupal\Core\Entity\EntityForm;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\filter\Plugin\Filter\FilterNull;
+
+/**
+ * Provides a base form for a filter format.
+ */
+abstract class FilterFormatFormBase extends EntityForm {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $format = $this->entity;
+    $is_fallback = ($format->id() == $this->config('filter.settings')->get('fallback_format'));
+
+    $form['#tree'] = TRUE;
+    $form['#attached']['library'][] = 'filter/drupal.filter.admin';
+
+    $form['name'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Name'),
+      '#default_value' => $format->label(),
+      '#required' => TRUE,
+      '#weight' => -30,
+    ];
+    $form['format'] = [
+      '#type' => 'machine_name',
+      '#required' => TRUE,
+      '#default_value' => $format->id(),
+      '#maxlength' => 255,
+      '#machine_name' => [
+        'exists' => [$this, 'exists'],
+        'source' => ['name'],
+      ],
+      '#disabled' => !$format->isNew(),
+      '#weight' => -20,
+    ];
+
+    // Add user role access selection.
+    $form['roles'] = [
+      '#type' => 'checkboxes',
+      '#title' => $this->t('Roles'),
+      '#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()),
+      '#disabled' => $is_fallback,
+      '#weight' => -10,
+    ];
+    if ($is_fallback) {
+      $form['roles']['#description'] = $this->t('All roles for this text format must be enabled and cannot be changed.');
+    }
+    if (!$format->isNew()) {
+      // If editing an existing text format, pre-select its current permissions.
+      $form['roles']['#default_value'] = array_keys(filter_get_roles_by_format($format));
+    }
+
+    // Create filter plugin instances for all available filters, including both
+    // enabled/configured ones as well as new and not yet unconfigured ones.
+    $filters = $format->filters();
+    foreach ($filters as $filter_id => $filter) {
+      // When a filter is missing, it is replaced by the null filter. Remove it
+      // here, so that saving the form will remove the missing filter.
+      if ($filter instanceof FilterNull) {
+        drupal_set_message($this->t('The %filter filter is missing, and will be removed once this format is saved.', ['%filter' => $filter_id]), 'warning');
+        $filters->removeInstanceID($filter_id);
+      }
+    }
+
+    // Filter status.
+    $form['filters']['status'] = [
+      '#type' => 'item',
+      '#title' => $this->t('Enabled filters'),
+      '#prefix' => '<div id="filters-status-wrapper">',
+      '#suffix' => '</div>',
+      // This item is used as a pure wrapping container with heading. Ignore its
+      // value, since 'filters' should only contain filter definitions.
+      // See https://www.drupal.org/node/1829202.
+      '#input' => FALSE,
+    ];
+    // Filter order (tabledrag).
+    $form['filters']['order'] = [
+      '#type' => 'table',
+      // For filter.admin.js
+      '#attributes' => ['id' => 'filter-order'],
+      '#title' => $this->t('Filter processing order'),
+      '#tabledrag' => [
+        [
+         'action' => 'order',
+         'relationship' => 'sibling',
+         'group' => 'filter-order-weight',
+        ],
+      ],
+      '#tree' => FALSE,
+      '#input' => FALSE,
+      '#theme_wrappers' => ['form_element'],
+    ];
+    // Filter settings.
+    $form['filter_settings'] = [
+      '#type' => 'vertical_tabs',
+      '#title' => $this->t('Filter settings'),
+    ];
+
+    foreach ($filters as $name => $filter) {
+      $form['filters']['status'][$name] = [
+        '#type' => 'checkbox',
+        '#title' => $filter->getLabel(),
+        '#default_value' => $filter->status,
+        '#parents' => ['filters', $name, 'status'],
+        '#description' => $filter->getDescription(),
+        '#weight' => $filter->weight,
+      ];
+
+      $form['filters']['order'][$name]['#attributes']['class'][] = 'draggable';
+      $form['filters']['order'][$name]['#weight'] = $filter->weight;
+      $form['filters']['order'][$name]['filter'] = [
+        '#markup' => $filter->getLabel(),
+      ];
+      $form['filters']['order'][$name]['weight'] = [
+        '#type' => 'weight',
+        '#title' => $this->t('Weight for @title', ['@title' => $filter->getLabel()]),
+        '#title_display' => 'invisible',
+        '#delta' => 50,
+        '#default_value' => $filter->weight,
+        '#parents' => ['filters', $name, 'weight'],
+        '#attributes' => ['class' => ['filter-order-weight']],
+      ];
+
+      // Retrieve the settings form of the filter plugin. The plugin should not be
+      // aware of the text format. Therefore, it only receives a set of minimal
+      // base properties to allow advanced implementations to work.
+      $settings_form = [
+        '#parents' => ['filters', $name, 'settings'],
+        '#tree' => TRUE,
+      ];
+      $settings_form = $filter->settingsForm($settings_form, $form_state);
+      if (!empty($settings_form)) {
+        $form['filters']['settings'][$name] = [
+          '#type' => 'details',
+          '#title' => $filter->getLabel(),
+          '#open' => TRUE,
+          '#weight' => $filter->weight,
+          '#parents' => ['filters', $name, 'settings'],
+          '#group' => 'filter_settings',
+        ];
+        $form['filters']['settings'][$name] += $settings_form;
+      }
+    }
+    return parent::form($form, $form_state);
+  }
+
+  /**
+   * Determines if the format already exists.
+   *
+   * @param string $format_id
+   *   The format ID
+   *
+   * @return bool
+   *   TRUE if the format exists, FALSE otherwise.
+   */
+  public function exists($format_id) {
+    return (bool) $this->entityTypeManager
+      ->getStorage('filter_format')
+      ->getQuery()
+      ->condition('format', $format_id)
+      ->execute();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    parent::validateForm($form, $form_state);
+
+    // @todo Move trimming upstream.
+    $format_format = trim($form_state->getValue('format'));
+    $format_name = trim($form_state->getValue('name'));
+
+    // Ensure that the values to be saved later are exactly the ones validated.
+    $form_state->setValueForElement($form['format'], $format_format);
+    $form_state->setValueForElement($form['name'], $format_name);
+
+    $format_exists = $this->entityTypeManager
+      ->getStorage('filter_format')
+      ->getQuery()
+      ->condition('format', $format_format, '<>')
+      ->condition('name', $format_name)
+      ->execute();
+    if ($format_exists) {
+      $form_state->setErrorByName('name', $this->t('Text format names must be unique. A format named %name already exists.', ['%name' => $format_name]));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    parent::submitForm($form, $form_state);
+
+    // Add the submitted form values to the text format, and save it.
+    $format = $this->entity;
+    foreach ($form_state->getValues() as $key => $value) {
+      if ($key != 'filters') {
+        $format->set($key, $value);
+      }
+      else {
+        foreach ($value as $instance_id => $config) {
+          $format->setFilterConfig($instance_id, $config);
+        }
+      }
+    }
+    $format->save();
+
+    // Save user permissions.
+    if ($permission = $format->getPermissionName()) {
+      foreach ($form_state->getValue('roles') as $rid => $enabled) {
+        user_role_change_permissions($rid, [$permission => $enabled]);
+      }
+    }
+
+    $form_state->setRedirect('filter.admin_overview');
+
+    return $this->entity;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function actions(array $form, FormStateInterface $form_state) {
+    $actions = parent::actions($form, $form_state);
+    $actions['submit']['#value'] = $this->t('Save configuration');
+    return $actions;
+  }
+
+}