You are here

class MediaBulkUploadForm in Media Bulk Upload 8

Class BulkMediaUploadForm.

@package Drupal\media_upload\Form

Hierarchy

Expanded class hierarchy of MediaBulkUploadForm

1 string reference to 'MediaBulkUploadForm'
media_bulk_upload.routing.yml in ./media_bulk_upload.routing.yml
media_bulk_upload.routing.yml

File

src/Form/MediaBulkUploadForm.php, line 24

Namespace

Drupal\media_bulk_upload\Form
View source
class MediaBulkUploadForm extends FormBase {

  /**
   * Media Type storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $mediaTypeStorage;

  /**
   * Media Bulk Config storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $mediaBulkConfigStorage;

  /**
   * Media entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $mediaStorage;

  /**
   * File entity storage.
   *
   * @var \Drupal\file\FileStorageInterface
   */
  protected $fileStorage;

  /**
   * Media SubForm Manager.
   *
   * @var \Drupal\media_bulk_upload\MediaSubFormManager
   */
  protected $mediaSubFormManager;

  /**
   * The max file size for the media bulk form.
   *
   * @var string
   */
  protected $maxFileSizeForm;

  /**
   * The allowed extensions for the media bulk form.
   *
   * @var array
   */
  protected $allowed_extensions = [];

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * BulkMediaUploadForm constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\media_bulk_upload\MediaSubFormManager $mediaSubFormManager
   *   Media Sub Form Manager.
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   Current User.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(EntityTypeManagerInterface $entityTypeManager, MediaSubFormManager $mediaSubFormManager, AccountProxyInterface $currentUser, MessengerInterface $messenger) {
    $this->mediaTypeStorage = $entityTypeManager
      ->getStorage('media_type');
    $this->mediaBulkConfigStorage = $entityTypeManager
      ->getStorage('media_bulk_config');
    $this->mediaStorage = $entityTypeManager
      ->getStorage('media');
    $this->fileStorage = $entityTypeManager
      ->getStorage('file');
    $this->maxFileSizeForm = Environment::getUploadMaxSize();
    $this->mediaSubFormManager = $mediaSubFormManager;
    $this->currentUser = $currentUser;
    $this->messenger = $messenger;
  }

  /**
   * {@inheritdoc}
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('entity_type.manager'), $container
      ->get('media_bulk_upload.subform_manager'), $container
      ->get('current_user'), $container
      ->get('messenger'));
  }

  /**
   * Returns a unique string identifying the form.
   *
   * @return string
   *   The unique string identifying the form.
   */
  public function getFormId() {
    return 'media_bulk_upload_form';
  }

  /**
   * Form constructor.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param \Drupal\media_bulk_upload\Entity\MediaBulkConfigInterface|null $media_bulk_config
   *   The media bulk configuration entity.
   *
   * @return array
   *   The form structure.
   *
   * @throws \Exception
   */
  public function buildForm(array $form, FormStateInterface $form_state, MediaBulkConfigInterface $media_bulk_config = NULL) {
    $mediaBulkConfig = $media_bulk_config;
    if ($mediaBulkConfig === NULL) {
      return $form;
    }
    $mediaTypeManager = $this->mediaSubFormManager
      ->getMediaTypeManager();
    $mediaTypes = $this->mediaSubFormManager
      ->getMediaTypeManager()
      ->getBulkMediaTypes($mediaBulkConfig);
    $mediaTypeLabels = [];
    foreach ($mediaTypes as $mediaType) {
      $extensions = $mediaTypeManager
        ->getMediaTypeExtensions($mediaType);
      natsort($extensions);
      $this
        ->addAllowedExtensions($extensions);
      $maxFileSize = $mediaTypeManager
        ->getTargetFieldMaxSize($mediaType);
      if (empty($maxFileSize)) {
        $maxFileSize = $this->mediaSubFormManager
          ->getDefaultMaxFileSize();
      }
      $mediaTypeLabels[] = $mediaType
        ->label() . ' (max ' . $maxFileSize . '): ' . implode(', ', $extensions);
      if ($this
        ->isMaxFileSizeLarger($maxFileSize)) {
        $this
          ->setMaxFileSizeForm($maxFileSize);
      }
    }
    $form['#tree'] = TRUE;
    $form['information_wrapper'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'media-bulk-upload-information-wrapper',
        ],
      ],
    ];
    $form['information_wrapper']['information_label'] = [
      '#type' => 'html_tag',
      '#tag' => 'label',
      '#value' => $this
        ->t('Information'),
      '#attributes' => [
        'class' => [
          'form-control-label',
        ],
        'for' => 'media_bulk_upload_information',
      ],
    ];
    $form['information_wrapper']['information'] = [
      '#theme' => 'item_list',
      '#title' => $this
        ->t('Media Types:'),
      '#items' => $mediaTypeLabels,
    ];
    $form['information_wrapper']['warning'] = [
      '#type' => 'html_tag',
      '#tag' => 'span',
      '#id' => 'media_bulk_upload_information',
      '#name' => 'media_bulk_upload_information',
      '#value' => '<p>Please be
        aware that if file extensions overlap between the media types that are
        available in this upload form, that the media entity will be assigned
        automatically to one of these types.</p>',
    ];
    $form['dropzonejs'] = [
      '#type' => 'dropzonejs',
      '#title' => $this
        ->t('Dropzone'),
      '#required' => TRUE,
      '#dropzone_description' => $this
        ->t('Click or drop your files here'),
      '#max_filesize' => $this->maxFileSizeForm,
      '#extensions' => implode(' ', $this->allowed_extensions),
    ];
    if ($this->mediaSubFormManager
      ->validateMediaFormDisplayUse($mediaBulkConfig)) {
      $form['fields'] = [
        '#type' => 'fieldset',
        '#title' => $this
          ->t('Fields'),
        'shared' => [
          '#field_parents' => [
            'fields',
            'shared',
          ],
          '#parents' => [
            'fields',
            'shared',
          ],
        ],
      ];
      $this->mediaSubFormManager
        ->buildMediaSubForm($form['fields']['shared'], $form_state, $mediaBulkConfig);
    }
    $form['media_bundle_config'] = [
      '#type' => 'value',
      '#value' => $mediaBulkConfig
        ->id(),
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Submit'),
    ];
    return $form;
  }

  /**
   * Add allowed extensions.
   *
   * @param array $extensions
   *   Allowed Extensions.
   *
   * @return $this
   *   MediaBulkUploadForm.
   */
  protected function addAllowedExtensions(array $extensions) {
    $this->allowed_extensions = array_unique(array_merge($this->allowed_extensions, $extensions));
    return $this;
  }

  /**
   * Validate if a max file size is bigger then the current max file size.
   *
   * @param string $MaxFileSize
   *   File Size.
   *
   * @return bool
   *  TRUE if the given size is larger than the one that is set.
   */
  protected function isMaxFileSizeLarger($MaxFileSize) {
    $size = Bytes::toInt($MaxFileSize);
    $currentSize = Bytes::toInt($this->maxFileSizeForm);
    return $size > $currentSize;
  }

  /**
   * Set the max File size for the form.
   *
   * @param string $newMaxFileSize
   *   File Size.
   *
   * @return $this
   *   MediaBulkUploadForm.
   */
  protected function setMaxFileSizeForm($newMaxFileSize) {
    $this->maxFileSizeForm = $newMaxFileSize;
    return $this;
  }

  /**
   * Submit handler to create the file entities and media entities.
   *
   * @param array $form
   *   The form render array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state
      ->getValues();
    $mediaBundleConfigId = $values['media_bundle_config'];

    /** @var MediaBulkConfigInterface $mediaBulkConfig */
    $mediaBulkConfig = $this->mediaBulkConfigStorage
      ->load($mediaBundleConfigId);
    $files = $values['dropzonejs']['uploaded_files'];
    $mediaTypes = $this->mediaSubFormManager
      ->getMediaTypeManager()
      ->getBulkMediaTypes($mediaBulkConfig);
    $mediaType = reset($mediaTypes);
    $mediaFormDisplay = $this->mediaSubFormManager
      ->getMediaFormDisplay($mediaBulkConfig, $mediaType);
    $this
      ->prepareFormValues($form_state);
    $savedMediaItems = [];
    foreach ($files as $file) {
      try {
        $media = $this
          ->processFile($mediaBulkConfig, $file);
        if (!$media) {
          continue;
        }
        if ($this->mediaSubFormManager
          ->validateMediaFormDisplayUse($mediaBulkConfig)) {
          $extracted = $mediaFormDisplay
            ->extractFormValues($media, $form['fields']['shared'], $form_state);
          $this
            ->copyFormValuesToEntity($media, $extracted, $form_state);
        }
        $media
          ->save();
        $savedMediaItems[] = $media;
      } catch (\Exception $e) {
        watchdog_exception('media_bulk_upload', $e);
      }
    }
    if (!empty($savedMediaItems)) {
      $this
        ->messenger()
        ->addStatus($this
        ->t('@count media item(s) are created.', [
        '@count' => count($savedMediaItems),
      ]));
    }
  }

  /**
   * Process a file upload.
   *
   * Will create a file entity and prepare a media entity with data.
   *
   * @param \Drupal\media_bulk_upload\Entity\MediaBulkConfigInterface $mediaBulkConfig
   *   Media Bulk Config.
   * @param array $file
   *   File upload data.
   *
   * @return \Drupal\media\MediaInterface
   *   The unsaved media entity that is created.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Exception
   */
  protected function processFile(MediaBulkConfigInterface $mediaBulkConfig, array $file) {
    $fileInfo = pathinfo($file['filename']);
    $filename = $fileInfo['basename'];
    if (!$this
      ->validateFilename($fileInfo)) {
      $this
        ->messenger()
        ->addError($this
        ->t('File :filename does not have a valid extension or filename.', [
        ':filename' => $filename,
      ]));
      throw new \Exception("File {$filename} does not have a valid extension or filename.");
    }
    $allowedMediaTypes = $this->mediaSubFormManager
      ->getMediaTypeManager()
      ->getBulkMediaTypes($mediaBulkConfig);
    $matchingMediaTypes = $this->mediaSubFormManager
      ->getMediaTypeManager()
      ->getMediaTypeIdsByFileExtension($fileInfo['extension']);
    $mediaTypes = array_intersect_key($matchingMediaTypes, $allowedMediaTypes);
    $mediaType = reset($mediaTypes);
    if (!$this
      ->validateFileSize($mediaType, $file['path'])) {
      $fileSizeSetting = $this->mediaSubFormManager
        ->getMediaTypeManager()
        ->getTargetFieldMaxSize($mediaType);
      $mediaTypeLabel = $mediaType
        ->label();
      $this
        ->messenger()
        ->addError($this
        ->t('File :filename exceeds the maximum file size of :file_size for media type :media_type exceeded.', [
        ':filename' => $filename,
        ':file_size' => $fileSizeSetting,
        ':media_type' => $mediaTypeLabel,
      ]));
      throw new \Exception("File {$filename} exceeds the maximum file size of {$fileSizeSetting} for media type {$mediaTypeLabel} exceeded.");
    }
    $uri_scheme = $this->mediaSubFormManager
      ->getTargetFieldDirectory($mediaType);
    $destination = $uri_scheme . '/' . $file['filename'];
    $file_default_scheme = \Drupal::config('system.file')
      ->get('default_scheme') . '://';
    if ($uri_scheme === $file_default_scheme) {
      $destination = $uri_scheme . $file['filename'];
    }

    /** @var \Drupal\file\FileInterface $fileEntity */
    $fileEntity = $this->fileStorage
      ->create([
      'uri' => $file['path'],
      'uid' => $this->currentUser
        ->id(),
      'status' => FILE_STATUS_PERMANENT,
    ]);
    $fileEntity
      ->save();
    file_move($fileEntity, $destination);
    if (!$fileEntity) {
      $this
        ->messenger()
        ->addError($this
        ->t('File :filename could not be created.', [
        ':filename' => $filename,
      ]), 'error');
      throw new \Exception('File entity could not be created.');
    }
    $values = $this
      ->getNewMediaValues($mediaType, $fileInfo, $fileEntity);

    /** @var \Drupal\media\MediaInterface $media */
    $media = $this->mediaStorage
      ->create($values);
    return $media;
  }

  /**
   * Validate if the filename and extension are valid in the provided file info.
   *
   * @param array $fileInfo
   *   File info.
   *
   * @return bool
   *   If the file info validates, returns true.
   */
  protected function validateFilename(array $fileInfo) {
    return !(empty($fileInfo['filename']) || empty($fileInfo['extension']));
  }

  /**
   * Check the size of a file.
   *
   * @param \Drupal\media\MediaTypeInterface $mediaType
   *   Media Type.
   * @param string $filePath
   *   File path.
   *
   * @return bool
   *   True if max size for a given file do not exceeds max size for its type.
   */
  protected function validateFileSize(MediaTypeInterface $mediaType, $filePath) {
    $fileSizeSetting = $this->mediaSubFormManager
      ->getMediaTypeManager()
      ->getTargetFieldMaxSize($mediaType);
    $fileSize = filesize($filePath);
    $maxFileSize = !empty($fileSizeSetting) ? Bytes::toInt($fileSizeSetting) : Environment::getUploadMaxSize();
    if ($maxFileSize == 0) {
      return true;
    }
    return $fileSize <= $maxFileSize;
  }

  /**
   * Builds the array of all necessary info for the new media entity.
   *
   * @param \Drupal\media\MediaTypeInterface $mediaType
   *   Media Type ID.
   * @param array $fileInfo
   *   File info.
   * @param \Drupal\file\FileInterface $file
   *   File entity.
   *
   * @return array
   *   Return an array describing the new media entity.
   */
  protected function getNewMediaValues(MediaTypeInterface $mediaType, array $fileInfo, FileInterface $file) {
    $targetFieldName = $this->mediaSubFormManager
      ->getMediaTypeManager()
      ->getTargetFieldName($mediaType);
    return [
      'bundle' => $mediaType
        ->id(),
      'name' => $fileInfo['filename'],
      $targetFieldName => [
        'target_id' => $file
          ->id(),
        'title' => $fileInfo['filename'],
      ],
    ];
  }

  /**
   * Copy the submitted values for the media subform to the media entity.
   *
   * @param \Drupal\media\MediaInterface $media
   *   Media Entity.
   * @param array $extracted
   *   Extracted entity values.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Form State.
   */
  protected function copyFormValuesToEntity(MediaInterface $media, array $extracted, FormStateInterface $form_state) {
    foreach ($form_state
      ->getValues() as $name => $values) {
      if (isset($extracted[$name]) || !$media
        ->hasField($name)) {
        continue;
      }
      $media
        ->set($name, $values);
    }
  }

  /**
   * Prepare form submitted values.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Form State.
   *
   * @return $this
   *   Media Bulk Upload Form.
   */
  protected function prepareFormValues(FormStateInterface $form_state) {

    // If the shared name is empty, remove it from the form state.
    // Otherwise the extractFormValues function will override with an empty value.
    $shared = $form_state
      ->getValue([
      'fields',
      'shared',
    ]);
    if (empty($shared['name'][0]['value'])) {
      unset($shared['name']);
      $form_state
        ->setValue([
        'fields',
        'shared',
      ], $shared);
    }
    return $this;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 1
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. 1
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. Overrides UrlGeneratorTrait::redirect
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.
FormBase::validateForm public function Form validation handler. Overrides FormInterface::validateForm 62
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
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.
MediaBulkUploadForm::$allowed_extensions protected property The allowed extensions for the media bulk form.
MediaBulkUploadForm::$currentUser protected property The current user.
MediaBulkUploadForm::$fileStorage protected property File entity storage.
MediaBulkUploadForm::$maxFileSizeForm protected property The max file size for the media bulk form.
MediaBulkUploadForm::$mediaBulkConfigStorage protected property Media Bulk Config storage.
MediaBulkUploadForm::$mediaStorage protected property Media entity storage.
MediaBulkUploadForm::$mediaSubFormManager protected property Media SubForm Manager.
MediaBulkUploadForm::$mediaTypeStorage protected property Media Type storage.
MediaBulkUploadForm::addAllowedExtensions protected function Add allowed extensions.
MediaBulkUploadForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
MediaBulkUploadForm::copyFormValuesToEntity protected function Copy the submitted values for the media subform to the media entity.
MediaBulkUploadForm::create public static function Overrides FormBase::create
MediaBulkUploadForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
MediaBulkUploadForm::getNewMediaValues protected function Builds the array of all necessary info for the new media entity.
MediaBulkUploadForm::isMaxFileSizeLarger protected function Validate if a max file size is bigger then the current max file size.
MediaBulkUploadForm::prepareFormValues protected function Prepare form submitted values.
MediaBulkUploadForm::processFile protected function Process a file upload.
MediaBulkUploadForm::setMaxFileSizeForm protected function Set the max File size for the form.
MediaBulkUploadForm::submitForm public function Submit handler to create the file entities and media entities. Overrides FormInterface::submitForm
MediaBulkUploadForm::validateFilename protected function Validate if the filename and extension are valid in the provided file info.
MediaBulkUploadForm::validateFileSize protected function Check the size of a file.
MediaBulkUploadForm::__construct public function BulkMediaUploadForm constructor.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
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. 1
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.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.