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

FluidTYPO3 / vhs / 30001290505

23 Jul 2026 10:57AM UTC coverage: 70.309% (-1.7%) from 72.022%
30001290505

push

github

NamelessCoder
[TER] 8.0.0

4819 of 6854 relevant lines covered (70.31%)

6.54 hits per line

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

31.15
/Classes/ViewHelpers/Render/UncacheViewHelper.php
1
<?php
2
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
3

4
/*
5
 * This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.md file that was distributed with this source code.
9
 */
10

11
use FluidTYPO3\Vhs\Core\ViewHelper\AbstractViewHelper;
12
use FluidTYPO3\Vhs\Utility\ContentObjectFetcher;
13
use FluidTYPO3\Vhs\Utility\RequestResolver;
14
use FluidTYPO3\Vhs\View\UncacheContentObject;
15
use FluidTYPO3\Vhs\View\UncacheTemplateView;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
18
use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
19
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
20
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
21
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
22
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
23

24
/**
25
 * Uncaches partials. Use like ``f:render``.
26
 * The partial will then be rendered each time.
27
 * Please be aware that this will impact render time.
28
 * Arguments must be serializable and will be cached.
29
 */
30
class UncacheViewHelper extends AbstractViewHelper
31
{
32
    /**
33
     * @var boolean
34
     */
35
    protected $escapeOutput = false;
36

37
    public function initializeArguments(): void
38
    {
39
        $this->registerArgument('partial', 'string', 'Reference to a partial.', true);
3✔
40
        $this->registerArgument('section', 'string', 'Name of section inside the partial to render.');
3✔
41
        $this->registerArgument('arguments', 'array', 'Arguments to pass to the partial.');
3✔
42
        $this->registerArgument(
3✔
43
            'persistPartialPaths',
3✔
44
            'bool',
3✔
45
            'Normally, v:render.uncache will persist the partialRootPaths array that was active when the ViewHelper' .
3✔
46
            'was called, so the exact paths will be reused when rendering the uncached portion of the page output. ' .
3✔
47
            'This is done to ensure that even if you manually added some partial paths through some dynamic means (' .
3✔
48
            'for example, based on a controller argument) then those paths would be used. However, in some cases ' .
3✔
49
            'this will be undesirable - namely when using a cache that is shared between multiple TYPO3 instances ' .
3✔
50
            'and each instance has a different path in the server\'s file system (e.g. load balanced setups). ' .
3✔
51
            'On such setups you should set persistPartialPaths="0" on this ViewHelper to prevent it from caching ' .
3✔
52
            'the resolved partialRootPaths. The ViewHelper will then instead use whichever partialRootPaths are ' .
3✔
53
            'configured for the extension that calls `v:render.uncache`. Note that when this is done, the special ' .
3✔
54
            'use case of dynamic or controller-overridden partialRootPaths is simply not supported.',
3✔
55
            false,
3✔
56
            true
3✔
57
        );
3✔
58
    }
59

60
    /**
61
     * @return mixed
62
     */
63
    public static function renderStatic(
64
        array $arguments,
65
        \Closure $renderChildrenClosure,
66
        RenderingContextInterface $renderingContext
67
    ) {
68
        /** @var RenderingContext $renderingContext */
69
        $templateVariableContainer = $renderingContext->getVariableProvider();
×
70
        $partialArguments = $arguments['arguments'];
×
71
        if (!is_array($partialArguments)) {
×
72
            $partialArguments = (array) $partialArguments;
×
73
        }
74
        if (!isset($partialArguments['settings']) && $templateVariableContainer->exists('settings')) {
×
75
            $partialArguments['settings'] = $templateVariableContainer->get('settings');
×
76
        }
77

78
        $substKey = 'INT_SCRIPT.' . $GLOBALS['TSFE']->uniqueHash();
×
79
        $content = '<!--' . $substKey . '-->';
×
80

81
        $request = RequestResolver::resolveRequestFromRenderingContext($renderingContext);
×
82

83
        if (class_exists(ExtbaseRequestParameters::class) && method_exists($request, 'getAttribute')) {
×
84
            /** @var ExtbaseRequestParameters $extbaseParameters */
85
            $extbaseParameters = $request->getAttribute('extbase');
×
86
        } else {
87
            $extbaseParameters = [
×
88
                'actionName' => RequestResolver::resolveControllerActionNameFromRequest($request),
×
89
                'extensionName' => RequestResolver::resolveControllerExtensionNameFromRequest($request),
×
90
                'controllerName' => RequestResolver::resolveControllerNameFromRequest($request),
×
91
                'controllerObjectName' => RequestResolver::resolveControllerObjectNameFromRequest($request),
×
92
                'pluginName' => RequestResolver::resolvePluginNameFromRequest($request),
×
93
                'format' => RequestResolver::resolveFormatFromRequest($request),
×
94
            ];
×
95
        }
96

97
        $conf = [
×
98
            'userFunc' => UncacheTemplateView::class . '->callUserFunction',
×
99
            'partial' => $arguments['partial'],
×
100
            'section' => $arguments['section'],
×
101
            'arguments' => $partialArguments,
×
102
            'controllerContext' => $extbaseParameters,
×
103
        ];
×
104

105
        if ($arguments['persistPartialPaths'] ?? true) {
×
106
            $conf['partialRootPaths'] = $renderingContext->getTemplatePaths()->getPartialRootPaths();
×
107
        }
108

109
        $contentObjectRenderer = static::getContentObject();
×
110

111
        $content = $contentObjectRenderer->cObjGetSingle(
×
112
            'COA_INT',
×
113
            [
×
114
                '10' => 'USER',
×
115
                '10.' => $conf,
×
116
            ]
×
117
        );
×
118
        return $content;
×
119
    }
120

121
    protected static function getContentObject(): ContentObjectRenderer
122
    {
123
        /** @var ConfigurationManagerInterface $configurationManager */
124
        $configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
×
125
        /** @var ContentObjectRenderer|null $contentObject */
126
        $contentObject = ContentObjectFetcher::resolve($configurationManager);
×
127
        if ($contentObject === null) {
×
128
            throw new Exception('v:render.uncache requires a ContentObjectRenderer, none found', 1737808465);
×
129
        }
130
        return $contentObject;
×
131
    }
132
}
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