Skip to content

Commit

Permalink
Asset sys API update. Now supports custom data and could generate pub…
Browse files Browse the repository at this point in the history
…lic route for asset
  • Loading branch information
TomasHermanek committed Jan 16, 2024
1 parent 7df3f86 commit 61b85c9
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 32 deletions.
12 changes: 12 additions & 0 deletions src/Domain/Asset/AssetSysFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use AnzuSystems\CoreDamBundle\Domain\AssetFile\AssetFileManagerProvider;
use AnzuSystems\CoreDamBundle\Domain\AssetFile\AssetFileMessageDispatcher;
use AnzuSystems\CoreDamBundle\Domain\AssetFile\AssetFileStatusFacadeProvider;
use AnzuSystems\CoreDamBundle\Domain\AssetFileRoute\AssetFileRouteFacade;
use AnzuSystems\CoreDamBundle\Domain\AssetMetadata\AssetMetadataManager;
use AnzuSystems\CoreDamBundle\Entity\AssetFile;
use AnzuSystems\CoreDamBundle\Exception\InvalidMimeTypeException;
use AnzuSystems\CoreDamBundle\FileSystem\FileSystemProvider;
Expand All @@ -28,6 +30,8 @@ public function __construct(
private readonly AssetFileMessageDispatcher $assetFileMessageDispatcher,
private readonly AssetFileStatusFacadeProvider $facadeProvider,
private readonly FileSystemProvider $fileSystemProvider,
private readonly AssetFileRouteFacade $assetFileRouteFacade,
private readonly AssetMetadataManager $assetMetadataManager,
) {
}

Expand All @@ -41,9 +45,17 @@ public function createFromDto(AssetFileSysCreateDto $dto): AssetFile
{
$this->validator->validate($dto);
$assetFile = $this->assetSysFactory->createFromDto($dto);
$this->assetMetadataManager->updateFromCustomData($assetFile->getAsset(), $dto->getCustomData());
$this->facadeProvider->getStatusFacade($assetFile)->storeAndProcess($assetFile);
$this->fileSystemProvider->getTmpFileSystem()->clearPaths();

if (
$dto->isGeneratePublicRoute() &&
empty($assetFile->getAssetAttributes()->getOriginAssetId())
) {
$this->assetFileRouteFacade->makePublicAssetFile($assetFile);
}

return $assetFile;
}
}
40 changes: 20 additions & 20 deletions src/Domain/AssetFile/AbstractAssetFileFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,26 @@ public function createFromExternalProvider(
return $this->assetFileManager->create($assetFile, false);
}

/**
* @throws FilesystemException
* @throws InvalidMimeTypeException
*/
public function getTypeFromPath(string $storageName, string $filePath): AssetType
{
$fileSystem = $this->fileSystemProvider->getFileSystemByStorageName($storageName);
if (null === $fileSystem) {
throw new DomainException(sprintf('File system not configured (%s)', $storageName));
}

if (false === $fileSystem->has($filePath)) {
throw new DomainException(sprintf('File (%s) not exists in storage (%s)', $filePath, $storageName));
}

return $this->getTypeFromMime(
$fileSystem->mimeType($filePath)
);
}

/**
* @return T
*
Expand Down Expand Up @@ -240,26 +260,6 @@ protected function createBlankDocument(AssetLicence $licence, ?string $id = null
;
}

/**
* @throws FilesystemException
* @throws InvalidMimeTypeException
*/
protected function getTypeFromPath(string $storageName, string $filePath): AssetType
{
$fileSystem = $this->fileSystemProvider->getFileSystemByStorageName($storageName);
if (null === $fileSystem) {
throw new DomainException(sprintf('File system not configured (%s)', $storageName));
}

if (false === $fileSystem->has($filePath)) {
throw new DomainException(sprintf('File (%s) not exists in storage (%s)', $filePath, $storageName));
}

return $this->getTypeFromMime(
$fileSystem->mimeType($filePath)
);
}

/**
* @throws InvalidMimeTypeException
*/
Expand Down
7 changes: 7 additions & 0 deletions src/Domain/AssetFileRoute/AssetFileRouteFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ public function __construct(
) {
}

public function makePublicAssetFile(AssetFile $assetFile, AssetFileRouteAdmCreateDto $dto = null): AssetFileRoute
{
return $assetFile instanceof ImageFile
? $this->makeImagePublic($assetFile)
: $this->makePublicFromDto($assetFile, $dto ?? new AssetFileRouteAdmCreateDto());
}

/**
* @throws ForbiddenOperationException
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Domain/AssetMetadata/AssetMetadataBulkFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function bulkUpdate(Collection $list): Collection
$this->checkPermissions($updateDto);
$asset = $updateDto->getAsset();

$this->assetMetadataManager->updateFromMetadataBulkDto($asset, $updateDto, false);
$this->assetMetadataManager->updateFromCustomData($asset, $updateDto->getCustomData(), false);
$updated[] = FormProvidableMetadataBulkUpdateDto::getInstance(
asset: $this->assetManager->updateFromMetadataBulkDto($asset, $updateDto, false)
);
Expand Down
9 changes: 4 additions & 5 deletions src/Domain/AssetMetadata/AssetMetadataManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ public function create(AssetMetadata $assetMetadata, bool $flush = true): AssetM
/**
* @throws NonUniqueResultException
*/
public function updateFromMetadataBulkDto(
public function updateFromCustomData(
Asset $asset,
FormProvidableMetadataBulkUpdateDto $dto,
array $customData,
bool $flush = true
): AssetMetadata {
$assetMetadata = $asset->getMetadata();
$this->trackModification($assetMetadata);
$assetMetadata->setCustomData($this->updateCustomData($asset, $dto));
$assetMetadata->setCustomData($this->updateCustomData($asset, $customData));
$this->flush($flush);

return $assetMetadata;
Expand All @@ -59,12 +59,11 @@ public function removeSuggestions(AssetMetadata $assetMetadata, bool $flush = tr
/**
* @throws NonUniqueResultException
*/
private function updateCustomData(Asset $asset, FormProvidableMetadataBulkUpdateDto $dto): array
private function updateCustomData(Asset $asset, array $newCustomData): array
{
$form = $this->customFormProvider->provideForm($asset);

$oldCustomData = $asset->getMetadata()->getCustomData();
$newCustomData = $dto->getCustomData();

foreach ($form->getElements() as $element) {
if ($element->getAttributes()->isReadonly()) {
Expand Down
26 changes: 26 additions & 0 deletions src/Model/Dto/AssetFile/AssetCustomFormProvidableDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace AnzuSystems\CoreDamBundle\Model\Dto\AssetFile;

use AnzuSystems\CoreDamBundle\Entity\ExtSystem;
use AnzuSystems\CoreDamBundle\Entity\Interfaces\AssetCustomFormProvidableInterface;
use AnzuSystems\CoreDamBundle\Model\Enum\AssetType;

final readonly class AssetCustomFormProvidableDto implements AssetCustomFormProvidableInterface
{
public function __construct(
private AssetType $assetType,
private ExtSystem $extSystem,
) {
}

public function getAssetType(): AssetType
{
return $this->assetType;
}

public function getExtSystem(): ExtSystem
{
return $this->extSystem;
}
}
41 changes: 39 additions & 2 deletions src/Model/Dto/AssetFile/AssetFileSysCreateDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,27 @@
use AnzuSystems\CommonBundle\Exception\ValidationException;
use AnzuSystems\CoreDamBundle\Entity\AssetLicence;
use AnzuSystems\CoreDamBundle\Entity\ExtSystem;
use AnzuSystems\CoreDamBundle\Entity\Interfaces\CustomDataInterface;
use AnzuSystems\CoreDamBundle\Entity\Interfaces\ExtSystemInterface;
use AnzuSystems\CoreDamBundle\Model\Enum\AssetType;
use AnzuSystems\CoreDamBundle\Validator\Constraints as AppAssert;
use AnzuSystems\SerializerBundle\Attributes\Serialize;
use AnzuSystems\SerializerBundle\Handler\Handlers\EntityIdHandler;
use Symfony\Component\Validator\Constraints as Assert;

final class AssetFileSysCreateDto implements ExtSystemInterface
#[AppAssert\AssetFileSysCreate]
final class AssetFileSysCreateDto implements ExtSystemInterface, CustomDataInterface
{
#[Serialize]
#[Assert\NotBlank(message: ValidationException::ERROR_FIELD_EMPTY)]
#[Assert\Length(max: 192, maxMessage: ValidationException::ERROR_FIELD_LENGTH_MAX)]
private string $path;
private string $path = '';

#[Serialize]
private array $customData = [];

#[Serialize]
private bool $generatePublicRoute = false;

#[Serialize(handler: EntityIdHandler::class)]
#[Assert\NotBlank(message: ValidationException::ERROR_FIELD_EMPTY)]
Expand Down Expand Up @@ -49,4 +59,31 @@ public function getExtSystem(): ExtSystem
{
return $this->licence->getExtSystem();
}

public function getCustomData(): array
{
return $this->customData;
}

public function setCustomData(array $customData): static
{
$this->customData = $customData;

return $this;
}

public function isGeneratePublicRoute(): bool
{
return $this->generatePublicRoute;
}

public function setGeneratePublicRoute(bool $generatePublicRoute): void
{
$this->generatePublicRoute = $generatePublicRoute;
}

public function getAssetType(): AssetType
{
return AssetType::Image;
}
}
7 changes: 7 additions & 0 deletions src/Model/Dto/AssetFile/AssetFileSysDetailDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace AnzuSystems\CoreDamBundle\Model\Dto\AssetFile;

use AnzuSystems\CoreDamBundle\Entity\AssetFile;
use AnzuSystems\CoreDamBundle\Entity\AssetFileMetadata;
use AnzuSystems\CoreDamBundle\Model\Dto\AbstractEntityDto;
use AnzuSystems\CoreDamBundle\Model\Enum\AssetFileProcessStatus;
use AnzuSystems\CoreDamBundle\Model\Enum\AssetType;
Expand Down Expand Up @@ -55,4 +56,10 @@ public function getAssetType(): AssetType
{
return $this->assetFile->getAssetType();
}

#[Serialize(strategy: Serialize::KEYS_VALUES)]
public function getCustomData(): array
{
return $this->assetFile->getAsset()->getMetadata()->getCustomData();
}
}
17 changes: 17 additions & 0 deletions src/Validator/Constraints/AssetFileSysCreate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace AnzuSystems\CoreDamBundle\Validator\Constraints;

use Attribute;
use Symfony\Component\Validator\Constraint;

#[Attribute]
final class AssetFileSysCreate extends Constraint
{
public function getTargets(): string
{
return self::CLASS_CONSTRAINT;
}
}
71 changes: 71 additions & 0 deletions src/Validator/Constraints/AssetFileSysCreateValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace AnzuSystems\CoreDamBundle\Validator\Constraints;

use AnzuSystems\CommonBundle\Exception\ValidationException;
use AnzuSystems\CoreDamBundle\Domain\AssetFile\AssetFileFactory;
use AnzuSystems\CoreDamBundle\Domain\Configuration\ExtSystemConfigurationProvider;
use AnzuSystems\CoreDamBundle\Exception\DomainException;
use AnzuSystems\CoreDamBundle\Exception\InvalidMimeTypeException;
use AnzuSystems\CoreDamBundle\Model\Dto\AssetFile\AssetCustomFormProvidableDto;
use AnzuSystems\CoreDamBundle\Model\Dto\AssetFile\AssetFileSysCreateDto;
use Doctrine\ORM\NonUniqueResultException;
use League\Flysystem\FilesystemException;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Contracts\Service\Attribute\Required;

final class AssetFileSysCreateValidator extends CustomDataValidator
{
private ExtSystemConfigurationProvider $configurationProvider;
private AssetFileFactory $assetFileFactory;

#[Required]
public function setConfigurationProvider(ExtSystemConfigurationProvider $configurationProvider): void
{
$this->configurationProvider = $configurationProvider;
}

#[Required]
public function setAssetFileFactory(AssetFileFactory $assetFileFactory): void
{
$this->assetFileFactory = $assetFileFactory;
}

/**
* @throws InvalidMimeTypeException
* @throws FilesystemException
* @throws NonUniqueResultException
*/
public function validate(mixed $value, Constraint $constraint): void
{
if (false === ($value instanceof AssetFileSysCreateDto)) {
throw new UnexpectedTypeException($constraint, AssetFileSysCreateDto::class);
}

$configuration = $this->configurationProvider->getExtSystemConfiguration($value->getExtSystem()->getSlug());

try {
$assetType = $this->assetFileFactory->getTypeFromPath($configuration->getExtStorage(), $value->getPath());
} catch (DomainException) {
$this->context
->buildViolation(ValidationException::ERROR_FIELD_INVALID)
->atPath('path')
->addViolation();

return;
}

$this->validateForm(
form: $this->customFormProvider->provideForm(
(new AssetCustomFormProvidableDto(
assetType: $assetType,
extSystem: $value->getExtSystem()
))
),
value: $value
);
}
}
14 changes: 10 additions & 4 deletions src/Validator/Constraints/CustomDataValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

final class CustomDataValidator extends ConstraintValidator
class CustomDataValidator extends ConstraintValidator
{
private const PATH_TEMPLATE = 'customData.%s';

private readonly iterable $validators;

public function __construct(
private readonly CustomFormProvider $customFormProvider,
protected readonly CustomFormProvider $customFormProvider,
#[TaggedIterator(tag: ElementValidatorInterface::class, indexAttribute: 'key')]
iterable $validators,
) {
Expand All @@ -48,9 +48,15 @@ public function validate(mixed $value, Constraint $constraint): void
throw new UnexpectedTypeException($constraint, ResourceCustomFormProvidableInterface::class);
}

$form = $this->customFormProvider->provideForm($value);
$customData = $value->getCustomData();
$this->validateForm(
form: $this->customFormProvider->provideForm($value),
value: $value
);
}

protected function validateForm(CustomForm $form, CustomDataInterface $value): void
{
$customData = $value->getCustomData();
foreach ($form->getElements() as $element) {
if ($element->getAttributes()->isReadonly()) {
continue;
Expand Down

0 comments on commit 61b85c9

Please sign in to comment.