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

CPS-IT / handlebars / 12371132181

17 Dec 2024 10:29AM UTC coverage: 89.53% (-0.2%) from 89.771%
12371132181

Pull #374

github

web-flow
Merge 3bc516881 into f487a763c
Pull Request #374: [FEATURE] Introduce `#[AsHelper]` attribute for helper DI registration

1 of 3 new or added lines in 2 files covered. (33.33%)

10 existing lines in 3 files now uncovered.

667 of 745 relevant lines covered (89.53%)

3.14 hits per line

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

97.06
/Classes/Renderer/Helper/RenderHelper.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the TYPO3 CMS extension "handlebars".
7
 *
8
 * Copyright (C) 2024 Elias Häußler <e.haeussler@familie-redlich.de>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace Fr\Typo3Handlebars\Renderer\Helper;
25

26
use Fr\Typo3Handlebars\DataProcessing;
27
use Fr\Typo3Handlebars\Exception;
28
use Fr\Typo3Handlebars\Renderer;
29
use LightnCandy\SafeString;
30
use TYPO3\CMS\Core;
31
use TYPO3\CMS\Frontend;
32

33
/**
34
 * RenderHelper
35
 *
36
 * @author Elias Häußler <e.haeussler@familie-redlich.de>
37
 * @license GPL-2.0-or-later
38
 * @see https://github.com/frctl/fractal/blob/main/packages/handlebars/src/helpers/render.js
39
 */
40
class RenderHelper implements HelperInterface
41
{
42
    public function __construct(
4✔
43
        protected readonly Renderer\RendererInterface $renderer,
44
        protected readonly Core\TypoScript\TypoScriptService $typoScriptService,
45
        protected readonly Frontend\ContentObject\ContentObjectRenderer $contentObjectRenderer,
46
    ) {}
4✔
47

48
    /**
49
     * @throws Exception\InvalidConfigurationException
50
     */
51
    public function evaluate(string $name): SafeString
4✔
52
    {
53
        // Get helper options
54
        $arguments = \func_get_args();
4✔
55
        array_shift($arguments);
4✔
56
        $options = array_pop($arguments);
4✔
57

58
        // Resolve data
59
        $rootData = $options['data']['root'];
4✔
60
        $merge = (bool)($options['hash']['merge'] ?? false);
4✔
61
        $renderUncached = (bool)($options['hash']['uncached'] ?? false);
4✔
62

63
        // Fetch custom context
64
        // ====================
65
        // Custom contexts can be defined as helper argument, e.g.
66
        // {{render '@foo' customContext}}
67
        $context = reset($arguments);
4✔
68
        if (!\is_array($context)) {
4✔
69
            $context = [];
1✔
70
        }
71

72
        // Fetch default context
73
        // =====================
74
        // Default contexts can be defined by using the template name when rendering a
75
        // specific template, e.g. if $name = '@foo' then $rootData['@foo'] is requested
76
        $defaultContext = $rootData[$name] ?? [];
4✔
77

78
        // Resolve context
79
        // ===============
80
        // Use default context as new context if no custom context is given, otherwise
81
        // merge both contexts in case merge=true is passed as helper option, e.g.
82
        // {{render '@foo' customContext merge=true}}
83
        if ($context === []) {
4✔
84
            $context = $defaultContext;
1✔
85
        } elseif ($merge) {
3✔
86
            Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($defaultContext, $context);
1✔
87
            $context = $defaultContext;
1✔
88
        }
89

90
        if ($renderUncached) {
4✔
91
            $content = $this->registerUncachedTemplateBlock($name, $context);
1✔
92
        } else {
93
            $content = $this->renderer->render($name, $context);
3✔
94
        }
95

96
        return new SafeString($content);
4✔
97
    }
98

99
    /**
100
     * @param array<string, mixed> $context
101
     * @throws Exception\InvalidConfigurationException
102
     */
103
    protected function registerUncachedTemplateBlock(string $templateName, array $context): string
1✔
104
    {
105
        $processorClass = $context['_processor'] ?? null;
1✔
106

107
        // Check whether the required data processor is valid
108
        if (!\is_string($processorClass) || !\in_array(DataProcessing\DataProcessorInterface::class, class_implements($processorClass) ?: [])) {
1✔
UNCOV
109
            throw Exception\InvalidConfigurationException::create('_processor');
×
110
        }
111

112
        // Do not pass data processor reference as context to requested data processor
113
        unset($context['_processor']);
1✔
114

115
        return $this->contentObjectRenderer->cObjGetSingle('USER_INT', [
1✔
116
            'userFunc' => $processorClass . '->process',
1✔
117
            'userFunc.' => [
1✔
118
                'templatePath' => $templateName,
1✔
119
                'context.' => $this->typoScriptService->convertPlainArrayToTypoScriptArray($context),
1✔
120
            ],
1✔
121
        ]);
1✔
122
    }
123
}
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

© 2025 Coveralls, Inc