-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3e393e6
commit 7f33431
Showing
10 changed files
with
399 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Attribute; | ||
|
||
use StfalconStudio\ApiBundle\Exception\InvalidArgumentException; | ||
|
||
/** | ||
* Dependent Entity Attribute. | ||
*/ | ||
#[\Attribute(\Attribute::TARGET_PROPERTY)] | ||
class DependentEntity | ||
{ | ||
/** | ||
* @param string $propertyPath | ||
*/ | ||
public function __construct(private readonly string $propertyPath) | ||
{ | ||
if (empty($propertyPath)) { | ||
throw new InvalidArgumentException('The "propertyPath" parameter can not be empty.'); | ||
} | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getPropertyPath(): string | ||
{ | ||
return $this->propertyPath; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Service\DependentEntity; | ||
|
||
/** | ||
* Dependent Entity Interface. | ||
*/ | ||
interface DependentEntityInterface | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Service\DependentEntity; | ||
|
||
use StfalconStudio\ApiBundle\Attribute\DependentEntity; | ||
use StfalconStudio\ApiBundle\Exception\LogicException; | ||
use StfalconStudio\ApiBundle\Exception\RuntimeException; | ||
use StfalconStudio\ApiBundle\Service\Repository\RepositoryService; | ||
use StfalconStudio\ApiBundle\Traits\PropertyAccessorTrait; | ||
|
||
/** | ||
* Dependent Entity Service. | ||
*/ | ||
class DependentEntityService | ||
{ | ||
use PropertyAccessorTrait; | ||
|
||
/** | ||
* @param RepositoryService $repositoryService | ||
*/ | ||
public function __construct(private readonly RepositoryService $repositoryService) | ||
{ | ||
} | ||
|
||
/** | ||
* @param DependentEntityInterface $entity | ||
* | ||
* @return void | ||
*/ | ||
public function setDependentEntities(DependentEntityInterface $entity): void | ||
{ | ||
$class = new \ReflectionClass($entity); | ||
|
||
$properties = $class->getProperties(); | ||
|
||
foreach ($properties as $property) { | ||
$propertyName = $property->getName(); | ||
$attributes = $property->getAttributes(DependentEntity::class); | ||
|
||
if (\count($attributes) > 1) { | ||
throw new RuntimeException(\sprintf('Detected more than one DependentEntity attribute for property %s. Only one DependentEntity attribute allowed per property.', $propertyName)); | ||
} | ||
|
||
if (empty($attributes)) { | ||
continue; | ||
} | ||
|
||
$propertyPath = $attributes[0]->getArguments()['propertypath']; | ||
|
||
$propertyPathValue = $this->propertyAccessor->getValue($entity, $propertyPath); | ||
|
||
if (\is_string($propertyPathValue)) { | ||
$reflectionType = $property->getType(); | ||
|
||
if (!$reflectionType instanceof \ReflectionNamedType) { | ||
throw new LogicException(\sprintf('Cannot get reflection type from property %s', $propertyName)); | ||
} | ||
|
||
$class = $reflectionType->getName(); | ||
|
||
$dependentEntity = $this->repositoryService->getEntityById($propertyPathValue, $class); | ||
} else { | ||
$dependentEntity = null; | ||
} | ||
|
||
$this->propertyAccessor->setValue($entity, $propertyName, $dependentEntity); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Service\Repository; | ||
|
||
/** | ||
* Findable By Id Interface. | ||
*/ | ||
interface FindableByIdInterface | ||
{ | ||
/** | ||
* @param string $id | ||
* | ||
* @return mixed | ||
*/ | ||
public function findOneById(string $id): mixed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Service\Repository; | ||
|
||
/** | ||
* Gettable One By Id Interface. | ||
*/ | ||
interface GettableOneByIdInterface | ||
{ | ||
/** | ||
* @param string $id | ||
* | ||
* @return mixed | ||
*/ | ||
public function getOneById(string $id): mixed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Service\Repository; | ||
|
||
use StfalconStudio\ApiBundle\Exception\LogicException; | ||
use StfalconStudio\ApiBundle\Traits\EntityManagerTrait; | ||
|
||
/** | ||
* Repository Service. | ||
*/ | ||
class RepositoryService | ||
{ | ||
use EntityManagerTrait; | ||
|
||
/** | ||
* @param string $id | ||
* @param string $class | ||
* | ||
* @return mixed | ||
*/ | ||
public function getEntityById(string $id, string $class): mixed | ||
{ | ||
$repository = $this->em->getRepository($class); // @phpstan-ignore-line | ||
|
||
if (!$repository instanceof GettableOneByIdInterface) { | ||
throw new LogicException(\sprintf('Repository %s should implements %s interface', $repository->getClassName(), GettableOneByIdInterface::class)); | ||
} | ||
|
||
return $repository->getOneById($id); | ||
} | ||
|
||
/** | ||
* @param string $id | ||
* @param string $class | ||
* | ||
* @return mixed | ||
*/ | ||
public function findEntityById(string $id, string $class): mixed | ||
{ | ||
$repository = $this->em->getRepository($class); // @phpstan-ignore-line | ||
|
||
if (!$repository instanceof FindableByIdInterface) { | ||
throw new LogicException(\sprintf('Repository %s should implements %s interface', $repository->getClassName(), FindableByIdInterface::class)); | ||
} | ||
|
||
return $repository->findOneById($id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Traits; | ||
|
||
use Symfony\Component\PropertyAccess\PropertyAccessor; | ||
use Symfony\Contracts\Service\Attribute\Required; | ||
|
||
/** | ||
* Property Accessor Trait. | ||
*/ | ||
trait PropertyAccessorTrait | ||
{ | ||
protected PropertyAccessor $propertyAccessor; | ||
|
||
/** | ||
* @param PropertyAccessor $propertyAccessor | ||
* | ||
* @return void | ||
*/ | ||
#[Required] | ||
public function setPropertyAccessor(PropertyAccessor $propertyAccessor): void | ||
{ | ||
$this->propertyAccessor = $propertyAccessor; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Validator\Constraints\Entity; | ||
|
||
use StfalconStudio\ApiBundle\Exception\InvalidArgumentException; | ||
use Symfony\Component\Validator\Constraint; | ||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException; | ||
|
||
/** | ||
* Entity Exists. | ||
*/ | ||
#[\Attribute(\Attribute::TARGET_PROPERTY)] | ||
class EntityExists extends Constraint | ||
{ | ||
public const ENTITY_DOES_NOT_EXIST = 'ENTITY_DOES_NOT_EXIST'; | ||
|
||
/** @var array<string, string> */ | ||
protected const ERROR_NAMES = [ | ||
self::ENTITY_DOES_NOT_EXIST => self::ENTITY_DOES_NOT_EXIST, | ||
]; | ||
|
||
public string $message = 'entity_does_not_exist'; | ||
|
||
public string $class; | ||
|
||
/** | ||
* @param string $class | ||
* @param mixed $options | ||
* @param array|null $groups | ||
* @param mixed $payload | ||
*/ | ||
public function __construct(string $class, mixed $options = null, array $groups = null, mixed $payload = null) | ||
{ | ||
parent::__construct($options, $groups, $payload); | ||
|
||
if (empty($class)) { | ||
throw new ConstraintDefinitionException('The "class" parameter can not be empty.'); | ||
} | ||
|
||
if (!\class_exists($class)) { | ||
throw new InvalidArgumentException(\sprintf('Class %s does not exist.', $class)); | ||
} | ||
|
||
$this->class = $class; | ||
} | ||
} |
Oops, something went wrong.