• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CPS-IT / handlebars / 25304058960

04 May 2026 06:15AM UTC coverage: 87.421% (-2.4%) from 89.817%
25304058960

Pull #563

github

web-flow
Merge 83d9abf7e into 4639f0faf
Pull Request #563: [BUGFIX] Limit view factory override implementation to certain services

0 of 42 new or added lines in 1 file covered. (0.0%)

1376 of 1574 relevant lines covered (87.42%)

6.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/Classes/DependencyInjection/CompilerPass/HandlebarsViewFactoryPass.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the TYPO3 CMS extension "handlebars".
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17

18
namespace CPSIT\Typo3Handlebars\DependencyInjection\CompilerPass;
19

20
use CPSIT\Typo3Handlebars\View;
21
use Symfony\Component\DependencyInjection;
22

23
/**
24
 * HandlebarsViewFactoryPass
25
 *
26
 * @author Elias Häußler <e.haeussler@familie-redlich.de>
27
 * @license GPL-2.0-or-later
28
 *
29
 * @phpstan-type TargetService array{calls?: array<string, string>, properties?: list<string>}
30
 */
31
final class HandlebarsViewFactoryPass extends DependencyInjection\Compiler\AbstractRecursivePass
32
{
33
    private readonly DependencyInjection\Reference $viewFactory;
34

35
    /**
36
     * @var array<string, TargetService>
37
     */
38
    private array $targetServices = [];
39

NEW
40
    public function __construct(string $viewFactoryServiceId = View\HandlebarsViewFactory::class)
×
41
    {
NEW
42
        $this->viewFactory = new DependencyInjection\Reference($viewFactoryServiceId);
×
43
    }
44

NEW
45
    public function process(DependencyInjection\ContainerBuilder $container): void
×
46
    {
NEW
47
        if ($container->has((string)$this->viewFactory)) {
×
NEW
48
            parent::process($container);
×
49
        }
50
    }
51

NEW
52
    protected function processValue(mixed $value, bool $isRoot = false): mixed
×
53
    {
NEW
54
        $value = parent::processValue($value, $isRoot);
×
55

NEW
56
        if (!($value instanceof DependencyInjection\Definition)
×
NEW
57
            || $this->currentId === null
×
NEW
58
            || !$value->isAutowired()
×
NEW
59
            || $value->isAbstract()
×
NEW
60
            || $value->getClass() === null
×
61
        ) {
NEW
62
            return $value;
×
63
        }
64

NEW
65
        $configuration = $this->targetServices[$this->currentId] ?? $this->resolveBaseConfiguration($value->getClass());
×
66

NEW
67
        if ($configuration === null) {
×
NEW
68
            return $value;
×
69
        }
70

NEW
71
        foreach ($configuration['calls'] ?? [] as $methodName => $argumentName) {
×
NEW
72
            $value->removeMethodCall($methodName);
×
NEW
73
            $value->addMethodCall($methodName, [$argumentName => $this->viewFactory]);
×
74
        }
75

NEW
76
        foreach ($configuration['properties'] ?? [] as $propertyName) {
×
NEW
77
            $value->setArgument($propertyName, $this->viewFactory);
×
78
        }
79

NEW
80
        return $value;
×
81
    }
82

83
    /**
84
     * @return TargetService|null
85
     */
NEW
86
    private function resolveBaseConfiguration(string $className): ?array
×
87
    {
NEW
88
        $reflection = $this->container?->getReflectionClass($className, false);
×
89

NEW
90
        if ($reflection === null) {
×
NEW
91
            return null;
×
92
        }
93

NEW
94
        $current = $reflection;
×
95

96
        do {
NEW
97
            if (array_key_exists($current->getName(), $this->targetServices)) {
×
NEW
98
                return $this->targetServices[$current->getName()];
×
99
            }
100

NEW
101
            $current = $current->getParentClass();
×
NEW
102
        } while ($current !== false);
×
103

NEW
104
        return null;
×
105
    }
106

NEW
107
    public function addMethodCall(string $serviceId, string $methodName, string $argumentName = '$viewFactory'): self
×
108
    {
NEW
109
        $this->targetServices[$serviceId] ??= [];
×
NEW
110
        $this->targetServices[$serviceId]['calls'] ??= [];
×
NEW
111
        $this->targetServices[$serviceId]['calls'][$methodName] = $argumentName;
×
112

NEW
113
        return $this;
×
114
    }
115

NEW
116
    public function addProperty(string $serviceId, string $propertyName = '$viewFactory'): self
×
117
    {
NEW
118
        $this->targetServices[$serviceId] ??= [];
×
NEW
119
        $this->targetServices[$serviceId]['properties'] ??= [];
×
NEW
120
        $this->targetServices[$serviceId]['properties'][] = $propertyName;
×
121

NEW
122
        return $this;
×
123
    }
124
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc