From 04b3bb72c7062747e727e96e5450729521897872 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Thu, 4 Jul 2024 08:29:24 +0200 Subject: [PATCH] refs #487. Added image model and endpoint --- config/api_platform/Image.yaml | 30 ++++ config/services.yaml | 7 +- migrations/Version20240703090301.php | 35 ++++ ...grateSoftwareAndSoftwareProfileCommand.php | 57 +++++++ src/Dto/Input/ImageInput.php | 92 +++++++++++ src/Dto/Output/ImageOutput.php | 57 +++++++ src/Entity/Image.php | 149 ++++++++++++++++++ src/Entity/SoftwareProfile.php | 1 + src/Repository/ImageRepository.php | 18 +++ src/State/Processor/ImageProcessor.php | 68 ++++++++ .../Provider/HardwareProfileProvider.php | 9 +- src/State/Provider/HardwareProvider.php | 8 +- src/State/Provider/HardwareTypeProvider.php | 13 +- src/State/Provider/ImageProvider.php | 71 +++++++++ src/State/Provider/MenuProvider.php | 4 - .../Provider/OperativeSystemProvider.php | 11 +- .../Provider/OrganizationalUnitProvider.php | 13 +- src/State/Provider/PartitionProvider.php | 12 +- 18 files changed, 602 insertions(+), 53 deletions(-) create mode 100644 config/api_platform/Image.yaml create mode 100644 migrations/Version20240703090301.php create mode 100644 src/Command/Migration/MigrateSoftwareAndSoftwareProfileCommand.php create mode 100644 src/Dto/Input/ImageInput.php create mode 100644 src/Dto/Output/ImageOutput.php create mode 100644 src/Entity/Image.php create mode 100644 src/Repository/ImageRepository.php create mode 100644 src/State/Processor/ImageProcessor.php create mode 100644 src/State/Provider/ImageProvider.php diff --git a/config/api_platform/Image.yaml b/config/api_platform/Image.yaml new file mode 100644 index 0000000..37ab891 --- /dev/null +++ b/config/api_platform/Image.yaml @@ -0,0 +1,30 @@ +resources: + App\Entity\Image: + processor: App\State\Processor\ImageProcessor + input: App\Dto\Input\ImageInput + output: App\Dto\Output\ImageOutput + normalizationContext: + groups: ['default', 'image:read'] + denormalizationContext: + groups: ['image:write'] + operations: + ApiPlatform\Metadata\GetCollection: + provider: App\State\Provider\ImageProvider + filters: + - 'api_platform.filter.image.order' + - 'api_platform.filter.image.search' + ApiPlatform\Metadata\Get: + provider: App\State\Provider\ImageProvider + ApiPlatform\Metadata\Put: + provider: App\State\Provider\ImageProvider + ApiPlatform\Metadata\Patch: + provider: App\State\Provider\ImageProvider + ApiPlatform\Metadata\Post: ~ + ApiPlatform\Metadata\Delete: ~ + +properties: + App\Entity\Image: + id: + identifier: false + uuid: + identifier: true \ No newline at end of file diff --git a/config/services.yaml b/config/services.yaml index 6b82216..1c97d41 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -81,4 +81,9 @@ services: App\State\Provider\SoftwareProfileProvider: bind: $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' - $itemProvider: '@api_platform.doctrine.orm.state.item_provider' \ No newline at end of file + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + + App\State\Provider\ImageProvider: + bind: + $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' diff --git a/migrations/Version20240703090301.php b/migrations/Version20240703090301.php new file mode 100644 index 0000000..9a7588b --- /dev/null +++ b/migrations/Version20240703090301.php @@ -0,0 +1,35 @@ +addSql('CREATE TABLE image (id INT AUTO_INCREMENT NOT NULL, client_id INT NOT NULL, software_profile_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, description VARCHAR(255) DEFAULT NULL, comments VARCHAR(255) DEFAULT NULL, path VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, revision VARCHAR(255) DEFAULT NULL, info VARCHAR(255) DEFAULT NULL, size INT NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_C53D045FD17F50A6 (uuid), INDEX IDX_C53D045F19EB6921 (client_id), INDEX IDX_C53D045FED42A742 (software_profile_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE image ADD CONSTRAINT FK_C53D045F19EB6921 FOREIGN KEY (client_id) REFERENCES client (id)'); + $this->addSql('ALTER TABLE image ADD CONSTRAINT FK_C53D045FED42A742 FOREIGN KEY (software_profile_id) REFERENCES software_profile (id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE image DROP FOREIGN KEY FK_C53D045F19EB6921'); + $this->addSql('ALTER TABLE image DROP FOREIGN KEY FK_C53D045FED42A742'); + $this->addSql('DROP TABLE image'); + } +} diff --git a/src/Command/Migration/MigrateSoftwareAndSoftwareProfileCommand.php b/src/Command/Migration/MigrateSoftwareAndSoftwareProfileCommand.php new file mode 100644 index 0000000..6daf869 --- /dev/null +++ b/src/Command/Migration/MigrateSoftwareAndSoftwareProfileCommand.php @@ -0,0 +1,57 @@ +doctrine->getManager('og_1'); + + $organizationalUnitRepository = $this->entityManager->getRepository(OrganizationalUnit::class); + $softwareProfileRepository = $this->entityManager->getRepository(SoftwareProfile::class); + $softwareRepository = $this->entityManager->getRepository(Software::class); + + /** Obtener los perfiles software de la base de datos antigua **/ + $rsmSoftware = new ResultSetMapping(); + $rsmSoftware->addScalarResult('idtiposoftware', 'idtiposoftware'); + $rsmSoftware->addScalarResult('descripcion', 'descripcion'); + + $softwareQuery = $oldDatabaseEntityManager->createNativeQuery('SELECT idtiposoftware, descripcion FROM softwares', $rsmSoftware); + $softwareCollection = $softwareQuery->getResult(); + + foreach ($softwareCollection as $software) { + $softwareEntity = null; + $softwareEntity = $softwareRepository->findOneBy(['migrationId' => $software['idtiposoftware']]); + if (!$softwareEntity) { + $softwareEntity = new Software(); + $softwareEntity->setMigrationId($software['idtiposoftware']); + $softwareEntity->setName($software['descripcion']); + $softwareEntity->setDescription($software['descripcion']); + } + + $this->entityManager->persist($softwareEntity); + } + } +} \ No newline at end of file diff --git a/src/Dto/Input/ImageInput.php b/src/Dto/Input/ImageInput.php new file mode 100644 index 0000000..d6623ab --- /dev/null +++ b/src/Dto/Input/ImageInput.php @@ -0,0 +1,92 @@ +name = $image->getName(); + $this->description = $image->getDescription(); + $this->comments = $image->getComments(); + $this->type = $image->getType(); + $this->path = $image->getPath(); + $this->revision = $image->getRevision(); + $this->info = $image->getInfo(); + $this->size = $image->getSize(); + $this->client = new ClientOutput($image->getClient()); + $this->softwareProfile = new SoftwareProfileOutput($image->getSoftwareProfile()); + } + + public function createOrUpdateEntity(?Image $image = null): Image + { + if (!$image) { + $image = new Image(); + } + + $image->setName($this->name); + $image->setDescription($this->description); + $image->setComments($this->comments); + $image->setType($this->type); + $image->setPath($this->path); + $image->setRevision($this->revision); + $image->setInfo($this->info); + $image->setSize($this->size); + $image->setClient($this->client->getEntity()); + $image->setSoftwareProfile($this->softwareProfile->getEntity()); + + return $image; + } +} \ No newline at end of file diff --git a/src/Dto/Output/ImageOutput.php b/src/Dto/Output/ImageOutput.php new file mode 100644 index 0000000..f14e16a --- /dev/null +++ b/src/Dto/Output/ImageOutput.php @@ -0,0 +1,57 @@ +name = $image->getName(); + $this->description = $image->getDescription(); + $this->comments = $image->getComments(); + $this->type = $image->getType(); + $this->path = $image->getPath(); + $this->revision = $image->getRevision(); + $this->info = $image->getInfo(); + $this->size = $image->getSize(); + $this->clientOutput = new ClientOutput($image->getClient()); + $this->softwareProfile = new SoftwareProfileOutput($image->getSoftwareProfile()); + } +} \ No newline at end of file diff --git a/src/Entity/Image.php b/src/Entity/Image.php new file mode 100644 index 0000000..5d41052 --- /dev/null +++ b/src/Entity/Image.php @@ -0,0 +1,149 @@ +description; + } + + public function setDescription(?string $description): static + { + $this->description = $description; + + return $this; + } + + public function getComments(): ?string + { + return $this->comments; + } + + public function setComments(?string $comments): static + { + $this->comments = $comments; + + return $this; + } + + public function getPath(): ?string + { + return $this->path; + } + + public function setPath(string $path): static + { + $this->path = $path; + + return $this; + } + + public function getType(): ?string + { + return $this->type; + } + + public function setType(string $type): static + { + $this->type = $type; + + return $this; + } + + public function getRevision(): ?string + { + return $this->revision; + } + + public function setRevision(?string $revision): static + { + $this->revision = $revision; + + return $this; + } + + public function getInfo(): ?string + { + return $this->info; + } + + public function setInfo(?string $info): static + { + $this->info = $info; + + return $this; + } + + public function getSize(): ?int + { + return $this->size; + } + + public function setSize(int $size): static + { + $this->size = $size; + + return $this; + } + + public function getClient(): ?Client + { + return $this->client; + } + + public function setClient(?Client $client): static + { + $this->client = $client; + + return $this; + } + + public function getSoftwareProfile(): ?SoftwareProfile + { + return $this->softwareProfile; + } + + public function setSoftwareProfile(?SoftwareProfile $softwareProfile): static + { + $this->softwareProfile = $softwareProfile; + + return $this; + } +} diff --git a/src/Entity/SoftwareProfile.php b/src/Entity/SoftwareProfile.php index bc0f968..4ac75b8 100644 --- a/src/Entity/SoftwareProfile.php +++ b/src/Entity/SoftwareProfile.php @@ -20,6 +20,7 @@ class SoftwareProfile extends AbstractEntity #[ORM\JoinColumn(nullable: false)] private ?OrganizationalUnit $organizationalUnit = null; + /** * @var Collection */ diff --git a/src/Repository/ImageRepository.php b/src/Repository/ImageRepository.php new file mode 100644 index 0000000..b20b95b --- /dev/null +++ b/src/Repository/ImageRepository.php @@ -0,0 +1,18 @@ + + */ +class ImageRepository extends AbstractRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Image::class); + } +} diff --git a/src/State/Processor/ImageProcessor.php b/src/State/Processor/ImageProcessor.php new file mode 100644 index 0000000..8506b70 --- /dev/null +++ b/src/State/Processor/ImageProcessor.php @@ -0,0 +1,68 @@ +processCreateOrUpdate($data, $operation, $uriVariables, $context); + case $operation instanceof Delete: + return $this->processDelete($data, $operation, $uriVariables, $context); + } + } + + /** + * @throws \Exception + */ + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): ImageOutput + { + if (!($data instanceof ImageInput)) { + throw new \Exception(sprintf('data is not instance of %s', ImageInput::class)); + } + + $entity = null; + if (isset($uriVariables['uuid'])) { + $entity = $this->imageRepository->findOneByUuid($uriVariables['uuid']); + } + + $image = $data->createOrUpdateEntity($entity); + $this->validator->validate($image); + $this->imageRepository->save($image); + + return new ImageOutput($image); + } + + private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null + { + $user = $this->imageRepository->findOneByUuid($uriVariables['uuid']); + $this->imageRepository->delete($user); + + return null; + } +} diff --git a/src/State/Provider/HardwareProfileProvider.php b/src/State/Provider/HardwareProfileProvider.php index 241fda1..553b004 100644 --- a/src/State/Provider/HardwareProfileProvider.php +++ b/src/State/Provider/HardwareProfileProvider.php @@ -9,19 +9,16 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; -use App\Dto\Input\ClientInput; use App\Dto\Input\HardwareInput; use App\Dto\Input\HardwareProfileInput; -use App\Dto\Output\ClientOutput; -use App\Dto\Output\HardwareOutput; use App\Dto\Output\HardwareProfileOutput; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class HardwareProfileProvider implements ProviderInterface +readonly class HardwareProfileProvider implements ProviderInterface { public function __construct( - private readonly ProviderInterface $collectionProvider, - private readonly ProviderInterface $itemProvider + private ProviderInterface $collectionProvider, + private ProviderInterface $itemProvider ) { } diff --git a/src/State/Provider/HardwareProvider.php b/src/State/Provider/HardwareProvider.php index 0342d64..93c91af 100644 --- a/src/State/Provider/HardwareProvider.php +++ b/src/State/Provider/HardwareProvider.php @@ -9,17 +9,15 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; -use App\Dto\Input\ClientInput; use App\Dto\Input\HardwareInput; -use App\Dto\Output\ClientOutput; use App\Dto\Output\HardwareOutput; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class HardwareProvider implements ProviderInterface +readonly class HardwareProvider implements ProviderInterface { public function __construct( - private readonly ProviderInterface $collectionProvider, - private readonly ProviderInterface $itemProvider + private ProviderInterface $collectionProvider, + private ProviderInterface $itemProvider ) { } diff --git a/src/State/Provider/HardwareTypeProvider.php b/src/State/Provider/HardwareTypeProvider.php index f4e78cd..4a5835b 100644 --- a/src/State/Provider/HardwareTypeProvider.php +++ b/src/State/Provider/HardwareTypeProvider.php @@ -9,22 +9,15 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; -use App\Dto\Input\ClientInput; -use App\Dto\Input\HardwareInput; use App\Dto\Input\HardwareTypeInput; -use App\Dto\Input\OperativeSystemInput; -use App\Dto\Output\ClientOutput; -use App\Dto\Output\HardwareOutput; use App\Dto\Output\HardwareTypeOutput; -use App\Dto\Output\NetworkSettingsOutput; -use App\Dto\Output\OperativeSystemOutput; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class HardwareTypeProvider implements ProviderInterface +readonly class HardwareTypeProvider implements ProviderInterface { public function __construct( - private readonly ProviderInterface $collectionProvider, - private readonly ProviderInterface $itemProvider + private ProviderInterface $collectionProvider, + private ProviderInterface $itemProvider ) { } diff --git a/src/State/Provider/ImageProvider.php b/src/State/Provider/ImageProvider.php new file mode 100644 index 0000000..d807b4a --- /dev/null +++ b/src/State/Provider/ImageProvider.php @@ -0,0 +1,71 @@ +provideCollection($operation, $uriVariables, $context); + case $operation instanceof Patch: + case $operation instanceof Put: + return $this->provideInput($operation, $uriVariables, $context); + case $operation instanceof Get: + return $this->provideItem($operation, $uriVariables, $context); + } + } + + private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object + { + $paginator = $this->collectionProvider->provide($operation, $uriVariables, $context); + + $items = new \ArrayObject(); + foreach ($paginator->getIterator() as $item){ + $items[] = new ImageOutput($item); + } + + return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems()); + } + + public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + if (!$item) { + throw new NotFoundHttpException('Menu not found'); + } + + return new ImageOutput($item); + } + + public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + if (isset($uriVariables['uuid'])) { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + return $item !== null ? new ImageInput($item) : null; + } + + return new ImageInput(); + } +} diff --git a/src/State/Provider/MenuProvider.php b/src/State/Provider/MenuProvider.php index 71359bc..f82cbe6 100644 --- a/src/State/Provider/MenuProvider.php +++ b/src/State/Provider/MenuProvider.php @@ -9,11 +9,7 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; -use App\Dto\Input\ClientInput; -use App\Dto\Input\HardwareInput; use App\Dto\Input\MenuInput; -use App\Dto\Output\ClientOutput; -use App\Dto\Output\HardwareOutput; use App\Dto\Output\MenuOutput; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/src/State/Provider/OperativeSystemProvider.php b/src/State/Provider/OperativeSystemProvider.php index 6b0535c..9245913 100644 --- a/src/State/Provider/OperativeSystemProvider.php +++ b/src/State/Provider/OperativeSystemProvider.php @@ -9,20 +9,15 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; -use App\Dto\Input\ClientInput; -use App\Dto\Input\HardwareInput; use App\Dto\Input\OperativeSystemInput; -use App\Dto\Output\ClientOutput; -use App\Dto\Output\HardwareOutput; -use App\Dto\Output\NetworkSettingsOutput; use App\Dto\Output\OperativeSystemOutput; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class OperativeSystemProvider implements ProviderInterface +readonly class OperativeSystemProvider implements ProviderInterface { public function __construct( - private readonly ProviderInterface $collectionProvider, - private readonly ProviderInterface $itemProvider + private ProviderInterface $collectionProvider, + private ProviderInterface $itemProvider ) { } diff --git a/src/State/Provider/OrganizationalUnitProvider.php b/src/State/Provider/OrganizationalUnitProvider.php index 23703f9..25267a2 100644 --- a/src/State/Provider/OrganizationalUnitProvider.php +++ b/src/State/Provider/OrganizationalUnitProvider.php @@ -9,23 +9,16 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; -use App\Dto\Input\OrganizationalUnitClassroomGroupInput; -use App\Dto\Input\OrganizationalUnitClassroomInput; -use App\Dto\Input\OrganizationalUnitClientGroupInput; use App\Dto\Input\OrganizationalUnitInput; -use App\Dto\Input\OrganizationalUnitRootInput; -use App\Dto\Input\PartitionInput; -use App\Dto\Input\UserGroupInput; use App\Dto\Output\OrganizationalUnitOutput; use App\Entity\OrganizationalUnit; -use App\Model\OrganizationalUnitTypes; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class OrganizationalUnitProvider implements ProviderInterface +readonly class OrganizationalUnitProvider implements ProviderInterface { public function __construct( - private readonly ProviderInterface $collectionProvider, - private readonly ProviderInterface $itemProvider + private ProviderInterface $collectionProvider, + private ProviderInterface $itemProvider ) { } diff --git a/src/State/Provider/PartitionProvider.php b/src/State/Provider/PartitionProvider.php index ae6abe8..f4cfb17 100644 --- a/src/State/Provider/PartitionProvider.php +++ b/src/State/Provider/PartitionProvider.php @@ -9,21 +9,15 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Put; use ApiPlatform\State\Pagination\TraversablePaginator; use ApiPlatform\State\ProviderInterface; -use App\Dto\Input\ClientInput; -use App\Dto\Input\HardwareInput; -use App\Dto\Input\MenuInput; use App\Dto\Input\PartitionInput; -use App\Dto\Output\ClientOutput; -use App\Dto\Output\HardwareOutput; -use App\Dto\Output\MenuOutput; use App\Dto\Output\PartitionOutput; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -class PartitionProvider implements ProviderInterface +readonly class PartitionProvider implements ProviderInterface { public function __construct( - private readonly ProviderInterface $collectionProvider, - private readonly ProviderInterface $itemProvider + private ProviderInterface $collectionProvider, + private ProviderInterface $itemProvider ) { }