foldershare-8.x-1.2/src/Plugin/FolderShareCommand/MoveBase.php

src/Plugin/FolderShareCommand/MoveBase.php
<?php

namespace Drupal\foldershare\Plugin\FolderShareCommand;

use Symfony\Component\HttpFoundation\Request;

use Drupal\foldershare\Constants;
use Drupal\foldershare\Settings;
use Drupal\foldershare\Utilities\FormatUtilities;
use Drupal\foldershare\FolderShareInterface;
use Drupal\foldershare\Entity\FolderShare;
use Drupal\foldershare\Entity\Exception\RuntimeExceptionWithMarkup;
use Drupal\foldershare\Entity\Exception\ValidationException;

/**
 * Defines a command plugin to move files and folders.
 *
 * The command moves all selected files and folders to a chosen
 * destination folder or the root list.
 *
 * Configuration parameters:
 * - 'parentId': the parent folder, if any.
 * - 'selectionIds': selected entities to duplicate.
 * - 'destinationId': the destination folder, if any.
 *
 * @ingroup foldershare
 */
class MoveBase extends CopyMoveBase {

  /*--------------------------------------------------------------------
   *
   * Configuration.
   *
   *--------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function validateDestinationConstraints() {
    if ($this->destinationValidated === TRUE) {
      return;
    }

    if ($this->selectionValidated === FALSE) {
      $this->validateSelectionConstraints();
    }

    // Handle special cases for destination.
    $destinationId = $this->getDestinationId();
    if ($destinationId === FolderShareInterface::ALL_ROOT_LIST) {
      $routeProvider = \Drupal::service('router.route_provider');
      $titleResolver = \Drupal::service('title_resolver');
      $dummyRequest = new Request();

      $route = $routeProvider->getRouteByName(
        Constants::ROUTE_ROOT_ITEMS_ALL);
      $title = $titleResolver->getTitle($dummyRequest, $route);

      throw new ValidationException(FormatUtilities::createFormattedMessage(
        t(
          'Items cannot be moved to the administrator\'s "@title" list.',
          [
            '@title' => $title,
          ]),
        t('Please select a subfolder instead.')));
    }

    if ($destinationId === FolderShareInterface::PUBLIC_ROOT_LIST) {
      $routeProvider = \Drupal::service('router.route_provider');
      $titleResolver = \Drupal::service('title_resolver');
      $dummyRequest = new Request();

      $route = $routeProvider->getRouteByName(
        Constants::ROUTE_ROOT_ITEMS_PUBLIC);
      $title = $titleResolver->getTitle($dummyRequest, $route);

      throw new ValidationException(FormatUtilities::createFormattedMessage(
        t(
          'Items cannot be moved to the "@title" list.',
          [
            '@title' => $title,
          ]),
        t('Please select a subfolder instead.')));
    }

    parent::validateDestinationConstraints();
  }

  /**
   * {@inheritdoc}
   */
  public function validateParameters() {
    if ($this->parametersValidated === TRUE) {
      // Already validated.
      return;
    }

    //
    // Validate destination.
    // ---------------------
    // There must be a destination ID. It must be a valid ID. It must
    // not be one of the selected items. And it must not be a descendant
    // of the selected items.
    //
    // A positive destination ID is for a folder to receive the selected
    // items.
    //
    // A negative destination ID is for the user's root list.
    $destinationId = $this->getDestinationId();

    if ($destinationId < 0) {
      // Destination is the user's root list. Nothing further to validate.
      $this->parametersValidated = TRUE;
      return;
    }

    // Destination is a specific folder.
    $destination = FolderShare::load($destinationId);

    if ($destination === NULL) {
      // Destination ID is not valid. This should have been caught
      // well before this validation stage.
      throw new ValidationException(FormatUtilities::createFormattedMessage(
        t(
          '@method was called with an invalid entity ID "@id".',
          [
            '@method' => __METHOD__,
            '@id'     => $destinationId,
          ])));
    }

    // Verify that the destination is not in the selection. That would
    // be a copy to self, which is not valid.
    $selectionIds = $this->getSelectionIds();
    if (in_array($destinationId, $selectionIds) === TRUE) {
      throw new ValidationException(FormatUtilities::createFormattedMessage(
        t('Items cannot be moved into themselves..')));
    }

    // Verify that the destination is not a descendant of the selection.
    // That would be a recursive tree copy into itself.
    foreach ($selectionIds as $id) {
      $item = FolderShare::load($id);
      if ($item === NULL) {
        // The item does not exist.
        continue;
      }

      if ($destination->isDescendantOfFolderId($item->id()) === TRUE) {
        throw new ValidationException(FormatUtilities::createFormattedMessage(
          t('Items cannot be moved into their own subfolders.')));
      }

      unset($item);
    }

    unset($destination);

    $this->parametersValidated = TRUE;

    // Garbage collect.
    gc_collect_cycles();
  }

  /*--------------------------------------------------------------------
   *
   * Configuration form.
   *
   *--------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function getDescription(bool $forPage) {
    // The description varies for page vs. dialog:
    //
    // - Dialog: "Move this OPERAND to a new location".
    //
    // - Page: The description is as for a dialog, except that the single
    //   item form is not included because it is already in the title.
    $selectionIds = $this->getSelectionIds();

    //
    // Handle single item.
    // -------------------
    // Load the item and determine if it is shared.
    $nItems = count($selectionIds);
    if ($nItems === 1) {
      $item = FolderShare::load(reset($selectionIds));
      $isShared = $item->getRootItem()->isAccessShared();
      $isRoot = $item->isRootItem();
      $kind = $item->getKind();
      $name = $item->getName();

      unset($item);

      if ($forPage === TRUE) {
        if ($isShared === TRUE) {
          return [
            t(
              'Move this shared @operand to a new location.',
              [
                '@operand' => FolderShare::translateKind($kind),
              ]),
            ($isRoot === TRUE ?
              t('This item is shared. Moving it will end shared access and may affect other users.') :
              t('This item is shared. Moving it may affect other users.')),
          ];
        }

        return [
          t(
            'Move this @operand to a new location.',
            [
              '@operand' => FolderShare::translateKind($kind),
            ]),
        ];
      }

      if ($isShared === TRUE) {
        return [
          t(
            'Move shared "@name" to a new location.',
            [
              '@name' => $name,
            ]),
          ($isRoot === TRUE ?
            t('This item is shared. Moving it will end shared access and may affect other users.') :
            t('This item is shared. Moving it may affect other users.')),
        ];
      }

      return [
        t(
          'Move "@name" to a new location.',
          [
            '@name' => $name,
          ]),
      ];
    }

    // Find the kinds for each of the selection IDs. Then choose an
    // operand based on the selection's single kind, or "items".
    $selectionKinds = FolderShare::findKindsForIds($selectionIds);
    if (count($selectionKinds) === 1) {
      $operand = FolderShare::translateKinds(key($selectionKinds));
    }
    else {
      $operand = FolderShare::translateKinds('items');
    }

    // If there is no parent, then the selection are all root items.
    // Load them all and check if any of them are shared.
    //
    // If there is a parent, then just check that parent to get the root
    // and see if it is shared. Don't load the selection.
    $someShared = FALSE;
    $allShared = FALSE;
    $isRoot = FALSE;
    if ($this->getParent() === NULL) {
      $isRoot = TRUE;
      $nShared = 0;

      foreach ($selectionIds as $id) {
        $item = FolderShare::load($id);
        if ($item === NULL) {
          // The item does not exist.
          continue;
        }

        if ($item->isAccessShared() === TRUE) {
          $nShared++;
        }

        unset($item);
      }

      if ($nShared !== 0) {
        if (count($selectionIds) === $nShared) {
          $allShared = TRUE;
        }
        else {
          $someShared = TRUE;
        }
      }
    }
    else {
      $parent    = $this->getParent();
      $root      = $parent->getRootItem();
      $allShared = $root->isAccessShared();
      unset($root);
    }

    if ($allShared === TRUE) {
      return [
        t(
          'Move @count shared @operand to a new location.',
          [
            '@count'   => $nItems,
            '@operand' => $operand,
          ]),
        ($isRoot === TRUE ?
          t('These items shared. Moving them will end shared access and may affect other users.') :
          t('These items are shared. Moving them may affect other users.')),
      ];
    }

    if ($someShared === TRUE) {
      return [
        t(
          'Move @count @operand to a new location.',
          [
            '@count'   => $nItems,
            '@operand' => $operand,
          ]),
        ($isRoot === TRUE ?
          t('Some of these items shared. Moving them will end shared access and may affect other users.') :
          t('Some of these items are shared. Moving them may affect other users.')),
      ];
    }

    return [
      t(
        'Move @count @operand to a new location.',
        [
          '@count'   => $nItems,
          '@operand' => $operand,
        ]),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getTitle(bool $forPage) {
    // The title varies for page vs. dialog:
    //
    // - Dialog: "Move".
    //
    // - Page: The title is longer and has the form "Move OPERAND", where
    //   OPERAND can be the name of the item if one item is being deleted,
    //   or the count and kinds if multiple items are being deleted. This
    //   follows Drupal convention.
    if ($forPage === FALSE) {
      return t('Move');
    }

    $selectionIds = $this->getSelectionIds();

    if (count($selectionIds) === 1) {
      // Page title. There is only one item. Load it.
      $item = FolderShare::load($selectionIds[0]);
      return t(
        'Move "@name"',
        [
          '@name' => $item->getName(),
        ]);
    }

    // Find the kinds for each of the selection IDs. Then choose an
    // operand based on the selection's single kind, or "items".
    $selectionKinds = FolderShare::findKindsForIds($selectionIds);
    if (count($selectionIds) === 1) {
      $kind = key($selectionKinds);
      $operand = FolderShare::translateKind($kind);
    }
    elseif (count($selectionKinds) === 1) {
      $kind = key($selectionKinds);
      $operand = FolderShare::translateKinds($kind);
    }
    else {
      $operand = FolderShare::translateKinds('items');
    }

    // Include the count and operand kind.
    return t(
      "Move @count @operand?",
      [
        '@count' => count($selectionIds),
        '@operand' => $operand,
      ]);
  }

  /**
   * {@inheritdoc}
   */
  public function getSubmitButtonName() {
    return t('Move');
  }

  /*--------------------------------------------------------------------
   *
   * Execute.
   *
   *--------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function execute() {
    $ids = $this->getSelectionIds();
    $destination = $this->getDestination();

    try {
      if ($destination === NULL) {
        FolderShare::moveToRootMultiple($ids);
      }
      else {
        FolderShare::moveToFolderMultiple($ids, $destination);
      }
    }
    catch (RuntimeExceptionWithMarkup $e) {
      \Drupal::messenger()->addMessage($e->getMarkup(), 'error', TRUE);
    }
    catch (\Exception $e) {
      \Drupal::messenger()->addMessage($e->getMessage(), 'error');
    }

    if (Settings::getCommandNormalCompletionReportEnable() === TRUE) {
      \Drupal::messenger()->addMessage(
        \Drupal::translation()->formatPlural(
          count($ids),
          "The item has been moved.",
          "@count items have been moved."),
        'status');
    }
  }

}

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

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