You are here

class ConfigForm in Flysystem 3.0.x

Same name and namespace in other branches
  1. 8 src/Form/ConfigForm.php \Drupal\flysystem\Form\ConfigForm
  2. 3.x src/Form/ConfigForm.php \Drupal\flysystem\Form\ConfigForm
  3. 2.0.x src/Form/ConfigForm.php \Drupal\flysystem\Form\ConfigForm

Configure file system settings for this site.

Hierarchy

Expanded class hierarchy of ConfigForm

1 file declares its use of ConfigForm
ConfigFormTest.php in tests/src/Unit/Form/ConfigFormTest.php
1 string reference to 'ConfigForm'
flysystem.routing.yml in ./flysystem.routing.yml
flysystem.routing.yml

File

src/Form/ConfigForm.php, line 15

Namespace

Drupal\flysystem\Form
View source
class ConfigForm extends FormBase {

  /**
   * The Flysystem factory.
   *
   * @var \Drupal\flysystem\FlysystemFactory
   */
  protected $factory;

  /**
   * Constructs a ConfigForm object.
   *
   * @param \Drupal\flysystem\FlysystemFactory $factory
   *   The FlysystemF factory.
   */
  public function __construct(FlysystemFactory $factory) {
    $this->factory = $factory;
  }

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

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $schemes = $this->factory
      ->getSchemes();
    $form['sync_from'] = [
      '#type' => 'select',
      '#options' => array_combine($schemes, $schemes),
      '#title' => $this
        ->t('Sync from'),
      '#required' => TRUE,
    ];
    $form['sync_to'] = [
      '#type' => 'select',
      '#options' => array_combine($schemes, $schemes),
      '#title' => $this
        ->t('Sync to'),
      '#required' => TRUE,
    ];
    $form['force'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Force'),
      '#description' => $this
        ->t('Normally, existing files will be ignored. Selecting this option will overwrite any existing files.'),
    ];
    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Sync'),
      '#button_type' => 'primary',
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    if ($form_state
      ->getValue('sync_from') === $form_state
      ->getValue('sync_to')) {
      $form_state
        ->setError($form['sync_from'], $this
        ->t('"Sync from" and "Sync to" cannot be the same scheme.'));
      $form_state
        ->setError($form['sync_to']);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $scheme_from = $form_state
      ->getValue('sync_from');
    $scheme_to = $form_state
      ->getValue('sync_to');
    $from_files = $this
      ->getFileList($scheme_from);
    $to_files = [];
    if (!$form_state
      ->getValue('force')) {
      $to_files = $this
        ->getFileList($scheme_to);
    }
    $batch = [
      'operations' => [],
      'finished' => get_class($this) . '::finishBatch',
      'title' => $this
        ->t('Synchronizing file systems'),
      'init_message' => $this
        ->t('Starting file system synchronization.'),
      'progress_message' => $this
        ->t('Completed @current step of @total.'),
      'error_message' => $this
        ->t('File system synchronization has encountered an error.'),
    ];

    // @todo We shouldn't do all files in one go, but rather add files and
    // directories and recurse in a batch callback.
    foreach (array_diff($from_files, $to_files) as $filepath) {
      $batch['operations'][] = [
        get_class($this) . '::copyFile',
        [
          $scheme_from,
          $scheme_to,
          $filepath,
        ],
      ];
    }
    batch_set($batch);
  }

  /**
   * Copies a single file.
   *
   * @param string $scheme_from
   *   The scheme to sync from.
   * @param string $scheme_to
   *   The scheme to sync to.
   * @param string $filepath
   *   The file to sync.
   * @param array &$context
   *   The batch context.
   */
  public static function copyFile($scheme_from, $scheme_to, $filepath, array &$context) {
    $context['message'] = \Drupal::translation()
      ->translate('Copying: %file', [
      '%file' => $filepath,
    ]);
    $context['finished'] = 1;
    $factory = \Drupal::service('flysystem_factory');

    // Copying files could take a very long time. Using streams will keep memory
    // usage down, but we could still timeout.
    Environment::setTimeLimit(0);
    try {
      $read_handle = $factory
        ->getFilesystem($scheme_from)
        ->readStream($filepath);
      if (!is_resource($read_handle)) {
        $args = [
          '%scheme' => $scheme_from,
          '%file' => $filepath,
        ];
        $context['results']['errors'][] = [
          'The file %scheme://%file could not be opened.',
          $args,
        ];
        return;
      }
      $success = $factory
        ->getFilesystem($scheme_to)
        ->putStream($filepath, $read_handle);
      if (!$success) {
        $args = [
          '%scheme' => $scheme_to,
          '%file' => $filepath,
        ];
        $context['results']['errors'][] = [
          'The file %scheme://%file could not be saved.',
          $args,
        ];
      }
    } catch (\Exception $e) {
      $context['results']['errors'][] = [
        'An eror occured while copying %file.',
        [
          '%file' => $filepath,
        ],
      ];
      $context['results']['errors'][] = $e
        ->getMessage();
      watchdog_exception('flysystem', $e);
    }
    if (isset($read_handle) && is_resource($read_handle)) {
      fclose($read_handle);
    }
  }

  /**
   * Finish batch.
   */
  public static function finishBatch($success, array $results, array $operations) {
    $messenger = \Drupal::messenger();
    if (!$success) {

      // An error occurred.
      // $operations contains the operations that remained unprocessed.
      $args = [
        '%file' => reset($operations)[2],
      ];
      $messenger
        ->addError(\Drupal::translation()
        ->translate('An error occurred while syncing: %file', $args));
      return;
    }
    if (empty($results['errors'])) {
      $messenger
        ->addStatus(\Drupal::translation()
        ->translate('File synchronization finished successfully.'));
      return;
    }
    foreach ($results['errors'] as $error) {
      if (is_array($error)) {
        $messenger
          ->addError(\Drupal::translation()
          ->translate($error[0], $error[1]), TRUE);
        \Drupal::logger('flysystem')
          ->error($error[0], $error[1]);
      }
      else {
        $messenger
          ->addError(Html::escape($error), TRUE);
      }
    }
    $messenger
      ->addWarning(\Drupal::translation()
      ->translate('File synchronization experienced errors.'));
  }

  /**
   * Returns the file list for a scheme.
   *
   * @param string $scheme
   *   The scheme.
   *
   * @return string[]
   *   A list of files.
   */
  protected function getFileList($scheme) {
    $filesystem = $this->factory
      ->getFilesystem($scheme);
    $files = array_filter($filesystem
      ->listContents('', TRUE), function ($meta) {
      return $meta['type'] === 'file';
    });
    return array_map(function (array $meta) {
      return $meta['path'];
    }, $files);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ConfigForm::$factory protected property The Flysystem factory.
ConfigForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
ConfigForm::copyFile public static function Copies a single file.
ConfigForm::create public static function Instantiates a new instance of this class. Overrides FormBase::create
ConfigForm::finishBatch public static function Finish batch.
ConfigForm::getFileList protected function Returns the file list for a scheme.
ConfigForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
ConfigForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
ConfigForm::validateForm public function Form validation handler. Overrides FormBase::validateForm
ConfigForm::__construct public function Constructs a ConfigForm object.
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 3
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 3
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route.
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.