diff --git a/app/config/api/raw/demo.yml b/app/config/api/raw/demo.yml index 7a47c94..27e6260 100755 --- a/app/config/api/raw/demo.yml +++ b/app/config/api/raw/demo.yml @@ -37,3 +37,7 @@ Demo\Domain\Model\Administrator\Administrator: ROLE_ADMIN: id: neq: 1 + +Demo\Domain\Model\Service\Service: ~ + + diff --git a/app/config/packages/orm_target_entities.yml b/app/config/packages/orm_target_entities.yml index edc57a5..2aec2a5 100755 --- a/app/config/packages/orm_target_entities.yml +++ b/app/config/packages/orm_target_entities.yml @@ -8,4 +8,6 @@ doctrine: Ivoz\Core\Domain\Model\Changelog\ChangelogInterface: Ivoz\Core\Domain\Model\Changelog\Changelog Demo\Domain\Model\Timezone\TimezoneInterface: - Demo\Domain\Model\Timezone\Timezone \ No newline at end of file + Demo\Domain\Model\Timezone\Timezone + Demo\Domain\Model\Service\ServiceInterface: + Demo\Domain\Model\Service\Service \ No newline at end of file diff --git a/app/migrations/Version20240206172427.php b/app/migrations/Version20240206172427.php new file mode 100644 index 0000000..6eba7f2 --- /dev/null +++ b/app/migrations/Version20240206172427.php @@ -0,0 +1,44 @@ +addSql('CREATE TABLE Services (id INT UNSIGNED AUTO_INCREMENT NOT NULL, iden VARCHAR(50) NOT NULL, UNIQUE INDEX services_iden (iden), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->populateFactoryServices(); + } + + private function populateFactoryServices() + { + $factoryServices = [ + 'Recording', 'Voicemail', 'Queues' + ]; + + foreach ($factoryServices as $srv) { + $this->addSql('INSERT INTO Services(iden) VALUES(:srv)', ['srv' => $srv]); + } + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE Services'); + } +} diff --git a/app/src/Demo/Domain/Model/Service/Service.php b/app/src/Demo/Domain/Model/Service/Service.php new file mode 100644 index 0000000..60dc9f2 --- /dev/null +++ b/app/src/Demo/Domain/Model/Service/Service.php @@ -0,0 +1,31 @@ + + */ + public function getChangeSet(): array + { + return parent::getChangeSet(); + } + + /** + * Get id + * @codeCoverageIgnore + */ + public function getId(): null|int + { + return $this->id; + } +} diff --git a/app/src/Demo/Domain/Model/Service/ServiceAbstract.php b/app/src/Demo/Domain/Model/Service/ServiceAbstract.php new file mode 100644 index 0000000..31661dc --- /dev/null +++ b/app/src/Demo/Domain/Model/Service/ServiceAbstract.php @@ -0,0 +1,161 @@ +setIden($iden); + } + + abstract public function getId(): null|string|int; + + public function __toString(): string + { + return sprintf( + "%s#%s", + "Service", + (string) $this->getId() + ); + } + + /** + * @throws \Exception + */ + protected function sanitizeValues(): void + { + } + + /** + * @param int | null $id + */ + public static function createDto($id = null): ServiceDto + { + return new ServiceDto($id); + } + + /** + * @internal use EntityTools instead + * @param null|ServiceInterface $entity + */ + public static function entityToDto(?EntityInterface $entity, int $depth = 0): ?ServiceDto + { + if (!$entity) { + return null; + } + + Assertion::isInstanceOf($entity, ServiceInterface::class); + + if ($depth < 1) { + return static::createDto($entity->getId()); + } + + if ($entity instanceof \Doctrine\ORM\Proxy\Proxy && !$entity->__isInitialized()) { + return static::createDto($entity->getId()); + } + + $dto = $entity->toDto($depth - 1); + + return $dto; + } + + /** + * Factory method + * @internal use EntityTools instead + * @param ServiceDto $dto + */ + public static function fromDto( + DataTransferObjectInterface $dto, + ForeignKeyTransformerInterface $fkTransformer + ): static { + Assertion::isInstanceOf($dto, ServiceDto::class); + $iden = $dto->getIden(); + Assertion::notNull($iden, 'getIden value is null, but non null value was expected.'); + + $self = new static( + $iden + ); + + ; + + $self->initChangelog(); + + return $self; + } + + /** + * @internal use EntityTools instead + * @param ServiceDto $dto + */ + public function updateFromDto( + DataTransferObjectInterface $dto, + ForeignKeyTransformerInterface $fkTransformer + ): static { + Assertion::isInstanceOf($dto, ServiceDto::class); + + $iden = $dto->getIden(); + Assertion::notNull($iden, 'getIden value is null, but non null value was expected.'); + + $this + ->setIden($iden); + + return $this; + } + + /** + * @internal use EntityTools instead + */ + public function toDto(int $depth = 0): ServiceDto + { + return self::createDto() + ->setIden(self::getIden()); + } + + /** + * @return array + */ + protected function __toArray(): array + { + return [ + 'iden' => self::getIden() + ]; + } + + protected function setIden(string $iden): static + { + Assertion::maxLength($iden, 50, 'iden value "%s" is too long, it should have no more than %d characters, but has %d characters.'); + + $this->iden = $iden; + + return $this; + } + + public function getIden(): string + { + return $this->iden; + } +} diff --git a/app/src/Demo/Domain/Model/Service/ServiceDto.php b/app/src/Demo/Domain/Model/Service/ServiceDto.php new file mode 100644 index 0000000..4c40734 --- /dev/null +++ b/app/src/Demo/Domain/Model/Service/ServiceDto.php @@ -0,0 +1,7 @@ +setId($id); + } + + /** + * @inheritdoc + */ + public static function getPropertyMap(string $context = '', string $role = null): array + { + if ($context === self::CONTEXT_COLLECTION) { + return ['id' => 'id']; + } + + return [ + 'iden' => 'iden', + 'id' => 'id' + ]; + } + + /** + * @return array + */ + public function toArray(bool $hideSensitiveData = false): array + { + $response = [ + 'iden' => $this->getIden(), + 'id' => $this->getId() + ]; + + if (!$hideSensitiveData) { + return $response; + } + + foreach ($this->sensitiveFields as $sensitiveField) { + if (!array_key_exists($sensitiveField, $response)) { + throw new \Exception($sensitiveField . ' field was not found'); + } + $response[$sensitiveField] = '*****'; + } + + return $response; + } + + public function setIden(string $iden): static + { + $this->iden = $iden; + + return $this; + } + + public function getIden(): ?string + { + return $this->iden; + } + + /** + * @param int|null $id + */ + public function setId($id): static + { + $this->id = $id; + + return $this; + } + + public function getId(): ?int + { + return $this->id; + } +} diff --git a/app/src/Demo/Domain/Model/Service/ServiceInterface.php b/app/src/Demo/Domain/Model/Service/ServiceInterface.php new file mode 100644 index 0000000..80ab8c6 --- /dev/null +++ b/app/src/Demo/Domain/Model/Service/ServiceInterface.php @@ -0,0 +1,51 @@ + + */ + public function getChangeSet(): array; + + /** + * Get id + * @codeCoverageIgnore + */ + public function getId(): ?int; + + /** + * @param int | null $id + */ + public static function createDto($id = null): ServiceDto; + + /** + * @internal use EntityTools instead + * @param null|ServiceInterface $entity + */ + public static function entityToDto(?EntityInterface $entity, int $depth = 0): ?ServiceDto; + + /** + * Factory method + * @internal use EntityTools instead + * @param ServiceDto $dto + */ + public static function fromDto(DataTransferObjectInterface $dto, ForeignKeyTransformerInterface $fkTransformer): static; + + /** + * @internal use EntityTools instead + */ + public function toDto(int $depth = 0): ServiceDto; + + public function getIden(): string; +} diff --git a/app/src/Demo/Domain/Model/Service/ServiceRepository.php b/app/src/Demo/Domain/Model/Service/ServiceRepository.php new file mode 100644 index 0000000..e1f071d --- /dev/null +++ b/app/src/Demo/Domain/Model/Service/ServiceRepository.php @@ -0,0 +1,12 @@ + + */ +interface ServiceRepository extends RepositoryInterface +{ +} diff --git a/app/src/Demo/Domain/Model/Service/ServiceTrait.php b/app/src/Demo/Domain/Model/Service/ServiceTrait.php new file mode 100644 index 0000000..390cc47 --- /dev/null +++ b/app/src/Demo/Domain/Model/Service/ServiceTrait.php @@ -0,0 +1,85 @@ +sanitizeValues(); + if ($dto->getId()) { + $self->id = $dto->getId(); + $self->initChangelog(); + } + + return $self; + } + + /** + * @internal use EntityTools instead + * @param ServiceDto $dto + */ + public function updateFromDto( + DataTransferObjectInterface $dto, + ForeignKeyTransformerInterface $fkTransformer + ): static { + parent::updateFromDto($dto, $fkTransformer); + + $this->sanitizeValues(); + + return $this; + } + + /** + * @internal use EntityTools instead + */ + public function toDto(int $depth = 0): ServiceDto + { + $dto = parent::toDto($depth); + return $dto + ->setId($this->getId()); + } + + /** + * @return array + */ + protected function __toArray(): array + { + return parent::__toArray() + [ + 'id' => self::getId() + ]; + } +} diff --git a/app/src/Demo/Domain/Service/Service/AvoidUpdateDelete.php b/app/src/Demo/Domain/Service/Service/AvoidUpdateDelete.php new file mode 100644 index 0000000..6dd6270 --- /dev/null +++ b/app/src/Demo/Domain/Service/Service/AvoidUpdateDelete.php @@ -0,0 +1,40 @@ + + */ + public static function getSubscribedEvents(): array + { + return [ + self::EVENT_PRE_PERSIST => self::PRE_PERSIST_PRIORITY, + self::EVENT_PRE_REMOVE => self::PRE_REMOVE_PRIORITY + ]; + } + + public function execute(ServiceInterface $service): void + { + if ($service->isNew()) { + return; + } + + $iden = $service->getInitialValue('iden'); + + if (in_array($iden, Service::BUILTIN_SERVICES)) { + $msg = $service->hasBeenDeleted() + ? 'Service ' . $iden . 'can’t be deleted' + : 'Service ' . $iden . 'can’t be edited'; + + throw new \DomainException($msg); + } + } +} \ No newline at end of file diff --git a/app/src/Demo/Domain/Service/Service/ServiceLifecycleEventHandlerInterface.php b/app/src/Demo/Domain/Service/Service/ServiceLifecycleEventHandlerInterface.php new file mode 100644 index 0000000..c3c20c7 --- /dev/null +++ b/app/src/Demo/Domain/Service/Service/ServiceLifecycleEventHandlerInterface.php @@ -0,0 +1,11 @@ + $bindedBaseServices */ + public static $bindedBaseServices = [ + "pre_persist" => + [ + \Demo\Domain\Service\Service\AvoidUpdateDelete::class => 100, + ], + "pre_remove" => + [ + \Demo\Domain\Service\Service\AvoidUpdateDelete::class => 100, + ], + ]; + + protected function addService(string $event, LifecycleEventHandlerInterface|DomainEventSubscriberInterface $service): void + { + Assertion::isInstanceOf($service, ServiceLifecycleEventHandlerInterface::class); + $this->services[$event][] = $service; + } +} \ No newline at end of file diff --git a/app/src/Demo/Infrastructure/Persistence/Doctrine/Mapping/Service.Service.orm.xml b/app/src/Demo/Infrastructure/Persistence/Doctrine/Mapping/Service.Service.orm.xml new file mode 100644 index 0000000..f339f85 --- /dev/null +++ b/app/src/Demo/Infrastructure/Persistence/Doctrine/Mapping/Service.Service.orm.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/src/Demo/Infrastructure/Persistence/Doctrine/Mapping/Service.ServiceAbstract.orm.xml b/app/src/Demo/Infrastructure/Persistence/Doctrine/Mapping/Service.ServiceAbstract.orm.xml new file mode 100644 index 0000000..8fe8e73 --- /dev/null +++ b/app/src/Demo/Infrastructure/Persistence/Doctrine/Mapping/Service.ServiceAbstract.orm.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/app/src/Demo/Infrastructure/Persistence/Doctrine/ServiceDoctrineRepository.php b/app/src/Demo/Infrastructure/Persistence/Doctrine/ServiceDoctrineRepository.php new file mode 100644 index 0000000..495719e --- /dev/null +++ b/app/src/Demo/Infrastructure/Persistence/Doctrine/ServiceDoctrineRepository.php @@ -0,0 +1,33 @@ + + */ +class ServiceDoctrineRepository extends DoctrineRepository implements ServiceRepository +{ + public function __construct( + ManagerRegistry $registry, + EntityPersisterInterface $entityPersisterInterface, + ) { + parent::__construct( + $registry, + Service::class, + $entityPersisterInterface + ); + } +} \ No newline at end of file