Skip to content

Commit

Permalink
Add route attributes factory
Browse files Browse the repository at this point in the history
  • Loading branch information
loic425 committed Jan 10, 2022
1 parent 357f88c commit 1733d9e
Show file tree
Hide file tree
Showing 11 changed files with 395 additions and 256 deletions.
4 changes: 4 additions & 0 deletions src/Bundle/Resources/config/services/routing.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@

<service id="sylius.routing.loader.routes_attributes" class="Sylius\Bundle\ResourceBundle\Routing\RoutesAttributesLoader" public="false">
<argument>%sylius.resource.mapping%</argument>
<argument type="service" id="sylius.routing.factory.route_attributes" />
<tag name="routing.route_loader" />
</service>

<service id="sylius.routing.factory.route_attributes" class="Sylius\Bundle\ResourceBundle\Routing\RouteAttributesFactory" public="false" />
<service id="Sylius\Bundle\ResourceBundle\Routing\RouteAttributesFactoryInterface" alias="sylius.routing.factory.route_attributes" />
</services>
</container>
36 changes: 8 additions & 28 deletions src/Bundle/Routing/CrudRoutesAttributesLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,44 +29,24 @@ public function __construct(
public function __invoke(): RouteCollection
{
$routeCollection = new RouteCollection();
$paths = $this->mapping['paths'] ?? [];

/** @var \ReflectionClass $reflectionClass */
foreach ($this->getReflectionClasses() as $reflectionClass) {
$this->addRoutesForSyliusCrudRoutesAttributes($routeCollection, $reflectionClass);
/** @var string $className */
foreach (ClassReflection::getResourcesByPaths($paths) as $className) {
$this->addRoutesForSyliusCrudRoutesAttributes($routeCollection, $className);
}

return $routeCollection;
}

private function addRoutesForSyliusCrudRoutesAttributes(RouteCollection $routeCollection, \ReflectionClass $reflectionClass): void
private function addRoutesForSyliusCrudRoutesAttributes(RouteCollection $routeCollection, string $className): void
{
foreach ($this->getClassAttributes($reflectionClass, SyliusCrudRoutes::class) as $reflectionAttribute) {
$attributes = ClassReflection::getClassAttributes($className, SyliusCrudRoutes::class);

foreach ($attributes as $reflectionAttribute) {
$resource = Yaml::dump($reflectionAttribute->getArguments());
$resourceRouteCollection = $this->resourceLoader->load($resource);
$routeCollection->addCollection($resourceRouteCollection);
}
}

/**
* @return \ReflectionAttribute[]
*/
private function getClassAttributes(\ReflectionClass $reflectionClass, string $attributeName): array
{
return $reflectionClass->getAttributes($attributeName);
}

private function getReflectionClasses(): iterable
{
$paths = $this->mapping['paths'] ?? [];

foreach ($paths as $resourceDirectory) {
$resources = ClassReflection::getResourcesByPath($resourceDirectory);

foreach ($resources as $className) {
$reflectionClass = new \ReflectionClass($className);

yield $className => $reflectionClass;
}
}
}
}
75 changes: 75 additions & 0 deletions src/Bundle/Routing/RouteAttributesFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\ResourceBundle\Routing;

use Sylius\Component\Resource\Annotation\SyliusRoute;
use Sylius\Component\Resource\Reflection\ClassReflection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Webmozart\Assert\Assert;

final class RouteAttributesFactory implements RouteAttributesFactoryInterface
{
public function createRouteForClass(RouteCollection $routeCollection, string $className): void
{
$attributes = ClassReflection::getClassAttributes($className, SyliusRoute::class);

foreach ($attributes as $reflectionAttribute) {
$arguments = $reflectionAttribute->getArguments();

Assert::keyExists($arguments, 'name', 'Your route should have a name attribute.');

$syliusOptions = [];

if (isset($arguments['template'])) {
$syliusOptions['template'] = $arguments['template'];
}

if (isset($arguments['vars'])) {
$syliusOptions['vars'] = $arguments['vars'];
}

if (isset($arguments['criteria'])) {
$syliusOptions['criteria'] = $arguments['criteria'];
}

if (isset($arguments['repository'])) {
$syliusOptions['repository'] = $arguments['repository'];
}

if (isset($arguments['serializationGroups'])) {
$syliusOptions['serialization_groups'] = $arguments['serializationGroups'];
}

if (isset($arguments['serializationVersion'])) {
$syliusOptions['serialization_version'] = $arguments['serializationVersion'];
}

$route = new Route(
$arguments['path'],
[
'_controller' => $arguments['controller'] ?? null,
'_sylius' => $syliusOptions,
],
$arguments['requirements'] ?? [],
$arguments['options'] ?? [],
$arguments['host'] ?? '',
$arguments['schemes'] ?? [],
$arguments['methods'] ?? []
);

$routeCollection->add($arguments['name'], $route, $arguments['priority'] ?? 0);
}
}
}
24 changes: 24 additions & 0 deletions src/Bundle/Routing/RouteAttributesFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\ResourceBundle\Routing;

use Sylius\Component\Resource\Annotation\SyliusRoute;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Webmozart\Assert\Assert;

interface RouteAttributesFactoryInterface
{
public function createRouteForClass(RouteCollection $routeCollection, string $className): void;
}
76 changes: 10 additions & 66 deletions src/Bundle/Routing/RoutesAttributesLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,92 +23,36 @@ final class RoutesAttributesLoader
{
private array $mapping;

public function __construct(array $mapping)
private RouteAttributesFactoryInterface $routesAttributesFactory;

public function __construct(array $mapping, RouteAttributesFactoryInterface $routesAttributesFactory)
{
$this->mapping = $mapping;
$this->routesAttributesFactory = $routesAttributesFactory;
}

public function __invoke(): RouteCollection
{
$routeCollection = new RouteCollection();
$paths = $this->mapping['paths'] ?? [];

/** @var \ReflectionClass $reflectionClass */
foreach ($this->getReflectionClasses() as $reflectionClass) {
$this->addRoutesForSyliusRouteAttributes($routeCollection, $reflectionClass);
/** @var string $className */
foreach ($paths as $className) {
$this->routesAttributesFactory->createRouteForClass($routeCollection, $className);
}

return $routeCollection;
}

private function addRoutesForSyliusRouteAttributes(RouteCollection $routeCollection, \ReflectionClass $reflectionClass): void
{
foreach ($this->getClassAttributes($reflectionClass, SyliusRoute::class) as $reflectionAttribute) {
$arguments = $reflectionAttribute->getArguments();

Assert::keyExists($arguments, 'name', 'Your route should have a name attribute.');

$syliusOptions = [];

if (isset($arguments['template'])) {
$syliusOptions['template'] = $arguments['template'];
}

if (isset($arguments['vars'])) {
$syliusOptions['vars'] = $arguments['vars'];
}

if (isset($arguments['criteria'])) {
$syliusOptions['criteria'] = $arguments['criteria'];
}

if (isset($arguments['repository'])) {
$syliusOptions['repository'] = $arguments['repository'];
}

if (isset($arguments['serializationGroups'])) {
$syliusOptions['serialization_groups'] = $arguments['serializationGroups'];
}

if (isset($arguments['serializationVersion'])) {
$syliusOptions['serialization_version'] = $arguments['serializationVersion'];
}

$route = new Route(
$arguments['path'],
[
'_controller' => $arguments['controller'] ?? null,
'_sylius' => $syliusOptions,
],
$arguments['requirements'] ?? [],
$arguments['options'] ?? [],
$arguments['host'] ?? '',
$arguments['schemes'] ?? [],
$arguments['methods'] ?? []
);

$routeCollection->add($arguments['name'], $route, $arguments['priority'] ?? 0);
}
}

/**
* @return \ReflectionAttribute[]
*/
private function getClassAttributes(\ReflectionClass $reflectionClass, string $attributeName): array
{
return $reflectionClass->getAttributes($attributeName);
}

private function getReflectionClasses(): iterable
private function getClasses(): iterable
{
$paths = $this->mapping['paths'] ?? [];

foreach ($paths as $resourceDirectory) {
$resources = ClassReflection::getResourcesByPath($resourceDirectory);

foreach ($resources as $className) {
$reflectionClass = new \ReflectionClass($className);

yield $className => $reflectionClass;
yield $className;
}
}
}
Expand Down
Loading

0 comments on commit 1733d9e

Please sign in to comment.