You are here

class PhotosUploadForm in Album Photos 8.5

Same name and namespace in other branches
  1. 8.4 src/Form/PhotosUploadForm.php \Drupal\photos\Form\PhotosUploadForm
  2. 6.0.x src/Form/PhotosUploadForm.php \Drupal\photos\Form\PhotosUploadForm

Defines a form to upload photos to this site.

Hierarchy

Expanded class hierarchy of PhotosUploadForm

1 string reference to 'PhotosUploadForm'
photos.routing.yml in ./photos.routing.yml
photos.routing.yml

File

src/Form/PhotosUploadForm.php, line 26

Namespace

Drupal\photos\Form
View source
class PhotosUploadForm extends FormBase {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $connection;

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * The entity manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystem
   */
  protected $fileSystem;

  /**
   * The image factory.
   *
   * @var \Drupal\Core\Image\ImageFactory
   */
  protected $imageFactory;

  /**
   * A logger instance.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * The messenger.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The current route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * The photos upload handler.
   *
   * @var \Drupal\photos\PhotosUploadInterface
   */
  protected $photosUpload;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Database\Connection $connection
   *   The database connection.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager
   *   The entity manager service.
   * @param \Drupal\Core\File\FileSystem $file_system
   *   The file system service.
   * @param \Drupal\Core\Image\ImageFactory $image_factory
   *   The image factory.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The current route match.
   * @param \Drupal\photos\PhotosUploadInterface $photos_upload
   *   The photos upload handler.
   */
  public function __construct(Connection $connection, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_manager, FileSystem $file_system, ImageFactory $image_factory, MessengerInterface $messenger, ModuleHandlerInterface $module_handler, RouteMatchInterface $route_match, PhotosUploadInterface $photos_upload) {
    $this->connection = $connection;
    $this->entityFieldManager = $entity_field_manager;
    $this->entityTypeManager = $entity_manager;
    $this->fileSystem = $file_system;
    $this->imageFactory = $image_factory;
    $this->logger = $this
      ->getLogger('photos');
    $this->messenger = $messenger;
    $this->moduleHandler = $module_handler;
    $this->routeMatch = $route_match;
    $this->photosUpload = $photos_upload;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('database'), $container
      ->get('entity_field.manager'), $container
      ->get('entity_type.manager'), $container
      ->get('file_system'), $container
      ->get('image.factory'), $container
      ->get('messenger'), $container
      ->get('module_handler'), $container
      ->get('current_route_match'), $container
      ->get('photos.upload'));
  }

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

  /**
   * A custom access check.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The album node entity.
   *
   * @return \Drupal\Core\Access\AccessResult
   *   The access result.
   */
  public function access(NodeInterface $node) {

    // Check if user can edit this album.
    if ($node
      ->getType() == 'photos' && $node
      ->access('update')) {
      return AccessResult::allowed();
    }
    else {
      return AccessResult::forbidden();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this
      ->config('photos.settings');

    // Get node object.
    $node = $this->routeMatch
      ->getParameter('node');
    $nid = $node
      ->id();
    $form['#attributes']['enctype'] = 'multipart/form-data';
    $form['new'] = [
      '#title' => $this
        ->t('Image upload'),
      '#weight' => -4,
      '#type' => 'details',
      '#open' => TRUE,
    ];
    $allow_zip = $config
      ->get('photos_upzip') ? ' zip' : '';

    // Check if plubload is installed.
    if ($config
      ->get('photos_plupload_status')) {
      $form['new']['plupload'] = [
        '#type' => 'plupload',
        '#title' => $this
          ->t('Upload photos'),
        '#description' => $this
          ->t('Upload multiple images.'),
        '#autoupload' => TRUE,
        '#submit_element' => '#edit-submit',
        '#upload_validators' => [
          'file_validate_extensions' => [
            'jpg jpeg gif png' . $allow_zip,
          ],
        ],
        '#plupload_settings' => [
          'chunk_size' => '1mb',
        ],
      ];
    }
    else {

      // Manual upload form.
      $form['new']['#description'] = $this
        ->t('Allowed types: jpg gif png jpeg@zip', [
        '@zip' => $allow_zip,
      ]);
      for ($i = 0; $i < $config
        ->get('photos_num'); ++$i) {
        $form['new']['images_' . $i] = [
          '#type' => 'file',
        ];
        $form['new']['title_' . $i] = [
          '#type' => 'textfield',
          '#title' => $this
            ->t('Image title'),
        ];
        $form['new']['des_' . $i] = [
          '#type' => 'textarea',
          '#title' => $this
            ->t('Image description'),
          '#cols' => 40,
          '#rows' => 3,
        ];
      }
    }
    if ($this->moduleHandler
      ->moduleExists('media_library_form_element')) {

      // Check photos default multi-upload field.
      $uploadField = $this
        ->config('photos.settings')
        ->get('multi_upload_default_field');
      $uploadFieldParts = explode(':', $uploadField);
      $field = isset($uploadFieldParts[0]) ? $uploadFieldParts[0] : 'field_image';
      $allBundleFields = $this->entityFieldManager
        ->getFieldDefinitions('photos_image', 'photos_image');
      if (isset($allBundleFields[$field])) {
        $fieldType = $allBundleFields[$field]
          ->getType();

        // Check if media field.
        if ($fieldType == 'entity_reference') {
          $mediaField = isset($uploadFieldParts[1]) ? $uploadFieldParts[1] : '';
          $mediaBundle = isset($uploadFieldParts[2]) ? $uploadFieldParts[2] : '';
          if ($mediaField && $mediaBundle) {
            $form['new']['media_images'] = [
              '#type' => 'media_library',
              '#allowed_bundles' => [
                $mediaBundle,
              ],
              '#title' => $this
                ->t('Select media images'),
              '#default_value' => NULL,
              '#description' => $this
                ->t('Select media images to add to this album.'),
              '#cardinality' => -1,
            ];
          }
        }
      }
    }

    // @todo album_id is redundant unless albums become own entity.
    //   - maybe make album_id serial and add nid... or entity_id.
    $form['new']['album_id'] = [
      '#type' => 'value',
      '#value' => $nid,
    ];
    $form['new']['nid'] = [
      '#type' => 'value',
      '#value' => $nid,
    ];
    $form['new']['submit'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Confirm upload'),
      '#weight' => 10,
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {

    // ...
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $user = $this
      ->currentUser();
    $config = $this
      ->config('photos.settings');
    $count = 0;
    $nid = $form_state
      ->getValue('nid');

    // If photos_access is enabled check viewid.
    $scheme = 'default';
    if ($this->moduleHandler
      ->moduleExists('photos_access')) {
      $node = $this->entityTypeManager
        ->getStorage('node')
        ->load($nid);
      if (isset($node->privacy) && isset($node->privacy['viewid'])) {
        $album_viewid = $node->privacy['viewid'];
        if ($album_viewid > 0) {

          // Check for private file path.
          if (PrivateStream::basePath()) {
            $scheme = 'private';
          }
          else {

            // Set warning message.
            $this->messenger
              ->addWarning($this
              ->t('Warning: image
              files can still be accessed by visiting the direct URL. For
              better security, ask your website admin to setup a private file
              path.'));
          }
        }
      }
    }

    // Check if plupload is enabled.
    // @todo check for plupload library?
    if ($config
      ->get('photos_plupload_status')) {
      $plupload_files = $form_state
        ->getValue('plupload');
      foreach ($plupload_files as $uploaded_file) {
        if ($uploaded_file['status'] == 'done') {

          // Check for zip files.
          $ext = mb_substr($uploaded_file['name'], -3);
          if ($ext != 'zip' && $ext != 'ZIP') {

            // Prepare directory.
            // @todo move path to after entity is created or move again later if needed.
            // @todo generate temp path before tokens are available.
            $photosPath = $this->photosUpload
              ->path($scheme);
            $photosName = $uploaded_file['name'];
            $file_uri = $this->fileSystem
              ->getDestinationFilename($photosPath . '/' . $photosName, FileSystemInterface::EXISTS_RENAME);
            if ($this->fileSystem
              ->move($uploaded_file['tmppath'], $file_uri)) {
              $path_parts = pathinfo($file_uri);
              $image = $this->imageFactory
                ->get($file_uri);
              if (isset($path_parts['extension']) && $path_parts['extension'] && $image
                ->getWidth()) {

                // Create a file entity.
                $file = $this->entityTypeManager
                  ->getStorage('file')
                  ->create([
                  'uri' => $file_uri,
                  'uid' => $user
                    ->id(),
                  'status' => FILE_STATUS_PERMANENT,
                  'album_id' => $form_state
                    ->getValue('album_id'),
                  'nid' => $form_state
                    ->getValue('nid'),
                  'filename' => $photosName,
                  'filesize' => $image
                    ->getFileSize(),
                  'filemime' => $image
                    ->getMimeType(),
                ]);
                if ($file
                  ->save()) {
                  $this->photosUpload
                    ->saveImage($file);
                }
                $count++;
              }
              else {
                $this->fileSystem
                  ->delete($file_uri);
                $this->logger
                  ->notice('Wrong file type');
              }
            }
            else {
              $this->logger
                ->notice('Upload error. Could not move temp file.');
            }
          }
          else {
            if (!$config
              ->get('photos_upzip')) {
              $this->messenger
                ->addError($this
                ->t('Please set Album
                photos to open zip uploads.'));
            }
            $directory = $this->photosUpload
              ->path();
            $this->fileSystem
              ->prepareDirectory($directory);
            $zip = $this->fileSystem
              ->getDestinationFilename($directory . '/' . $uploaded_file['name'], FileSystemInterface::EXISTS_RENAME);
            if ($this->fileSystem
              ->move($uploaded_file['tmppath'], $zip)) {
              $params = [];
              $params['album_id'] = $form_state
                ->getValue('album_id');
              $params['nid'] = $form_state
                ->getValue('nid');
              $params['title'] = $uploaded_file['name'];
              $params['des'] = '';

              // Unzip it.
              if (!($file_count = $this->photosUpload
                ->unzip($zip, $params, $scheme))) {
                $this->messenger
                  ->addError($this
                  ->t('Zip upload failed.'));
              }
              else {

                // Update image upload count.
                $count = $count + $file_count;
              }
            }
          }
        }
        else {
          $this->messenger
            ->addError($this
            ->t('Error uploading some photos.'));
        }
      }
    }
    else {

      // Manual upload form.
      $album_id = $form_state
        ->getValue('album_id');
      $photos_num = $config
        ->get('photos_num');
      for ($i = 0; $i < $photos_num; ++$i) {
        if (isset($_FILES['files']['name']['images_' . $i]) && $_FILES['files']['name']['images_' . $i]) {
          $ext = mb_substr($_FILES['files']['name']['images_' . $i], -3);
          if ($ext != 'zip' && $ext != 'ZIP') {

            // Prepare directory.
            $photosPath = $this->photosUpload
              ->path($scheme);
            $photosName = $_FILES['files']['name']['images_' . $i];
            $file_uri = $this->fileSystem
              ->getDestinationFilename($photosPath . '/' . $photosName, FileSystemInterface::EXISTS_RENAME);
            if ($this->fileSystem
              ->move($_FILES['files']['tmp_name']['images_' . $i], $file_uri)) {
              $path_parts = pathinfo($file_uri);
              $image = $this->imageFactory
                ->get($file_uri);

              // @todo file_validate_is_image?
              if (isset($path_parts['extension']) && $path_parts['extension'] && $image
                ->getWidth()) {

                // Create a file entity.
                $file = $this->entityTypeManager
                  ->getStorage('file')
                  ->create([
                  'uri' => $file_uri,
                  'uid' => $user
                    ->id(),
                  'status' => FILE_STATUS_PERMANENT,
                  'album_id' => $form_state
                    ->getValue('album_id'),
                  'nid' => $form_state
                    ->getValue('nid'),
                  'filename' => $photosName,
                  'filesize' => $image
                    ->getFileSize(),
                  'filemime' => $image
                    ->getMimeType(),
                  'title' => $form_state
                    ->getValue('title_' . $i),
                  'des' => $form_state
                    ->getValue('des_' . $i),
                ]);
                if ($file
                  ->save()) {
                  $this->photosUpload
                    ->saveImage($file);
                }
                $count++;
              }
              else {
                $this->fileSystem
                  ->delete($file_uri);
                $this->logger
                  ->notice('Wrong file type');
              }
            }
          }
          else {

            // Zip upload from manual upload form.
            if (!$config
              ->get('photos_upzip')) {
              $this->messenger
                ->addError($this
                ->t('Please update settings to allow zip uploads.'));
            }
            else {
              $directory = $this->photosUpload
                ->path();
              $this->fileSystem
                ->prepareDirectory($directory);
              $zip = $this->fileSystem
                ->getDestinationFilename($directory . '/' . trim(basename($_FILES['files']['name']['images_' . $i])), FileSystemInterface::EXISTS_RENAME);
              if ($this->fileSystem
                ->move($_FILES['files']['tmp_name']['images_' . $i], $zip)) {
                $params = [];
                $params['album_id'] = $album_id;
                $params['nid'] = $form_state
                  ->getValue('nid') ? $form_state
                  ->getValue('nid') : $form_state
                  ->getValue('album_id');
                $params['description'] = $form_state
                  ->getValue('des_' . $i);
                $params['title'] = $form_state
                  ->getValue('title_' . $i);
                if (!($file_count = $this->photosUpload
                  ->unzip($zip, $params, $scheme))) {

                  // Upload failed.
                }
                else {
                  $count = $count + $file_count;
                }
              }
            }
          }
        }
      }
    }

    // Handle media field.
    $selected_media = explode(',', $form_state
      ->getValue('media_images'));
    foreach ($selected_media as $media_id) {

      // Save media to album.
      $mediaSaved = $this->photosUpload
        ->saveExistingMedia($media_id, $nid);
      if ($mediaSaved) {
        $count++;
      }
    }

    // Clear node and album page cache.
    Cache::invalidateTags([
      'node:' . $nid,
      'photos:album:' . $nid,
    ]);
    $message = $this
      ->formatPlural($count, '1 image uploaded.', '@count images uploaded.');
    $this->messenger
      ->addMessage($message);
  }

}

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::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.
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.
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PhotosUploadForm::$connection protected property The database connection.
PhotosUploadForm::$entityFieldManager protected property The entity field manager.
PhotosUploadForm::$entityTypeManager protected property The entity manager.
PhotosUploadForm::$fileSystem protected property The file system service.
PhotosUploadForm::$imageFactory protected property The image factory.
PhotosUploadForm::$logger protected property A logger instance.
PhotosUploadForm::$messenger protected property The messenger. Overrides MessengerTrait::$messenger
PhotosUploadForm::$moduleHandler protected property The module handler.
PhotosUploadForm::$photosUpload protected property The photos upload handler.
PhotosUploadForm::$routeMatch protected property The current route match. Overrides FormBase::$routeMatch
PhotosUploadForm::access public function A custom access check.
PhotosUploadForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
PhotosUploadForm::create public static function Instantiates a new instance of this class. Overrides FormBase::create
PhotosUploadForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
PhotosUploadForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
PhotosUploadForm::validateForm public function Form validation handler. Overrides FormBase::validateForm
PhotosUploadForm::__construct public function Constructor.
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.