Skip to content

Commit

Permalink
[framework] admin can remove an image and upload a new one (#3166)
Browse files Browse the repository at this point in the history
  • Loading branch information
malyMiso committed Sep 3, 2024
2 parents d29d0ef + 77d4cf0 commit d947fb8
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 157 deletions.
97 changes: 11 additions & 86 deletions src/Component/Image/ImageFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Shopsys\FrameworkBundle\Component\Image;

use Doctrine\ORM\EntityManagerInterface;
use Exception;
use League\Flysystem\FilesystemOperator;
use League\Flysystem\MountManager;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -33,7 +32,7 @@ class ImageFacade
* @param \League\Flysystem\FilesystemOperator $filesystem
* @param \Shopsys\FrameworkBundle\Component\FileUpload\FileUpload $fileUpload
* @param \Shopsys\FrameworkBundle\Component\Image\ImageLocator $imageLocator
* @param \Shopsys\FrameworkBundle\Component\Image\ImageFactoryInterface $imageFactory
* @param \Shopsys\FrameworkBundle\Component\Image\ImageFactory $imageFactory
* @param \League\Flysystem\MountManager $mountManager
* @param \Psr\Log\LoggerInterface $logger
* @param \Shopsys\FrameworkBundle\Component\Cdn\CdnFacade $cdnFacade
Expand All @@ -47,7 +46,7 @@ public function __construct(
protected readonly FilesystemOperator $filesystem,
protected readonly FileUpload $fileUpload,
protected readonly ImageLocator $imageLocator,
protected readonly ImageFactoryInterface $imageFactory,
protected readonly ImageFactory $imageFactory,
protected readonly MountManager $mountManager,
protected readonly LoggerInterface $logger,
protected readonly CdnFacade $cdnFacade,
Expand All @@ -65,62 +64,25 @@ public function manageImages(object $entity, ImageUploadData $imageUploadData, ?
$imageEntityConfig = $this->imageConfig->getImageEntityConfig($entity);
$uploadedFiles = $imageUploadData->uploadedFiles;
$orderedImages = $imageUploadData->orderedImages;
$imagesToDelete = $imageUploadData->imagesToDelete;

if ($imageEntityConfig->isMultiple($type) === false) {
if (count($orderedImages) > 1) {
array_shift($orderedImages);
$this->deleteImages($entity, $orderedImages);
if (count($uploadedFiles) > 0) {
$imagesToDelete = $orderedImages;
}
$this->uploadImage($entity, $imageUploadData->uploadedFilenames, $uploadedFiles, $type);

if (count($uploadedFiles) === 0) {
$this->saveImagesPathnames($imageUploadData);
if (count($orderedImages) > 1) {
array_shift($orderedImages);
$imagesToDelete = $orderedImages;
}
} else {
$this->saveImageOrdering($orderedImages);
$this->saveImagesPathnames($imageUploadData);
$this->uploadImages($entity, $imageUploadData->uploadedFilenames, $uploadedFiles, $type);
}

$this->deleteImages($entity, $imageUploadData->imagesToDelete);
}

/**
* @param object $entity
* @param array<int, array<string,string>> $namesIndexedByImageIdAndLocale
* @param array<int, string> $temporaryFilenamesIndexedByImageId
* @param string|null $type
*/
protected function uploadImage(
object $entity,
array $namesIndexedByImageIdAndLocale,
array $temporaryFilenamesIndexedByImageId,
?string $type,
): void {
if (count($temporaryFilenamesIndexedByImageId) > 0) {
$imageEntityConfig = $this->imageConfig->getImageEntityConfig($entity);
$entityId = $this->getEntityId($entity);
$oldImage = $this->imageRepository->findImageByEntity(
$imageEntityConfig->getEntityName(),
$entityId,
$type,
);

if ($oldImage !== null) {
$this->em->remove($oldImage);
}

$newImage = $this->imageFactory->create(
$imageEntityConfig->getEntityName(),
$entityId,
array_pop($namesIndexedByImageIdAndLocale),
array_pop($temporaryFilenamesIndexedByImageId),
$type,
);
$this->em->persist($newImage);
$this->saveImagesPathnames($imageUploadData);
$this->uploadImages($entity, $imageUploadData->uploadedFilenames, $uploadedFiles, $type);

$this->em->flush();
}
$this->deleteImages($entity, $imagesToDelete);
}

/**
Expand Down Expand Up @@ -301,43 +263,6 @@ public function getById(int $imageId): Image
return $this->imageRepository->getById($imageId);
}

/**
* @param object $sourceEntity
* @param object $targetEntity
*/
public function copyImages(object $sourceEntity, object $targetEntity): void
{
$sourceImages = $this->getAllImagesByEntity($sourceEntity);

foreach ($sourceImages as $sourceImage) {
try {
$this->mountManager->copy(
'main://' . $this->imageLocator->getAbsoluteImageFilepath(
$sourceImage,
),
'main://' . TransformString::removeDriveLetterFromPath(
$this->fileUpload->getTemporaryFilepath($sourceImage->getFilename()),
),
);
} catch (Exception $exception) {
$this->logger->error('Image could not be copied', [$exception]);

continue;
}

$targetImage = $this->imageFactory->create(
$this->imageConfig->getImageEntityConfig($targetEntity)->getEntityName(),
$this->getEntityId($targetEntity),
$sourceImage->getNames(),
$sourceImage->getFilename(),
$sourceImage->getType(),
);

$this->em->persist($targetImage);
}
$this->em->flush();
}

/**
* @param \Shopsys\FrameworkBundle\Component\Image\Image[] $orderedImages
*/
Expand Down
6 changes: 3 additions & 3 deletions src/Component/Image/ImageFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Shopsys\FrameworkBundle\Component\Image\Exception\EntityMultipleImageException;
use Shopsys\FrameworkBundle\Component\Image\Processing\ImageProcessor;

class ImageFactory implements ImageFactoryInterface
class ImageFactory
{
/**
* @param \Shopsys\FrameworkBundle\Component\Image\Processing\ImageProcessor $imageProcessor
Expand All @@ -32,7 +32,7 @@ public function __construct(
* @param string|null $type
* @return \Shopsys\FrameworkBundle\Component\Image\Image
*/
public function create(
protected function create(
string $entityName,
int $entityId,
array $namesIndexedByLocale,
Expand Down Expand Up @@ -62,7 +62,7 @@ public function createMultiple(
array $temporaryFilenames,
?string $type,
): array {
if (!$imageEntityConfig->isMultiple($type)) {
if (!$imageEntityConfig->isMultiple($type) && count($temporaryFilenames) > 1) {
$message = 'Entity ' . $imageEntityConfig->getEntityClass()
. ' is not allowed to have multiple images for type ' . ($type ?: 'NULL');

Expand Down
42 changes: 0 additions & 42 deletions src/Component/Image/ImageFactoryInterface.php

This file was deleted.

3 changes: 0 additions & 3 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,6 @@ services:
Shopsys\FrameworkBundle\Component\Image\ImageFacade:
arguments: ['%shopsys.image_url_prefix%']

Shopsys\FrameworkBundle\Component\Image\ImageFactoryInterface:
alias: Shopsys\FrameworkBundle\Component\Image\ImageFactory

Shopsys\FrameworkBundle\Component\Image\ImageLocator:
arguments: ['%shopsys.image_dir%']

Expand Down
24 changes: 1 addition & 23 deletions tests/Unit/Component/Image/ImageFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use Shopsys\FrameworkBundle\Component\FileUpload\FileUpload;
use Shopsys\FrameworkBundle\Component\Image\Config\ImageEntityConfig;
use Shopsys\FrameworkBundle\Component\Image\Exception\EntityMultipleImageException;
use Shopsys\FrameworkBundle\Component\Image\Image;
use Shopsys\FrameworkBundle\Component\Image\ImageFactory;
use Shopsys\FrameworkBundle\Component\Image\ImageRepository;
use Shopsys\FrameworkBundle\Component\Image\Processing\ImageProcessor;
Expand All @@ -31,7 +30,7 @@ public function testCreateMultipleException(): void
$imageFactory = new ImageFactory($imageProcessorMock, $this->getFileUpload(), new EntityNameResolver([]));

$this->expectException(EntityMultipleImageException::class);
$imageFactory->createMultiple($imageEntityConfig, 1, [], [], 'type');
$imageFactory->createMultiple($imageEntityConfig, 1, ['test1.png', 'test2.png'], ['test1_tmp.png', 'test2_tmp.png'], 'type');
}

public function testCreateMultiple(): void
Expand Down Expand Up @@ -61,27 +60,6 @@ public function testCreateMultiple(): void
}
}

public function testCreate(): void
{
$imageEntityConfig = new ImageEntityConfig('entityName', 'entityClass', [], ['type' => true]);
$filename = 'filename.jpg';

$imageProcessorMock = $this->getMockBuilder(ImageProcessor::class)
->disableOriginalConstructor()
->onlyMethods(['convertToShopFormatAndGetNewFilename'])
->getMock();
$imageProcessorMock->expects($this->any())->method('convertToShopFormatAndGetNewFilename')->willReturn(
$filename,
);

$imageFactory = new ImageFactory($imageProcessorMock, $this->getFileUpload(), new EntityNameResolver([]));
$image = $imageFactory->create($imageEntityConfig->getEntityName(), 1, [], $filename, 'type');
$temporaryFiles = $image->getTemporaryFilesForUpload();

$this->assertInstanceOf(Image::class, $image);
$this->assertSame($filename, array_pop($temporaryFiles)->getTemporaryFilename());
}

/**
* @return \Shopsys\FrameworkBundle\Component\FileUpload\FileUpload
*/
Expand Down

0 comments on commit d947fb8

Please sign in to comment.