Completed
Push — master ( d301ea...e33285 )
by Bernhard
63:00 queued 15:07
created

TwigLoaderPass   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 50%

Importance

Changes 2
Bugs 2 Features 0
Metric Value
wmc 14
c 2
b 2
f 0
lcom 0
cbo 2
dl 0
loc 62
ccs 19
cts 38
cp 0.5
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A isAddLoaderCall() 0 6 4
C process() 0 52 10
1
<?php
2
3
/*
4
 * This file is part of the puli/symfony-bundle package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\SymfonyBundle\DependencyInjection\Compiler;
13
14
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Reference;
17
18
/**
19
 * Moves the "puli.twig.template_loader" service before the
20
 * "twig.loader.filesystem" service.
21
 *
22
 * This is necessary since the following PR:
23
 * https://github.com/symfony/symfony/pull/12894
24
 *
25
 * If not done, the PuliTemplateLoader is never invoked, because the filesystem
26 2
 * loader already resolves the Puli template path using the PuliFileLocator.
27
 * The responsible line is TemplateNameParser:59 which does not throw an
28 2
 * exception anymore.
29
 *
30
 * @since  1.0
31
 *
32
 * @author Bernhard Schussek <[email protected]>
33 2
 */
34
class TwigLoaderPass implements CompilerPassInterface
35 2
{
36 3
    public function process(ContainerBuilder $container)
37
    {
38 3
        if (false === $container->hasDefinition('twig')) {
39 3
            return;
40
        }
41
42 4
        $chainLoader = $container->getDefinition('twig.loader.chain');
43
44 4
        $methodCalls = $chainLoader->getMethodCalls();
45 2
        $symfonyKey1 = null;
46 4
        $symfonyKey2 = null;
47 4
        $puliKey = null;
48 2
49 2
        // By default, the filesystem loader is added before the Puli loader
50
        // However, that prevents the Puli loader from being used at all, so
51
        // we need to insert the Puli loader right before the filesystem
52
        // loader
53 4
        foreach ($methodCalls as $key => $methodCall) {
54
            if ($this->isAddLoaderCall($methodCall, 'twig.loader.filesystem')) {
55 2
                $symfonyKey1 = $key;
56 2
                continue;
57 2
            }
58
59
            if ($this->isAddLoaderCall($methodCall, 'twig.loader.native_filesystem')) {
60
                $symfonyKey2 = $key;
61 2
                continue;
62
            }
63 2
64
            if ($this->isAddLoaderCall($methodCall, 'puli.twig.template_loader')) {
65
                $puliKey = $key;
66
                continue;
67
            }
68
        }
69
70
        // Move the Puli loader before the filesystem loaders if necessary
71 2
        if ((null === $symfonyKey1 && null === $symfonyKey2) || null === $puliKey) {
72 2
            return;
73
        }
74
75
        $symfonyKey = min($symfonyKey1, $symfonyKey2);
76
77
        if ($puliKey < $symfonyKey) {
78
            return;
79
        }
80
81
        $puliLoaderCall = $methodCalls[$puliKey];
82
        unset($methodCalls[$puliKey]);
83
84
        array_splice($methodCalls, $symfonyKey, 0, array($puliLoaderCall));
85
86
        $chainLoader->setMethodCalls($methodCalls);
87
    }
88
89
    private function isAddLoaderCall(array $methodCall, $serviceId)
90
    {
91
        return 'addLoader' === $methodCall[0] && isset($methodCall[1][0])
92
            && $methodCall[1][0] instanceof Reference
93
            && $serviceId === (string) $methodCall[1][0];
94
    }
95
}
96