Completed
Push — master ( e221c0...5a5b2e )
by Matze
05:22
created

ControllerCompilerPass::process()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.0406

Importance

Changes 9
Bugs 0 Features 3
Metric Value
c 9
b 0
f 3
dl 0
loc 30
ccs 15
cts 17
cp 0.8824
rs 8.439
cc 5
eloc 16
nc 5
nop 1
crap 5.0406
1
<?php
2
3
namespace BrainExe\Core\DependencyInjection\CompilerPass;
4
5
use BrainExe\Core\Annotations\CompilerPass;
6
use BrainExe\Core\Annotations\Route as RouteAnnotation;
7
use BrainExe\Core\Application\SerializedRouteCollection;
8
use BrainExe\Core\Traits\FileCacheTrait;
9
use Exception;
10
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
11
use Symfony\Component\DependencyInjection\ContainerBuilder;
12
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
13
use Symfony\Component\Routing\Route;
14
15
/**
16
 * @CompilerPass(priority=5)
17
 */
18
class ControllerCompilerPass implements CompilerPassInterface
19
{
20
    use FileCacheTrait;
21
22
    const CONTROLLER_TAG = 'controller';
23
    const ROUTE_TAG      = 'route';
24
25
    /**
26
     * {@inheritdoc}
27
     */
28 3
    public function process(ContainerBuilder $container)
29
    {
30 3
        $controllers = $container->findTaggedServiceIds(self::ROUTE_TAG);
31
32 3
        $serialized = [];
33 3
        foreach ($controllers as $controllerId => $tag) {
34 3
            foreach ($tag as $routeRaw) {
35
                /** @var RouteAnnotation $route */
36 3
                $route = $routeRaw[0];
37
38 3
                $name = $route->getName();
39 3
                if (empty($name)) {
40
                    throw new Exception(sprintf('"name" is missing for @Route(%s)', $controllerId));
41
                }
42
43 3
                if (isset($serialized[$name])) {
44
                    throw new Exception(sprintf('Route name %s does already exits in %s', $name, $controllerId));
45
                }
46
47 3
                $serialized[$name] = serialize($this->createRoute($route));
48
            }
49
50 3
            $controller = $container->getDefinition($controllerId);
51 3
            $controller->clearTag(self::ROUTE_TAG);
52
        }
53
54 3
        ksort($serialized);
55
56 3
        $this->dumpMatcher($container, $serialized);
57 3
    }
58
59
    /**
60
     * @param RouteAnnotation $route
61
     * @return Route
62
     */
63 3
    private function createRoute(RouteAnnotation $route)
64
    {
65 3
        if ($route->isCsrf()) {
66 1
            $route->setOptions(['csrf' => true]);
67
        }
68
69 3
        return new Route(
70 3
            $route->getPath(),
71 3
            $route->getDefaults(),
72 3
            $route->getRequirements(),
73 3
            $route->getOptions(),
74 3
            $route->getHost(),
75 3
            $route->getSchemes(),
76 3
            $route->getMethods(),
77 3
            $route->getCondition()
78
        );
79
    }
80
81
    /**
82
     * @param ContainerBuilder $container
83
     * @param array $routes
84
     * @codeCoverageIgnore
85
     */
86
    protected function dumpMatcher(ContainerBuilder $container, array $routes)
87
    {
88
        $this->dumpVariableToCache(SerializedRouteCollection::CACHE_FILE, $routes);
89
90
        /** @var SerializedRouteCollection $routerCollection */
91
        $routerCollection = $container->get('Core.RouteCollection');
92
93
        $routerFile  = sprintf('%scache/router_matcher.php', ROOT);
94
        $routeDumper = new PhpMatcherDumper($routerCollection);
95
        $content     = $routeDumper->dump();
96
        file_put_contents($routerFile, $content);
97
    }
98
}
99