Passed
Push — master ( 3fd334...04d844 )
by
unknown
14:33
created

RenderingContextFactory   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 6
eloc 28
c 1
b 0
f 0
dl 0
loc 55
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 39 5
A __construct() 0 8 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
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 TYPO3\CMS\Fluid\Core\Rendering;
19
20
use Psr\Container\ContainerInterface;
21
use TYPO3\CMS\Core\Cache\CacheManager;
22
use TYPO3\CMS\Core\DependencyInjection\FailsafeContainer;
23
use TYPO3\CMS\Extbase\Object\ObjectManager;
24
use TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperResolver;
25
use TYPO3Fluid\Fluid\Core\Cache\FluidCacheInterface;
26
use TYPO3Fluid\Fluid\Core\Parser\TemplateProcessor\EscapingModifierTemplateProcessor;
27
use TYPO3Fluid\Fluid\Core\Parser\TemplateProcessor\NamespaceDetectionTemplateProcessor;
28
use TYPO3Fluid\Fluid\Core\Parser\TemplateProcessor\PassthroughSourceModifierTemplateProcessor;
29
use TYPO3Fluid\Fluid\Core\Parser\TemplateProcessorInterface;
30
31
/**
32
 * Factory class registered in ServiceProvider to create a RenderingContext.
33
 *
34
 * This is a low level factory always registered, even in failsafe mode: fluid
35
 * is needed in install tool which does not rely on the normal (cached) symfony DI
36
 * mechanism - Services.yaml is ignored in failsafe mode.
37
 *
38
 * A casual failsafe instantiation / injection using ServiceProvider.php wouldn't
39
 * need this factory - the ViewHelperResolver is a "normal" case. But the failsafe
40
 * mechanism is strict and relies on two things: The service is public: true,
41
 * this is the case with RenderingContext. And the service is shared: true - a
42
 * stateless singleton. This is not true for RenderingContext, it by definition
43
 * relies on context and must be created a-new per fluid parsing instance.
44
 *
45
 * To allow creating RenderingContext objects in failsafe mode, this factory
46
 * is registered as service provider to dynamically prepare instances.
47
 */
48
class RenderingContextFactory
49
{
50
    private ContainerInterface $container;
51
    private CacheManager $cacheManager;
52
    private ViewHelperResolver $viewHelperResolver;
53
54
    public function __construct(
55
        ContainerInterface $container,
56
        CacheManager $cacheManager,
57
        ViewHelperResolver $viewHelperResolver
58
    ) {
59
        $this->container = $container;
60
        $this->cacheManager = $cacheManager;
61
        $this->viewHelperResolver = $viewHelperResolver;
62
    }
63
64
    public function create(): RenderingContext
65
    {
66
        /** @var TemplateProcessorInterface[] $processors */
67
        $processors = [];
68
69
        if ($this->container instanceof FailsafeContainer) {
70
            // Load default set of processors in failsafe mode (install tool context)
71
            // as custom processors can not be retrieved from the symfony container
72
            $processors = [
73
                new EscapingModifierTemplateProcessor(),
74
                new PassthroughSourceModifierTemplateProcessor(),
75
                new NamespaceDetectionTemplateProcessor()
76
            ];
77
        } else {
78
            foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['preProcessors'] as $className) {
79
                if ($this->container->has($className)) {
80
                    /** @var TemplateProcessorInterface[] $processors */
81
                    $processors[] = $this->container->get($className);
82
                } else {
83
                    // @deprecated: Layer for processors that can't be instantiated by symfony-DI yet,
84
                    // probably due to a missing Services.yaml in the providing extension. Fall back to ObjectManager,
85
                    // which logs a deprecation. If condition and else can be dropped in v12.
86
                    $objectManager = $this->container->get(ObjectManager::class);
87
                    /** @var TemplateProcessorInterface[] $processors */
88
                    $processors[] = $objectManager->get($className);
89
                }
90
            }
91
        }
92
93
        $cache = $this->cacheManager->getCache('fluid_template');
94
        if (!$cache instanceof FluidCacheInterface) {
95
            throw new \RuntimeException('Cache fluid_template must implement FluidCacheInterface', 1623148753);
96
        }
97
98
        return new RenderingContext(
99
            $this->viewHelperResolver,
100
            $cache,
101
            $processors,
102
            $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['expressionNodeTypes']
103
        );
104
    }
105
}
106