Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
HypeMC committed Jun 6, 2023
1 parent 823fd29 commit 3721351
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 29 deletions.
2 changes: 1 addition & 1 deletion config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@
->args([
service('sofascore.purgatory.mapping.configuration'),
service('router'),
service('controller_resolver'),
service('sofascore.purgatory.annotation_reader'),
service('doctrine.orm.entity_manager'),
abstract_arg('ControllerClassMapPass'),
])

->set('sofascore.purgatory.mapping.annotation_loader.warmer', AnnotationsLoaderWarmer::class)
Expand Down
22 changes: 22 additions & 0 deletions src/DependencyInjection/CompilerPass/ControllerClassMapPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Sofascore\PurgatoryBundle\DependencyInjection\CompilerPass;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

final class ControllerClassMapPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
$classMap = [];

foreach ($container->findTaggedServiceIds('controller.service_arguments', true) as $id => $tags) {
$classMap[$id] = $container->getDefinition($id)->getClass();
}

$container->getDefinition('sofascore.purgatory.mapping.annotation_loader')->replaceArgument(4, $classMap);
}
}
73 changes: 45 additions & 28 deletions src/Mapping/Loader/AnnotationsLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,30 @@
use Sofascore\PurgatoryBundle\Mapping\MappingValue;
use Sofascore\PurgatoryBundle\Mapping\PropertySubscription;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouterInterface;

class AnnotationsLoader implements LoaderInterface, WarmableInterface
{
protected RouterInterface $router;
protected Configuration $config;
protected ControllerResolverInterface $controllerResolver;
protected Reader $annotationReader;
protected ObjectManager $manager;
protected array $serviceClassMap;

public function __construct(
Configuration $config,
RouterInterface $router,
ControllerResolverInterface $controllerResolver,
Reader $annotationReader,
ObjectManager $manager,
array $serviceClassMap,
) {
$this->config = $config;
$this->router = $router;
$this->controllerResolver = $controllerResolver;
$this->annotationReader = $annotationReader;
$this->manager = $manager;
$this->serviceClassMap = $serviceClassMap;
}

/**
Expand Down Expand Up @@ -118,15 +116,17 @@ private function loadMappings(): MappingCollection
}
}

$controllerCallable = $this->resolveController($route->getDefault('_controller'));
if (null === $routeController = $route->getDefault('_controller')) {
continue;
}

// if controller cannot be resolved, skip route
if (false === $controllerCallable) {
if (null === $controllerCallableReflection = $this->resolveControllerCallable($routeController)) {
continue;
}

// get class/property subscriptions
$this->parseControllerMappings($controllerCallable, $routeName, $route, $subscriptions);
$this->parseControllerMappings($controllerCallableReflection, $routeName, $route, $subscriptions);
}

// resolve subscription classes and properties
Expand Down Expand Up @@ -154,22 +154,46 @@ private function loadMappings(): MappingCollection
return $mappingCollection;
}

protected function resolveController(?string $controllerPath): callable|false
private function resolveControllerCallable(array|object|string $controller): ?\ReflectionMethod
{
if (null === $controllerPath) {
return false;
if (\is_array($controller) && isset($controller[0]) && \is_string($controller[0]) && isset($controller[1])) {
$resolvedClass = $this->resolveClass($controller[0]);

return $resolvedClass ? new \ReflectionMethod($resolvedClass, $controller[1]) : null;

Check failure on line 162 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

ArgumentTypeCoercion

src/Mapping/Loader/AnnotationsLoader.php:162:59: ArgumentTypeCoercion: Argument 1 of ReflectionMethod::__construct expects class-string|object, but parent type non-falsy-string provided (see https://psalm.dev/193)

Check failure on line 162 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

ArgumentTypeCoercion

src/Mapping/Loader/AnnotationsLoader.php:162:59: ArgumentTypeCoercion: Argument 1 of ReflectionMethod::__construct expects class-string|object, but parent type non-falsy-string provided (see https://psalm.dev/193)
}

// set controller path
$request = new Request([], [], ['_controller' => $controllerPath]);
if (\is_object($controller) && \is_callable($controller)) {
return new \ReflectionMethod($controller, '__invoke');
}

try {
// resolve controller path
return $this->controllerResolver->getController($request);
} catch (\Exception $e) {
// if error happens skip route
return false;
if (\function_exists($controller)) {

Check failure on line 169 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:169:30: PossiblyInvalidArgument: Argument 1 of function_exists expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)

Check failure on line 169 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:169:30: PossiblyInvalidArgument: Argument 1 of function_exists expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)
return null;
}

if (!str_contains($controller, '::')) {

Check failure on line 173 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:173:27: PossiblyInvalidArgument: Argument 1 of str_contains expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)

Check failure on line 173 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:173:27: PossiblyInvalidArgument: Argument 1 of str_contains expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)
$resolvedClass = $this->resolveClass($controller);

Check failure on line 174 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:174:50: PossiblyInvalidArgument: Argument 1 of Sofascore\PurgatoryBundle\Mapping\Loader\AnnotationsLoader::resolveClass expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)

Check failure on line 174 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:174:50: PossiblyInvalidArgument: Argument 1 of Sofascore\PurgatoryBundle\Mapping\Loader\AnnotationsLoader::resolveClass expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)

return $resolvedClass ? new \ReflectionMethod($resolvedClass, '__invoke') : null;

Check failure on line 176 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

ArgumentTypeCoercion

src/Mapping/Loader/AnnotationsLoader.php:176:59: ArgumentTypeCoercion: Argument 1 of ReflectionMethod::__construct expects class-string|object, but parent type non-falsy-string provided (see https://psalm.dev/193)

Check failure on line 176 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

ArgumentTypeCoercion

src/Mapping/Loader/AnnotationsLoader.php:176:59: ArgumentTypeCoercion: Argument 1 of ReflectionMethod::__construct expects class-string|object, but parent type non-falsy-string provided (see https://psalm.dev/193)
}

[$class, $method] = explode('::', $controller, 2);

Check failure on line 179 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyUndefinedArrayOffset

src/Mapping/Loader/AnnotationsLoader.php:179:18: PossiblyUndefinedArrayOffset: Possibly undefined array key (see https://psalm.dev/167)

Check failure on line 179 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:179:43: PossiblyInvalidArgument: Argument 2 of explode expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)

Check failure on line 179 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyUndefinedArrayOffset

src/Mapping/Loader/AnnotationsLoader.php:179:18: PossiblyUndefinedArrayOffset: Possibly undefined array key (see https://psalm.dev/167)

Check failure on line 179 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

PossiblyInvalidArgument

src/Mapping/Loader/AnnotationsLoader.php:179:43: PossiblyInvalidArgument: Argument 2 of explode expects string, but possibly different type array<array-key, mixed>|object|string provided (see https://psalm.dev/092)

$resolvedClass = $this->resolveClass($class);

return $resolvedClass ? new \ReflectionMethod($resolvedClass, $method) : null;

Check failure on line 183 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

ArgumentTypeCoercion

src/Mapping/Loader/AnnotationsLoader.php:183:55: ArgumentTypeCoercion: Argument 1 of ReflectionMethod::__construct expects class-string|object, but parent type non-falsy-string provided (see https://psalm.dev/193)

Check failure on line 183 in src/Mapping/Loader/AnnotationsLoader.php

View workflow job for this annotation

GitHub Actions / Static Analysis

ArgumentTypeCoercion

src/Mapping/Loader/AnnotationsLoader.php:183:55: ArgumentTypeCoercion: Argument 1 of ReflectionMethod::__construct expects class-string|object, but parent type non-falsy-string provided (see https://psalm.dev/193)
}

private function resolveClass(string $serviceIdOrClass): ?string
{
if (isset($this->serviceClassMap[$serviceIdOrClass])) {
return $this->serviceClassMap[$serviceIdOrClass];
}

if (class_exists($serviceIdOrClass)) {
return $serviceIdOrClass;
}

return null;
}

/**
Expand All @@ -178,19 +202,12 @@ protected function resolveController(?string $controllerPath): callable|false
* @throws \ReflectionException|ReaderException
*/
private function parseControllerMappings(
callable $controllerCallable,
\ReflectionMethod $controllerCallableReflection,
string $routeName,
Route $route,
array &$subscriptions,
): array {
if (!\is_array($controllerCallable)) {
return [];
}

[$controller, $method] = $controllerCallable;

$reflectionMethod = new \ReflectionMethod($controller, $method);
$methodAnnotations = $this->annotationReader->getAnnotations($reflectionMethod);
$methodAnnotations = $this->annotationReader->getAnnotations($controllerCallableReflection);

foreach ($methodAnnotations as $class => $annotations) {
if (PurgeOn::class === $class) {
Expand Down
2 changes: 2 additions & 0 deletions src/PurgatoryBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Sofascore\PurgatoryBundle;

use Sofascore\PurgatoryBundle\DependencyInjection\CompilerPass\ControllerClassMapPass;
use Sofascore\PurgatoryBundle\DependencyInjection\CompilerPass\RegisterPurgerImplementationCompilerPass;
use Sofascore\PurgatoryBundle\DependencyInjection\CompilerPass\SymfonyPurgerRemovalCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -20,5 +21,6 @@ public function build(ContainerBuilder $container): void

$container->addCompilerPass(new RegisterPurgerImplementationCompilerPass());
$container->addCompilerPass(new SymfonyPurgerRemovalCompilerPass());
$container->addCompilerPass(new ControllerClassMapPass());
}
}

0 comments on commit 3721351

Please sign in to comment.