aws_s3_stream_wrapper-1.0.x-dev/src/Form/EditWrapperConfigurationForm.php

src/Form/EditWrapperConfigurationForm.php
<?php

namespace Drupal\aws_s3_stream_wrapper\Form;

use Drupal\Core\DrupalKernel;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Configure the dynamic S3 wrappers.
 */
class EditWrapperConfigurationForm extends ConfigFormBase {

  /**
   * Prefix when naming config for a particular scheme.
   *
   * @var string
   */
  const CONFIG_KEY_PREFIX = 'aws_s3_stream_wrapper.stream_wrapper';

  /**
   * Drupal kernel service.
   *
   * @var \Drupal\Core\DrupalKernel
   */
  protected $kernel;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\DrupalKernel $kernel
   *   Drupal kernel.
   */
  public function __construct(DrupalKernel $kernel) {
    $this->kernel = $kernel;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('kernel')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'aws_s3_stream_wrapper.edit_wrapper_configuration';
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $scheme = NULL) {
    if ($scheme) {
      $configKey = self::CONFIG_KEY_PREFIX . '.' . $scheme;
      $config = $this->config($configKey);
      if (empty($config->get())) {
        throw new NotFoundHttpException();
      }
    }
    else {
      // Generate an empty config property.
      $config = $this->config(self::CONFIG_KEY_PREFIX);
    }

    $form['scheme'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Scheme'),
      '#required' => TRUE,
      '#default_value' => $config->get('scheme'),
      // Read-only when editing an existing dynamic stream wrapper.
      '#disabled' => $config->get('scheme'),
    ];
    if (empty($config->get('scheme'))) {
      $form['scheme']['#element_validate'] = ['::schemeValidate'];
    }
    $form['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name'),
      '#default_value' => $config->get('name'),
    ];
    $form['description'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Description'),
      '#default_value' => $config->get('description'),
    ];
    $form['bucket_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Bucket'),
      '#default_value' => $config->get('bucket_name'),
      '#element_validate' => ['::bucketNameValidate'],
      // S3 bucket names must be between 3 and 63 characters long.
      '#max_length' => 63,
    ];
    $form['bucket_path_prefix'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Bucket path prefix'),
      '#default_value' => $config->get('bucket_path_prefix'),
    ];
    $form['visible'] = [
      '#type' => 'radios',
      '#title' => $this->t('Visibility'),
      '#options' => [
        1 => $this->t('Visible'),
        0 => $this->t('Hidden'),
      ],
      '#description' => $this->t('Select whether this stream wrapper should appear in the Drupal UI.'),
      '#default_value' => ($config->get('visible')) ?? 0,
    ];

    $form = parent::buildForm($form, $form_state);
    $form['actions']['submit']['#value'] = ($config->get('scheme'))
      ? $this->t('Save configuration')
      : $this->t('Add scheme');

    return $form;
  }

  /**
   * Validate that the name of the bucket meets the S3 requirements.
   *
   * @see https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
   */
  public function bucketNameValidate(array $element, FormStateInterface $form_state) {
    $bucketName = $form_state->getValue($element['#name']);

    // Bucket name is optional – if it's not defined, no validation needed.
    if (empty($bucketName)) {
      return;
    }

    // Rules for this pattern:
    // - Begin and end in a letter or number.
    // - Length between 3 and 63 characters.
    // - Only consist of lowercase letters, numbers, dots (.), and hyphens (-).
    $pattern = '/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/';
    if (!preg_match($pattern, $bucketName)) {
      $rules = [];

      if (strlen($bucketName) < 3 || strlen($bucketName) > 63) {
        $rules[] = $this->t('Bucket names must be between 3 and 63 characters long.');
      }

      if (!preg_match('/^[a-z0-9].*[a-z0-9]$/', $bucketName)) {
        $rules[] = $this->t('Bucket names must begin and end in a letter or number.');
      }

      if (preg_match('/[^a-z0-9.-]/', $bucketName)) {
        $rules[] = $this->t('Bucket names must consist only of lowercase letters, numbers, dots (.), and hyphens (-).');
      }
      $form_state->setError($element, implode("\n", $rules));
    }

    if (filter_var($bucketName, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
      $form_state->setError($element, $this->t('Bucket names must not be formatted as an IP address (for example, 192.168.5.4).'));
    }

    if (strpos($bucketName, 'xn--') === 0) {
      $form_state->setError($element, $this->t('Bucket name must not begin with "xn--".'));
    }

    if (preg_match('/-s3alias$/', $bucketName)) {
      $form_state->setError($element, $this->t('Bucket name must not end with "-s3alias".'));
    }
  }

  /**
   * Validate the scheme is not already defined, or uses a protected value.
   */
  public function schemeValidate(array $element, FormStateInterface $form_state) {
    $value = $form_state->getValue($element['#name']);

    $defined_wrappers = stream_get_wrappers();
    $defined_wrappers += [
      'temporary',
      'public',
      'private',
    ];

    if (in_array($value, $defined_wrappers)) {
      $form_state->setError($element, $this->t('The selected scheme name is already in use.'));
    }

    // Validate the stream wrapper naming rules.
    // @see https://www.php.net/manual/en/function.stream-wrapper-register.php
    // Valid protocol names must contain alphanumerics, dots (.), plusses (+),
    // or hyphens (-) only.
    $pattern = '/^[a-zA-Z0-9.+=]+$/';
    if (!preg_match($pattern, $value)) {
      $form_state->setError($element, $this->t('Valid protocol names must contain alphanumerics, dots (.), plusses (+), or hyphens (-) only.'));
    }
  }

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

    $configKey = self::CONFIG_KEY_PREFIX . '.' . $form_state->getValue('scheme');
    $config = $this->configFactory->getEditable($configKey);

    foreach ($form_state->getValues() as $key => $value) {
      if ($value) {
        $config->set($key, $value);
      }
      else {
        $config->clear($key);
      }
    }
    $config->save();

    // Mark the container for rebuild, to apply the changes in a new compiler
    // pass.
    $this->kernel->invalidateContainer();

    $this->messenger()->addMessage('The stream wrapper configuration has been saved.');
    $form_state->setRedirect('aws_s3_stream_wrapper.admin_overview');
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc