foldershare-8.x-1.2/src/Entity/FolderShareTraits/OperationRenameTrait.php

src/Entity/FolderShareTraits/OperationRenameTrait.php
<?php

namespace Drupal\foldershare\Entity\FolderShareTraits;

use Drupal\foldershare\ManageFileSystem;
use Drupal\foldershare\ManageLog;
use Drupal\foldershare\Utilities\FileUtilities;
use Drupal\foldershare\Entity\Exception\LockException;
use Drupal\foldershare\Entity\Exception\ValidationException;

/**
 * Rename FolderShare entities.
 *
 * This trait includes methods to rename FolderShare entities and
 * wrapped File entities.
 *
 * <B>Internal trait</B>
 * This trait is internal to the FolderShare module and used to define
 * features of the FolderShare entity class. It is a mechanism to group
 * functionality to improve code management.
 *
 * @ingroup foldershare
 */
trait OperationRenameTrait {

  /*---------------------------------------------------------------------
   *
   * Rename FolderShare entity.
   *
   *---------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function rename(string $newName) {
    //
    // Validate
    // --------
    // The new name must be different and legal.
    $oldName = $this->getName();
    if ($oldName === $newName) {
      // No change.
      return;
    }

    // The checkName() function throws an exception if the name is too
    // long or uses illegal characters.
    $this->checkName($newName);

    //
    // Lock root folder tree.
    // ----------------------
    // Lock the item's root's folder tree to insure no other operation can
    // modify the folder tree while this item is being updated.
    //
    // LOCK ROOT FOLDER TREE.
    $rootId = $this->getRootItemId();
    if (self::acquireRootOperationLock($rootId) === FALSE) {
      throw new LockException(
        self::getStandardLockExceptionMessage(t('renamed'), $this->getName()));
    }

    //
    // Lock owner's root list, if needed.
    // ----------------------------------
    // If this item is a root item, then lock the root list of the item's
    // owner (which is normally this user). This is needed in order to keep
    // the root list unchanged while we check for name collisions.
    //
    // LOCK OWNER'S ROOT LIST.
    if ($this->isRootItem() === TRUE) {
      if (self::acquireUserRootListLock($this->getOwnerId()) === FALSE) {
        // UNLOCK ROOT FOLDER TREE.
        self::releaseRootOperationLock($rootId);

        throw new LockException(
          self::getStandardLockExceptionMessage(t('renamed'), $this->getName()));
      }
    }

    //
    // Check name.
    // -----------
    // Check that the new name is unique within either the parent folder
    // (if any) or the owner's root list (if there is no parent).
    if ($this->isRootItem() === TRUE) {
      $uid = (int) $this->getOwnerId();
      if (self::isRootNameUnique($newName, (int) $this->id(), $uid) === FALSE) {
        // UNLOCK OWNER'S ROOT LIST.
        self::releaseUserRootListLock($uid);

        // UNLOCK ROOT FOLDER TREE.
        self::releaseRootOperationLock($rootId);

        throw new ValidationException(
          self::getStandardNameInUseExceptionMessage($newName));
      }
    }
    else {
      $parentFolder = $this->getParentFolder();

      if ($parentFolder->isNameUnique($newName, (int) $this->id()) === FALSE) {
        // UNLOCK ROOT FOLDER TREE.
        self::releaseRootOperationLock($rootId);

        throw new ValidationException(
          self::getStandardNameInUseExceptionMessage($newName));
      }
    }

    //
    // Change the name.
    // ----------------
    // Set the name and save.
    //
    // If the item is a file, image, or media object change the underlying
    // item's name too.
    $this->setName($newName);
    $this->save();

    $this->renameWrappedFile($newName);

    //
    // Unlock everything.
    // ------------------
    // Unlock the owner's root list, if it was locked, and unlock the
    // root folder tree containing the item.
    //
    if ($this->isRootItem() === TRUE) {
      // UNLOCK OWNER'S ROOT LIST.
      self::releaseUserRootListLock($this->getOwnerId());
    }

    // UNLOCK ROOT FOLDER TREE.
    self::releaseRootOperationLock($rootId);

    //
    // Hook & log.
    // -----------
    // Note the change.
    $requestingUid = self::getCurrentUserId()[0];
    self::postOperationHook(
      'rename',
      [
        $this,
        $oldName,
        $newName,
        $requestingUid,
      ]);
    ManageLog::activity(
      "Renamed @kind '@oldName' (# @id) to '@newName'.",
      [
        '@id'      => $this->id(),
        '@kind'    => $this->getKind(),
        '@oldName' => $oldName,
        '@newName' => $newName,
        'entity'   => $this,
        'uid'      => $requestingUid,
      ]);
  }

  /*---------------------------------------------------------------------
   *
   * Rename wrapped File entity.
   *
   *---------------------------------------------------------------------*/

  /**
   * Renames an entity's underlying file, image, and media entity.
   *
   * After a FolderShare entity has been renamed, this method updates any
   * underlying entities to share the same name. This includes File objects
   * underneath 'file' and 'image' kinds, and Media objects underneath
   * 'media' kinds.
   *
   * This method has no effect if the current entity is not a file, image,
   * or media wrapper.
   *
   * @param string $newName
   *   The new name for the underlying entities.
   */
  private function renameWrappedFile(string $newName) {
    if ($this->isFolder() === TRUE) {
      // Folders do not wrap files.
      return;
    }

    // Change the underlying File or Media entity's name.  This public
    // name appears in the file and image URI as well so that field
    // formatters can see a name and extension, if they need it.
    if ($this->isFile() === TRUE || $this->isImage() === TRUE) {
      if ($this->isFile() === TRUE) {
        $file = $this->getFile();
      }
      else {
        $file = $this->getImage();
      }

      if ($file === NULL) {
        // There is no wrapped file? The entity is corrupted!
        return;
      }

      // Get the file's MIME type based upon the new name, which may
      // have changed the file name extension.
      $mimeType = \Drupal::service('file.mime_type.guesser')->guess($newName);

      // Set the name first. This is used by the FileUtilities call below
      // to compute a new URI based upon the name (really, just the
      // extension) and the file's entity ID.
      $file->setFilename($newName);
      $file->save();

      $oldUri = $file->getFileUri();
      $newUri = ManageFileSystem::getFileUri($file);

      // If the URIs differ, then something about the new name has caused
      // the underlying saved file to change its name. This is probably the
      // filename extension. Move the file.
      if ($oldUri !== $newUri) {
        // It should not be possible for the following move to fail. The
        // old and new URIs differ and both are based upon the file
        // entity's ID, which is unique. This prevents name collisions.
        // Only the filename extensions can differ.
        //
        // The only errors that can occur are problems with the underlying
        // server file system. And there's nothing we can do about them.
        // The above function will report those to the server log.
        FileUtilities::rename($oldUri, $newUri);

        // Update the URI to point to the moved file.
        $file->setFileUri($newUri);

        // If the file name has changed, the extension may have changed,
        // and thus the MIME type may have changed. Save the new MIME type.
        $file->setMimeType($mimeType);
        $file->save();

        $this->setMimeType($mimeType);
      }

      // If the newly renamed file now has a top-level MIME type that
      // indicates a change from a generic file to an image, or the
      // reverse, then we need to swap use of the 'file' and 'image'
      // fields in the FolderShare entity. Both fields still reference
      // a File entity.
      $isForImage = self::isMimeTypeImage($mimeType);
      if ($this->isFile() === TRUE && $isForImage === TRUE) {
        // The file was a generic file, and now it is an image.
        $this->clearFileId();
        $this->setImageId($file->id());
        $this->setKind(self::IMAGE_KIND);
      }
      elseif ($this->isImage() === TRUE && $isForImage === FALSE) {
        // The file was an image, and now it is a generic file.
        $this->setFileId($file->id());
        $this->clearImageId();
        $this->setKind(self::FILE_KIND);
      }

      $this->save();
      unset($file);
    }
    elseif ($this->isMedia() === TRUE) {
      $media = $this->getMedia();
      if ($media !== NULL) {
        $media->setName($newName);
        $media->save();
        unset($media);
      }
    }
  }

}

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

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