1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Bridges\ApplicationDI;
9:
10: use Nette;
11: use Tracy;
12:
13:
14: 15: 16:
17: class RoutingExtension extends Nette\DI\CompilerExtension
18: {
19: public $defaults = [
20: 'debugger' => NULL,
21: 'routes' => [],
22: 'cache' => FALSE,
23: ];
24:
25:
26: private $debugMode;
27:
28:
29: public function __construct($debugMode = FALSE)
30: {
31: $this->defaults['debugger'] = interface_exists(Tracy\IBarPanel::class);
32: $this->debugMode = $debugMode;
33: }
34:
35:
36: public function loadConfiguration()
37: {
38: $config = $this->validateConfig($this->defaults);
39: $builder = $this->getContainerBuilder();
40:
41: $router = $builder->addDefinition($this->prefix('router'))
42: ->setClass(Nette\Application\IRouter::class)
43: ->setFactory(Nette\Application\Routers\RouteList::class);
44:
45: foreach ($config['routes'] as $mask => $action) {
46: $router->addSetup('$service[] = new Nette\Application\Routers\Route(?, ?);', [$mask, $action]);
47: }
48:
49: if ($this->name === 'routing') {
50: $builder->addAlias('router', $this->prefix('router'));
51: }
52: }
53:
54:
55: public function beforeCompile()
56: {
57: $builder = $this->getContainerBuilder();
58:
59: if ($this->debugMode && $this->config['debugger'] && $application = $builder->getByType(Nette\Application\Application::class)) {
60: $builder->getDefinition($application)->addSetup('@Tracy\Bar::addPanel', [
61: new Nette\DI\Statement(Nette\Bridges\ApplicationTracy\RoutingPanel::class),
62: ]);
63: }
64: }
65:
66:
67: public function afterCompile(Nette\PhpGenerator\ClassType $class)
68: {
69: if (!empty($this->config['cache'])) {
70: $method = $class->getMethod(Nette\DI\Container::getMethodName($this->prefix('router')));
71: try {
72: $router = eval($method->getBody());
73: if ($router instanceof Nette\Application\Routers\RouteList) {
74: $router->warmupCache();
75: }
76: $s = serialize($router);
77: } catch (\Throwable $e) {
78: throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: ' . $e->getMessage(), 0, $e);
79: } catch (\Exception $e) {
80: throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: ' . $e->getMessage(), 0, $e);
81: }
82: $method->setBody('return unserialize(?);', [$s]);
83: }
84: }
85:
86: }
87: