Completed
Pull Request — master (#10)
by Matze
07:31
created

ControllerCompilerPass::process()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 5.0027

Importance

Changes 8
Bugs 0 Features 3
Metric Value
c 8
b 0
f 3
dl 0
loc 30
ccs 20
cts 21
cp 0.9524
rs 8.439
cc 5
eloc 17
nc 5
nop 1
crap 5.0027
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 Exception;
9
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
10
use Symfony\Component\DependencyInjection\ContainerBuilder;
11
use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
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
    const CONTROLLER_TAG = 'controller';
21
    const ROUTE_TAG      = 'route';
22
23
    /**
24
     * {@inheritdoc}
25
     */
26 3
    public function process(ContainerBuilder $container)
27
    {
28 3
        $coreCollector = $container->getDefinition('Core.RouteCollection');
29 3
        $controllers   = $container->findTaggedServiceIds(self::ROUTE_TAG);
30
31 3
        $serialized = [];
32 3
        foreach ($controllers as $controllerId => $tag) {
33 3
            foreach ($tag as $routeRaw) {
34
                /** @var RouteAnnotation $route */
35 3
                $route = $routeRaw[0];
36
37 3
                $name = $route->getName();
38 3
                if (!$name) {
39
                    throw new Exception(sprintf('"name" is missing for @Route(%s)', $controllerId));
40
                }
41 3
                if ($route->isCsrf()) {
42 1
                    $route->setOptions(['csrf' => true]);
43 1
                }
44
45 3
                $serialized[$name] = serialize($this->createRoute($route));
46 3
            }
47
48 3
            $controller = $container->getDefinition($controllerId);
49 3
            $controller->clearTag(self::ROUTE_TAG);
50 3
        }
51
52 3
        $coreCollector->addArgument($serialized);
53
54 3
        $this->dumpMatcher($container);
55 3
    }
56
57
    /**
58
     * @param RouteAnnotation $route
59
     * @return Route
60
     */
61 3
    private function createRoute(RouteAnnotation $route)
62
    {
63 3
        if ($route->isCsrf()) {
64 1
            $route->setOptions(['csrf' => true]);
65 1
        }
66
67 3
        return new Route(
68 3
            $route->getPath(),
69 3
            $route->getDefaults(),
70 3
            $route->getRequirements(),
71 3
            $route->getOptions(),
72 3
            $route->getHost(),
73 3
            $route->getSchemes(),
74 3
            $route->getMethods(),
75 3
            $route->getCondition()
76 3
        );
77
    }
78
79
    /**
80
     * @param ContainerBuilder $container
81
     * @codeCoverageIgnore
82
     */
83
    protected function dumpMatcher(ContainerBuilder $container)
84
    {
85
        if (!is_dir(ROOT . 'cache')) {
86
            return;
87
        }
88
89
        /** @var SerializedRouteCollection $routerCollection */
90
        $routerCollection = $container->get('Core.RouteCollection');
91
92
        $routerFile  = sprintf('%scache/router_matcher.php', ROOT);
93
        $routeDumper = new PhpMatcherDumper($routerCollection);
94
        $content     = $routeDumper->dump();
95
        file_put_contents($routerFile, $content);
96
97
        $routerFile  = sprintf('%scache/router_generator.php', ROOT);
98
        $routeDumper = new PhpGeneratorDumper($routerCollection);
99
        $content     = $routeDumper->dump();
100
        file_put_contents($routerFile, $content);
101
    }
102
}
103