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

CPS-IT / handlebars-forms / 23530930037

25 Mar 2026 08:00AM UTC coverage: 0.778% (-0.009%) from 0.787%
23530930037

push

github

eliashaeussler
[TASK] Use and apply PHPStan strict and deprecation rules

0 of 4 new or added lines in 2 files covered. (0.0%)

17 existing lines in 1 file now uncovered.

7 of 900 relevant lines covered (0.78%)

0.03 hits per line

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

0.0
/Classes/Domain/Renderer/HandlebarsFormRenderer.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the TYPO3 CMS extension "handlebars_forms".
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\Typo3HandlebarsForms\Domain\Renderer;
19

20
use CPSIT\Typo3Handlebars\View;
21
use Symfony\Component\DependencyInjection;
22
use TYPO3\CMS\Core;
23
use TYPO3\CMS\Extbase;
24
use TYPO3\CMS\Form;
25
use TYPO3\CMS\Frontend;
26

27
/**
28
 * HandlebarsFormRenderer
29
 *
30
 * @author Elias Häußler <e.haeussler@familie-redlich.de>
31
 * @license GPL-2.0-or-later
32
 */
33
#[DependencyInjection\Attribute\Autoconfigure(public: true, shared: false)]
34
final class HandlebarsFormRenderer extends Form\Domain\Renderer\AbstractElementRenderer
35
{
36
    private readonly Core\Information\Typo3Version $typo3Version;
37

38
    public function __construct(
×
39
        private readonly Extbase\Configuration\ConfigurationManagerInterface $configurationManager,
40
        private readonly View\HandlebarsViewFactory $viewFactory,
41
        private readonly Core\TypoScript\TypoScriptService $typoScriptService,
42
    ) {
43
        $this->typo3Version = new Core\Information\Typo3Version();
×
44
    }
45

46
    public function render(): string
×
47
    {
48
        $view = $this->resolveViewFromConfiguration() ?? $this->resolveDefaultView();
×
49
        $view->assign('form', $this->formRuntime);
×
50

51
        match ($this->typo3Version->getMajorVersion()) {
×
52
            13 => $this->triggerBeforeRenderingHook(),
×
53
            14 => $this->triggerBeforeRenderableIsRenderedEvent(),
×
54
            default => null,
×
55
        };
×
56

57
        if ($view instanceof View\HandlebarsView) {
×
58
            $templateName = $view->getTemplateName() ?? $this->formRuntime->getTemplateName();
×
59
        } else {
60
            $templateName = $this->formRuntime->getTemplateName();
×
61
        }
62

63
        return $view->render($templateName);
×
64
    }
65

66
    private function resolveViewFromConfiguration(): ?View\HandlebarsView
×
67
    {
68
        $request = $this->formRuntime->getRequest();
×
69
        $contentObjectRenderer = $request->getAttribute('currentContentObject');
×
70

71
        // Early return when outside of content object rendering
72
        if (!($contentObjectRenderer instanceof Frontend\ContentObject\ContentObjectRenderer)) {
×
73
            return null;
×
74
        }
75

76
        // Resolve form configuration from plugin configuration
77
        $pluginConfiguration = $this->configurationManager->getConfiguration(
×
78
            Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
×
79
        );
×
80
        $formConfiguration = $pluginConfiguration['handlebarsForms'] ?? null;
×
81

82
        // Early return if no handlebars configuration is available
83
        if (!is_array($formConfiguration)) {
×
84
            return null;
×
85
        }
86

87
        // HANDLEBARSTEMPLATE content object requires TypoScript configuration, so let's convert early
88
        $typoScriptConfiguration = $this->typoScriptService->convertPlainArrayToTypoScriptArray($formConfiguration);
×
89

90
        // Resolve TypoScript configuration based on form identifier
91
        $resolvedConfiguration = [];
×
92
        $possibleConfigurationKeys = [
×
93
            // Fallback
94
            'default',
×
95
            // Unique form identifier
96
            $this->formRuntime->getIdentifier(),
×
97
            // Original form identifier
98
            $this->formRuntime->getRenderingOptions()['_originalIdentifier'],
×
99
            // Form persistence identifier
100
            $this->formRuntime->getFormDefinition()->getPersistenceIdentifier(),
×
101
        ];
×
102
        foreach ($possibleConfigurationKeys as $possibleConfigurationKey) {
×
103
            if (is_string($possibleConfigurationKey) &&
×
104
                is_array($typoScriptConfiguration[$possibleConfigurationKey . '.'] ?? null)
×
105
            ) {
106
                Core\Utility\ArrayUtility::mergeRecursiveWithOverrule(
×
107
                    $resolvedConfiguration,
×
UNCOV
108
                    $typoScriptConfiguration[$possibleConfigurationKey . '.'],
×
UNCOV
109
                );
×
110
            }
111
        }
112

113
        return new View\HandlebarsView(
×
114
            $contentObjectRenderer,
×
115
            $this->typoScriptService,
×
116
            $resolvedConfiguration,
×
UNCOV
117
            $request,
×
UNCOV
118
        );
×
119
    }
120

121
    private function resolveDefaultView(): Core\View\ViewInterface
×
122
    {
123
        $renderingOptions = $this->formRuntime->getRenderingOptions();
×
124
        $templateRootPaths = $renderingOptions['templateRootPaths'] ?? [];
×
125
        $partialRootPaths = $renderingOptions['partialRootPaths'] ?? [];
×
126
        $layoutRootPaths = $renderingOptions['layoutRootPaths'] ?? [];
×
127

UNCOV
128
        if (!is_array($templateRootPaths)) {
×
129
            $templateRootPaths = null;
×
130
        }
UNCOV
131
        if (!is_array($partialRootPaths)) {
×
UNCOV
132
            $partialRootPaths = null;
×
133
        }
UNCOV
134
        if (!is_array($layoutRootPaths)) {
×
135
            $layoutRootPaths = null;
×
136
        }
137

138
        $viewFactoryData = new Core\View\ViewFactoryData(
×
139
            templateRootPaths: $templateRootPaths,
×
UNCOV
140
            partialRootPaths: $partialRootPaths,
×
141
            layoutRootPaths: $layoutRootPaths,
×
142
            request: $this->formRuntime->getRequest(),
×
UNCOV
143
        );
×
144

UNCOV
145
        return $this->viewFactory->create($viewFactoryData);
×
146
    }
147

148
    /**
149
     * @todo Remove once support for TYPO3 v13 is dropped
150
     */
UNCOV
151
    private function triggerBeforeRenderingHook(): void
×
152
    {
153
        /** @var class-string $className */
UNCOV
154
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRendering'] ?? [] as $className) {
×
155
            $hookObj = Core\Utility\GeneralUtility::makeInstance($className);
×
156

UNCOV
157
            if (method_exists($hookObj, 'beforeRendering')) {
×
UNCOV
158
                $hookObj->beforeRendering($this->formRuntime, $this->formRuntime->getFormDefinition());
×
159
            }
160
        }
161
    }
162

163
    /**
164
     * @todo Enable once support for TYPO3 v14 is added
165
     */
UNCOV
166
    private function triggerBeforeRenderableIsRenderedEvent(): void
×
167
    {
168
        // $this->eventDispatcher->dispatch(
169
        //     new Form\Event\BeforeRenderableIsRenderedEvent($this->formRuntime->getFormDefinition(), $this->formRuntime),
170
        // );
UNCOV
171
    }
×
172
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc