From bc11460df5782f6ba2e08268eff34e00f88fa0df Mon Sep 17 00:00:00 2001 From: Tom H Anderson Date: Wed, 2 Feb 2022 17:57:42 -0700 Subject: [PATCH] Added naming strategy --- README.md | 9 +++++- config/hal-doctrine.php | 1 + phpcs.xml.dist | 4 ++- src/DoctrineHydrator.php | 20 ++++++------- src/NamingStrategy/DefaultNamingStrategy.php | 30 +++++++++++++++++++ .../NamingStrategyInterface.php | 12 ++++++++ test/config/hal-doctrine.php | 1 + 7 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 src/NamingStrategy/DefaultNamingStrategy.php create mode 100644 src/NamingStrategy/NamingStrategyInterface.php diff --git a/README.md b/README.md index 110f147..d6aa2e3 100644 --- a/README.md +++ b/README.md @@ -111,9 +111,16 @@ to your `doctrine.php` configuration file: ``` +### Naming Strategy + +The default naming strategy uses the Inflector's `urlize()` method to change 'associationName' into 'association-name'. +If this is not the way you want to name your relationsihps or routes then create your own naming strategy and assign +it in the config file. + + ## Route naming -When using the `routeNamePatterns` to create a route name, the entity name becomes `$inflector->urlize(shortName)` +When using the `routeNamePatterns` to create a route name, the entity name becomes `$namingStrategy->route($entityName)` such as `api.short-name::fetch` according to the example configuration. diff --git a/config/hal-doctrine.php b/config/hal-doctrine.php index 396f8ad..3341f12 100644 --- a/config/hal-doctrine.php +++ b/config/hal-doctrine.php @@ -3,6 +3,7 @@ return [ 'default' => [ 'entityManager' => \Doctrine\ORM\EntityManager::class, + 'namingStrategy' => \ApiSkeletons\Laravel\HAL\Doctrine\NamingStrategy\DefaultNamingStrategy::class, 'routeNamePatterns' => [ 'entity' => 'api.{entityName}::fetch', 'collection' => 'api.{entityName}::fetchAll', diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 9a1fad5..3aa8af8 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -13,5 +13,7 @@ src - + + + diff --git a/src/DoctrineHydrator.php b/src/DoctrineHydrator.php index 004b111..1d9239c 100644 --- a/src/DoctrineHydrator.php +++ b/src/DoctrineHydrator.php @@ -4,16 +4,14 @@ namespace ApiSkeletons\Laravel\HAL\Doctrine; +use ApiSkeletons\Laravel\HAL\Doctrine\NamingStrategy\NamingStrategyInterface; use ApiSkeletons\Laravel\HAL\Hydrator; use ApiSkeletons\Laravel\HAL\Resource; use DateTime; -use Doctrine\Inflector\Inflector; -use Doctrine\Inflector\InflectorFactory; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Mapping\MappingException; use Exception; use Illuminate\Foundation\Application; -use ReflectionClass; use function array_diff_key; use function array_flip; @@ -28,7 +26,7 @@ class DoctrineHydrator extends Hydrator protected array $config = []; protected string $configurationSection = 'default'; protected EntityManager $entityManager; - protected Inflector $inflector; + protected NamingStrategyInterface $namingStrategy; public function __construct(Application $application) { @@ -50,8 +48,8 @@ public function __construct(Application $application) // @codeCoverageIgnoreEnd - $this->entityManager = $application->get($this->config['entityManager']); - $this->inflector = InflectorFactory::create()->build(); + $this->entityManager = $application->get($this->config['entityManager']); + $this->namingStrategy = $application->get($this->config['namingStrategy']); } public function extract(mixed $entity): Resource @@ -108,14 +106,14 @@ public function extract(mixed $entity): Resource if ($entityMetadata->isAssociationInverseSide($associationName)) { $resource->addLink( - $associationName, + $this->namingStrategy->association($associationName), route($associationRouteName, [ 'filter' => [$associationMapping['mappedBy'] => $identifier], ]) ); } else { $resource->addLink( - $associationName, + $this->namingStrategy->association($associationName), route($associationRouteName, [ 'filter' => [$associationMapping['inversedBy'] => $identifier], ]) @@ -128,13 +126,13 @@ public function extract(mixed $entity): Resource $associationRouteName = $this->getRouteName($associationMapping['targetEntity'], 'entity'); $resource->addLink( - $associationName, + $this->namingStrategy->association($associationName), route($associationRouteName, $identifier) ); } else { // For 1:1 relationships, only embed the owning side $resource->addEmbeddedResource( - $associationName, + $this->namingStrategy->association($associationName), $data[$associationName] ); } @@ -149,7 +147,7 @@ protected function getRouteName(string $entityName, string $routeType): string return $this->config['entities'][$entityName]['routeNames'][$routeType] ?? str_replace( '{entityName}', - $this->inflector->urlize((new ReflectionClass($entityName))->getShortName()), + $this->namingStrategy->route($entityName), $this->config['routeNamePatterns'][$routeType] ); } diff --git a/src/NamingStrategy/DefaultNamingStrategy.php b/src/NamingStrategy/DefaultNamingStrategy.php new file mode 100644 index 0000000..6b93786 --- /dev/null +++ b/src/NamingStrategy/DefaultNamingStrategy.php @@ -0,0 +1,30 @@ +inflector = InflectorFactory::create()->build(); + } + + public function route(string $entityName): string + { + return $this->inflector + ->urlize((new ReflectionClass($entityName))->getShortName()); + } + + public function association(string $associationName): string + { + return $this->inflector->urlize($associationName); + } +} diff --git a/src/NamingStrategy/NamingStrategyInterface.php b/src/NamingStrategy/NamingStrategyInterface.php new file mode 100644 index 0000000..18c165a --- /dev/null +++ b/src/NamingStrategy/NamingStrategyInterface.php @@ -0,0 +1,12 @@ + [ 'entityManager' => \Doctrine\ORM\EntityManager::class, + 'namingStrategy' => \ApiSkeletons\Laravel\HAL\Doctrine\NamingStrategy\DefaultNamingStrategy::class, 'routeNamePatterns' => [ 'entity' => 'api.{entityName}::fetch', 'collection' => 'api.{entityName}::fetchAll',