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

FluidTYPO3 / flux / 15918415903

20 May 2025 10:36AM UTC coverage: 91.109% (-2.1%) from 93.21%
15918415903

push

github

NamelessCoder
[TASK] Lock phpstan version

6927 of 7603 relevant lines covered (91.11%)

9.53 hits per line

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

87.58
/Classes/Controller/AbstractFluxController.php
1
<?php
2
declare(strict_types=1);
3
namespace FluidTYPO3\Flux\Controller;
4

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

12
use FluidTYPO3\Flux\Builder\RenderingContextBuilder;
13
use FluidTYPO3\Flux\Builder\RequestBuilder;
14
use FluidTYPO3\Flux\Builder\ViewBuilder;
15
use FluidTYPO3\Flux\Hooks\HookHandler;
16
use FluidTYPO3\Flux\Integration\NormalizedData\DataAccessTrait;
17
use FluidTYPO3\Flux\Integration\Resolver;
18
use FluidTYPO3\Flux\Provider\Interfaces\ControllerProviderInterface;
19
use FluidTYPO3\Flux\Provider\Interfaces\DataStructureProviderInterface;
20
use FluidTYPO3\Flux\Provider\Interfaces\FluidProviderInterface;
21
use FluidTYPO3\Flux\Provider\ProviderResolver;
22
use FluidTYPO3\Flux\Service\TypoScriptService;
23
use FluidTYPO3\Flux\Service\WorkspacesAwareRecordService;
24
use FluidTYPO3\Flux\Utility\ContentObjectFetcher;
25
use FluidTYPO3\Flux\Utility\ExtensionNamingUtility;
26
use FluidTYPO3\Flux\Utility\RecursiveArrayUtility;
27
use FluidTYPO3\Flux\ViewHelpers\FormViewHelper;
28
use Psr\Http\Message\ResponseFactoryInterface;
29
use Psr\Http\Message\ServerRequestInterface;
30
use TYPO3\CMS\Core\Utility\GeneralUtility;
31
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
32
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
33
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
34
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
35
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerInterface;
36
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
37
use TYPO3\CMS\Extbase\Mvc\Request;
38
use TYPO3\CMS\Extbase\Mvc\Response;
39
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
40
use TYPO3\CMS\Fluid\View\TemplateView;
41
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
42
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
43
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
44
use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;
45
use TYPO3Fluid\Fluid\View\ViewInterface;
46

47
/**
48
 * Abstract Flux-enabled controller
49
 *
50
 * Extends a traditional ActionController with new services and methods
51
 * to ease interaction with Flux forms. Is not required as subclass for
52
 * Controllers rendering records associated with Flux - all it does is
53
 * ease the interaction by providing a common API.
54
 */
55
abstract class AbstractFluxController extends ActionController
56
{
57
    use DataAccessTrait;
58

59
    protected string $extensionName = 'FluidTYPO3.Flux';
60
    protected ?string $fluxRecordField = 'pi_flexform';
61
    protected ?string $fluxTableName = 'tt_content';
62
    protected array $data = [];
63

64
    protected RenderingContextBuilder $renderingContextBuilder;
65
    protected RequestBuilder $requestBuilder;
66
    protected WorkspacesAwareRecordService $recordService;
67
    protected TypoScriptService $typoScriptService;
68
    protected ProviderResolver $providerResolver;
69
    protected Resolver $resolver;
70
    protected ViewBuilder $viewBuilder;
71
    protected ?ControllerProviderInterface $provider = null;
72

73
    public function __construct(
74
        RenderingContextBuilder $renderingContextBuilder,
75
        RequestBuilder $requestBuilder,
76
        WorkspacesAwareRecordService $recordService,
77
        TypoScriptService $typoScriptService,
78
        ProviderResolver $providerResolver,
79
        Resolver $resolver,
80
        ViewBuilder $viewBuilder
81
    ) {
82
        $this->renderingContextBuilder = $renderingContextBuilder;
22✔
83
        $this->requestBuilder = $requestBuilder;
22✔
84
        $this->recordService = $recordService;
22✔
85
        $this->typoScriptService = $typoScriptService;
22✔
86
        $this->providerResolver = $providerResolver;
22✔
87
        $this->resolver = $resolver;
22✔
88
        $this->viewBuilder = $viewBuilder;
22✔
89

90
        /** @var Arguments $arguments */
91
        $arguments = GeneralUtility::makeInstance(Arguments::class);
22✔
92
        $this->arguments = $arguments;
22✔
93

94
        /** @var Request $request */
95
        $request = $requestBuilder->buildRequestFor(
22✔
96
            $this->extensionName,
22✔
97
            'Dummy',
22✔
98
            'render',
22✔
99
            '',
22✔
100
            [],
22✔
101
        );
22✔
102
        $this->request = $request;
22✔
103
    }
104

105
    protected function initializeSettings(): void
106
    {
107
        if ($this->provider === null) {
1✔
108
            return;
×
109
        }
110
        $row = $this->getRecord();
1✔
111
        $extensionKey = $this->provider->getControllerExtensionKeyFromRecord($row);
1✔
112
        $extensionName = ExtensionNamingUtility::getExtensionName($extensionKey);
1✔
113
        $pluginName = $this->request->getPluginName();
1✔
114
        $this->settings = RecursiveArrayUtility::merge(
1✔
115
            (array) $this->configurationManager->getConfiguration(
1✔
116
                ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
1✔
117
                $extensionName,
1✔
118
                $pluginName
1✔
119
            ),
1✔
120
            (array) $this->settings
1✔
121
        );
1✔
122

123
        if ($this->provider instanceof DataStructureProviderInterface) {
1✔
124
            $this->data = $this->provider->getFlexFormValues($row);
1✔
125
        }
126

127
        $overrides = HookHandler::trigger(
1✔
128
            HookHandler::CONTROLLER_SETTINGS_INITIALIZED,
1✔
129
            [
1✔
130
                'settings' => $this->settings,
1✔
131
                'data' => $this->data,
1✔
132
                'record' => $row,
1✔
133
                'provider' => $this->provider,
1✔
134
                'controller' => $this,
1✔
135
                'request' => $this->request,
1✔
136
                'extensionKey' => $extensionKey
1✔
137
            ]
1✔
138
        );
1✔
139
        $this->data = $overrides['data'];
1✔
140
        $this->settings = $overrides['settings'];
1✔
141
        $this->provider = $overrides['provider'];
1✔
142
    }
143

144
    protected function initializeOverriddenSettings(): void
145
    {
146
        if ($this->provider === null) {
5✔
147
            return;
×
148
        }
149
        $row = $this->getRecord();
5✔
150
        $extensionKey = $this->provider->getControllerExtensionKeyFromRecord($row);
5✔
151
        $extensionKey = ExtensionNamingUtility::getExtensionKey($extensionKey);
5✔
152
        if (is_array($this->data['settings'] ?? null)) {
5✔
153
            // a "settings." array is defined in the flexform configuration - extract it, use as "settings" in template
154
            // as well as the internal $this->settings array as per expected Extbase behavior.
155
            $this->settings = RecursiveArrayUtility::merge($this->settings, $this->data['settings'] ?? []);
4✔
156
        }
157
        if ($this->settings['useTypoScript'] ?? false) {
5✔
158
            // an override shared by all Flux enabled controllers: setting plugin.tx_EXTKEY.settings.useTypoScript = 1
159
            // will read the "settings" array from that location instead - thus excluding variables from the flexform
160
            // which are still available as $this->data but no longer available automatically in the template.
161
            $this->settings = $this->typoScriptService->getSettingsForExtensionName($extensionKey);
3✔
162
        }
163
    }
164

165
    protected function initializeProvider(): void
166
    {
167
        $row = $this->getRecord();
4✔
168
        $table = (string) $this->getFluxTableName();
4✔
169
        $field = $this->getFluxRecordField();
4✔
170
        $provider = $this->providerResolver->resolvePrimaryConfigurationProvider(
4✔
171
            $table,
4✔
172
            $field,
4✔
173
            $row,
4✔
174
            null,
4✔
175
            [ControllerProviderInterface::class]
4✔
176
        );
4✔
177
        if ($provider === null) {
4✔
178
            throw new \RuntimeException(
1✔
179
                'Unable to resolve a ConfigurationProvider, but controller indicates it is a Flux-enabled ' .
1✔
180
                'Controller - this is a grave error and indicates that EXT: ' . $this->extensionName . ' itself is ' .
1✔
181
                'broken - or that EXT:' . $this->extensionName . ' has been overridden by another implementation ' .
1✔
182
                'which is broken. The controller that caused this error was ' . get_class($this) . '".',
1✔
183
                1377458581
1✔
184
            );
1✔
185
        }
186
        $this->provider = $provider;
3✔
187
    }
188

189
    protected function initializeViewVariables(ViewInterface $view): void
190
    {
191
        $contentObject = $this->getContentObject();
1✔
192
        $row = $this->getRecord();
1✔
193

194
        $view->assign('contentObject', $contentObject);
1✔
195
        $view->assign('data', $contentObject instanceof ContentObjectRenderer ? $contentObject->data : null);
1✔
196
        if ($this->provider instanceof FluidProviderInterface) {
1✔
197
            $view->assignMultiple($this->provider->getTemplateVariables($row));
1✔
198
        }
199
        $view->assignMultiple($this->data);
1✔
200
        $view->assign('settings', $this->settings);
1✔
201
        $view->assign('provider', $this->provider);
1✔
202
        $view->assign('record', $row);
1✔
203

204
        HookHandler::trigger(
1✔
205
            HookHandler::CONTROLLER_VARIABLES_ASSIGNED,
1✔
206
            [
1✔
207
                'view' => $view,
1✔
208
                'record' => $row,
1✔
209
                'settings' => $this->settings,
1✔
210
                'provider' => $this->provider,
1✔
211
                'contentObject' => $contentObject,
1✔
212
            ]
1✔
213
        );
1✔
214
    }
215

216
    protected function initializeViewHelperVariableContainer(
217
        ViewHelperVariableContainer $viewHelperVariableContainer
218
    ): void {
219
        $viewHelperVariableContainer->add(FormViewHelper::class, 'provider', $this->provider);
1✔
220
        $viewHelperVariableContainer->add(
1✔
221
            FormViewHelper::class,
1✔
222
            'extensionName',
1✔
223
            $this->request->getControllerExtensionKey()
1✔
224
        );
1✔
225
        $viewHelperVariableContainer->add(
1✔
226
            FormViewHelper::class,
1✔
227
            'pluginName',
1✔
228
            $this->request->getPluginName()
1✔
229
        );
1✔
230
        $viewHelperVariableContainer->add(FormViewHelper::class, 'record', $this->getRecord());
1✔
231
    }
232

233
    protected function initializeAction(): void
234
    {
235
        $this->initializeProvider();
1✔
236
        $this->initializeSettings();
1✔
237
        $this->initializeOverriddenSettings();
1✔
238
    }
239

240
    protected function resolveView(): ViewInterface
241
    {
242
        if (!$this->provider instanceof ControllerProviderInterface) {
2✔
243
            throw new \RuntimeException(
×
244
                get_class($this) . ' cannot handle record; no ControllerProviderInterface could be resolved',
×
245
                1672082347
×
246
            );
×
247
        }
248
        /** @var TemplateView $view */
249
        $view = GeneralUtility::makeInstance(TemplateView::class);
2✔
250
        $record = $this->getRecord();
2✔
251
        $extensionKey = ExtensionNamingUtility::getExtensionKey(
2✔
252
            $this->provider->getControllerExtensionKeyFromRecord($record)
2✔
253
        );
2✔
254
        $extensionName = ExtensionNamingUtility::getExtensionName($extensionKey);
2✔
255
        $controllerActionName = $this->provider->getControllerActionFromRecord($record);
2✔
256

257
        $templatePaths = $this->viewBuilder->buildTemplatePaths($extensionKey);
2✔
258

259
        /** @var RenderingContextInterface $renderingContext */
260
        $renderingContext = $view->getRenderingContext();
2✔
261

262
        $renderingContext = $this->renderingContextBuilder->buildRenderingContextFor(
2✔
263
            $extensionName,
2✔
264
            $this->resolver->resolveControllerNameFromControllerClassName(get_class($this)),
2✔
265
            $controllerActionName,
2✔
266
            $this->provider->getPluginName() ?? $this->provider->getControllerNameFromRecord($record)
2✔
267
        );
2✔
268
        if (method_exists($renderingContext, 'setRequest')) {
2✔
269
            $renderingContext->setRequest($this->request);
×
270
        }
271
        $renderingContext->setTemplatePaths($templatePaths);
2✔
272
        $renderingContext->setControllerAction($controllerActionName);
2✔
273

274
        $view->setRenderingContext($renderingContext);
2✔
275

276
        $this->initializeViewVariables($view);
2✔
277
        $this->initializeViewHelperVariableContainer($renderingContext->getViewHelperVariableContainer());
2✔
278
        HookHandler::trigger(
2✔
279
            HookHandler::CONTROLLER_VIEW_INITIALIZED,
2✔
280
            [
2✔
281
                'view' => $view,
2✔
282
                'request' => $this->request,
2✔
283
                'provider' => $this->provider,
2✔
284
                'controller' => $this,
2✔
285
                'extensionKey' => $extensionKey
2✔
286
            ]
2✔
287
        );
2✔
288
        return $view;
2✔
289
    }
290

291
    /**
292
     * @return \Psr\Http\Message\ResponseInterface|Response
293
     */
294
    protected function createHtmlResponse(string $html = null)
295
    {
296
        if (method_exists($this, 'htmlResponse')) {
×
297
            return parent::htmlResponse($html);
×
298
        }
299
        $response = clone $this->response;
×
300
        $response->setContent((string) $html);
×
301
        return $response;
×
302
    }
303

304
    /**
305
     * Default action, proxy for "render". Added in order to
306
     * capture requests which use the Fluid-native "default"
307
     * action name when no specific action name is set in the
308
     * request. The "default" action is also returned by
309
     * vanilla Provider instances when registering them for
310
     * content object types or other ad-hoc registrations.
311
     *
312
     * @return \Psr\Http\Message\ResponseInterface|Response|ResponseInterface
313
     */
314
    public function defaultAction()
315
    {
316
        return $this->renderAction();
1✔
317
    }
318

319
    /**
320
     * Render content
321
     *
322
     * @return \Psr\Http\Message\ResponseInterface|Response|ResponseInterface
323
     */
324
    public function renderAction()
325
    {
326
        if (!$this->provider instanceof ControllerProviderInterface) {
2✔
327
            throw new \RuntimeException(
1✔
328
                get_class($this) . ' cannot handle record; no ControllerProviderInterface could be resolved',
1✔
329
                1672082347
1✔
330
            );
1✔
331
        }
332
        $row = $this->getRecord();
1✔
333
        $extensionKey = $this->provider->getControllerExtensionKeyFromRecord($row);
1✔
334
        $extensionSignature = ExtensionNamingUtility::getExtensionSignature($extensionKey);
1✔
335
        $pluginName = $this->request->getPluginName();
1✔
336
        $pluginSignature = strtolower('tx_' . $extensionSignature . '_' . $pluginName);
1✔
337
        $controllerExtensionKey = $this->provider->getControllerExtensionKeyFromRecord($row);
1✔
338
        $requestActionName = $this->resolveOverriddenFluxControllerActionNameFromRequestParameters($pluginSignature);
1✔
339
        $controllerActionName = $this->provider->getControllerActionFromRecord($row);
1✔
340
        $actualActionName = null !== $requestActionName ? $requestActionName : $controllerActionName;
1✔
341
        $controllerName = $this->request->getControllerName();
1✔
342

343
        return $this->performSubRendering(
1✔
344
            $controllerExtensionKey,
1✔
345
            $controllerName,
1✔
346
            $actualActionName,
1✔
347
            $pluginName,
1✔
348
            $pluginSignature
1✔
349
        );
1✔
350
    }
351

352
    protected function resolveOverriddenFluxControllerActionNameFromRequestParameters(string $pluginSignature): ?string
353
    {
354
        return $this->getServerRequest()->getQueryParams()[$pluginSignature]['action'] ?? null;
1✔
355
    }
356

357
    /**
358
     * @return \Psr\Http\Message\ResponseInterface|Response|ResponseInterface
359
     */
360
    protected function performSubRendering(
361
        string $extensionName,
362
        string $controllerName,
363
        string $actionName,
364
        string $pluginName,
365
        string $pluginSignature
366
    ) {
367
        if (property_exists($this, 'responseFactory') && $this->responseFactory instanceof ResponseFactoryInterface) {
3✔
368
            $response = $this->responseFactory->createResponse();
3✔
369
        } else {
370
            /** @var ResponseInterface $response */
371
            $response = GeneralUtility::makeInstance(Response::class);
×
372
        }
373
    
374
        $shouldRelay = $this->hasSubControllerActionOnForeignController($extensionName, $controllerName, $actionName);
3✔
375
        $foreignControllerClass = null;
3✔
376
        $content = null;
3✔
377
        if (!$shouldRelay) {
3✔
378
            if ($this->provider instanceof FluidProviderInterface) {
2✔
379
                $templatePathAndFilename = $this->provider->getTemplatePathAndFilename($this->getRecord());
1✔
380
                $vendorLessExtensionName = ExtensionNamingUtility::getExtensionName($extensionName);
1✔
381
                /** @var TemplateView $view */
382
                $view = $this->view;
1✔
383
                $renderingContext = $view->getRenderingContext();
1✔
384
                $paths = $renderingContext->getTemplatePaths();
1✔
385

386
                if (method_exists($this->request, 'setControllerExtensionName')) {
1✔
387
                    $this->request->setControllerExtensionName($vendorLessExtensionName);
1✔
388
                }
389

390
                if (method_exists($this->request, 'withControllerExtensionName')) {
1✔
391
                    $this->request = $this->request->withControllerExtensionName($vendorLessExtensionName);
1✔
392
                }
393

394
                if (method_exists($renderingContext, 'setRequest')) {
1✔
395
                    $renderingContext->setRequest($this->request);
×
396
                }
397

398
                $this->configurationManager->setConfiguration(
1✔
399
                    array_merge(
1✔
400
                        (array) $this->configurationManager->getConfiguration(
1✔
401
                            ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT,
1✔
402
                            $vendorLessExtensionName
1✔
403
                        ),
1✔
404
                        [
1✔
405
                            'extensionName' => $vendorLessExtensionName,
1✔
406
                        ]
1✔
407
                    )
1✔
408
                );
1✔
409
                $paths->fillDefaultsByPackageName(
1✔
410
                    GeneralUtility::camelCaseToLowerCaseUnderscored($vendorLessExtensionName)
1✔
411
                );
1✔
412
                $paths->setTemplatePathAndFilename((string) $templatePathAndFilename);
1✔
413
            }
414
            $content = $this->view->render();
2✔
415
        } else {
416
            $foreignControllerClass = $this->resolver->resolveFluxControllerClassNameByExtensionKeyAndControllerName(
1✔
417
                $extensionName,
1✔
418
                $controllerName
1✔
419
            );
1✔
420
            $content = $this->callSubControllerAction(
1✔
421
                $extensionName,
1✔
422
                $foreignControllerClass ?? static::class,
1✔
423
                $actionName,
1✔
424
                $pluginName,
1✔
425
                $pluginSignature
1✔
426
            );
1✔
427
        }
428
        $content = HookHandler::trigger(
3✔
429
            HookHandler::CONTROLLER_AFTER_RENDERING,
3✔
430
            [
3✔
431
                'view' => $this->view,
3✔
432
                'content' => $content,
3✔
433
                'request' => $this->request,
3✔
434
                'response' => $response,
3✔
435
                'extensionName' => $extensionName,
3✔
436
                'controllerClassName' => $foreignControllerClass,
3✔
437
                'controllerActionName' => $actionName
3✔
438
            ]
3✔
439
        )['content'];
3✔
440

441
        return $content instanceof \Psr\Http\Message\ResponseInterface || $content instanceof ResponseInterface
3✔
442
            ? $content
×
443
            : $this->createHtmlResponse($content);
3✔
444
    }
445

446
    protected function hasSubControllerActionOnForeignController(
447
        string $extensionName,
448
        string $controllerName,
449
        string $actionName
450
    ): bool {
451
        $potentialControllerClassName = $this->resolver->resolveFluxControllerClassNameByExtensionKeyAndControllerName(
1✔
452
            $extensionName,
1✔
453
            $controllerName
1✔
454
        );
1✔
455
        if ($potentialControllerClassName === null) {
1✔
456
            return false;
1✔
457
        }
458
        $isNotThis = get_class($this) !== $potentialControllerClassName;
×
459
        $isValidController = class_exists($potentialControllerClassName);
×
460
        return ($isNotThis && $isValidController
×
461
            && method_exists($potentialControllerClassName, $actionName . 'Action'));
×
462
    }
463

464
    /**
465
     * @param class-string $controllerClassName
466
     * @return \Psr\Http\Message\ResponseInterface|ResponseInterface|null
467
     */
468
    protected function callSubControllerAction(
469
        string $extensionName,
470
        string $controllerClassName,
471
        string $controllerActionName,
472
        string $pluginName,
473
        string $pluginSignature
474
    ) {
475
        $serverRequest = $this->getServerRequest();
1✔
476
        $arguments = $serverRequest->getQueryParams()[$pluginSignature] ?? [];
1✔
477
        $arguments = array_merge($arguments, ((array) $serverRequest->getParsedBody())[$pluginSignature] ?? []);
1✔
478

479
        $request = $this->requestBuilder->buildRequestFor(
1✔
480
            $extensionName,
1✔
481
            $this->resolver->resolveControllerNameFromControllerClassName(
1✔
482
                $controllerClassName
1✔
483
            ),
1✔
484
            $controllerActionName,
1✔
485
            $pluginName,
1✔
486
            $arguments
1✔
487
        );
1✔
488

489
        /** @var ControllerInterface $potentialControllerInstance */
490
        $potentialControllerInstance = GeneralUtility::makeInstance($controllerClassName);
1✔
491

492
        if (property_exists($this, 'responseFactory') && $this->responseFactory instanceof ResponseFactoryInterface) {
1✔
493
            /** @var ResponseInterface\ $response */
494
            $response = $this->responseFactory->createResponse();
1✔
495
        } else {
496
            /** @var ResponseInterface $response */
497
            $response = GeneralUtility::makeInstance(Response::class);
×
498
        }
499

500
        try {
501
            HookHandler::trigger(
1✔
502
                HookHandler::CONTROLLER_BEFORE_REQUEST,
1✔
503
                [
1✔
504
                    'request' => $this->request,
1✔
505
                    'response' => $response,
1✔
506
                    'extensionName' => $extensionName,
1✔
507
                    'controllerClassName' => $controllerClassName,
1✔
508
                    'controllerActionName' => $controllerActionName
1✔
509
                ]
1✔
510
            );
1✔
511

512
            /** @var \Psr\Http\Message\ResponseInterface|ResponseInterface|null $responseFromCall */
513
            $responseFromCall = $potentialControllerInstance->processRequest($request, $response);
1✔
514
            if ($responseFromCall) {
1✔
515
                $response = $responseFromCall;
1✔
516
            }
517
        } catch (StopActionException $error) {
×
518
            // intentionally left blank
519
        }
520
        HookHandler::trigger(
1✔
521
            HookHandler::CONTROLLER_AFTER_REQUEST,
1✔
522
            [
1✔
523
                'request' => $this->request,
1✔
524
                'response' => $response,
1✔
525
                'extensionName' => $extensionName,
1✔
526
                'controllerClassName' => $controllerClassName,
1✔
527
                'controllerActionName' => $controllerActionName
1✔
528
            ]
1✔
529
        );
1✔
530

531
        return $response;
1✔
532
    }
533

534
    /**
535
     * Get the data stored in a record's Flux-enabled field,
536
     * i.e. the variables of the Flux template as configured in this
537
     * particular record.
538
     */
539
    protected function getData(): array
540
    {
541
        return $this->data;
1✔
542
    }
543

544
    protected function getFluxRecordField(): ?string
545
    {
546
        return $this->fluxRecordField;
3✔
547
    }
548

549
    protected function getFluxTableName(): ?string
550
    {
551
        return $this->fluxTableName;
5✔
552
    }
553

554
    public function getRecord(): array
555
    {
556
        $contentObject = $this->getContentObject();
4✔
557
        if ($contentObject === null) {
4✔
558
            throw new \UnexpectedValueException(
1✔
559
                "Record of table " . $this->getFluxTableName() . ' not found',
1✔
560
                1666538343
1✔
561
            );
1✔
562
        }
563

564
        if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '11.5', '<')) {
3✔
565
            /** @var TypoScriptFrontendController|null $tsfe */
566
            $tsfe = $GLOBALS['TSFE'] ?? null;
×
567
        } else {
568
            $tsfe = $contentObject->getTypoScriptFrontendController();
3✔
569
        }
570
        if ($tsfe === null) {
3✔
571
            throw new \UnexpectedValueException(
×
572
                "Record of table " . $this->getFluxTableName() . ' not found',
×
573
                1729864782
×
574
            );
×
575
        }
576

577
        [$table, $recordUid] = GeneralUtility::trimExplode(
3✔
578
            ':',
3✔
579
            $tsfe->currentRecord ?: $contentObject->currentRecord
3✔
580
        );
3✔
581
        $record = $this->recordService->getSingle($table, '*', (integer) $recordUid);
3✔
582
        if ($record === null) {
3✔
583
            throw new \UnexpectedValueException(
×
584
                "Record of table " . $this->getFluxTableName() . ' not found',
×
585
                1729864698
×
586
            );
×
587
        }
588

589
        if ($record['_LOCALIZED_UID'] ?? false) {
3✔
590
            $record = array_merge(
×
591
                $record,
×
592
                $this->recordService->getSingle(
×
593
                    (string) $this->getFluxTableName(),
×
594
                    '*',
×
595
                    $record['_LOCALIZED_UID']
×
596
                ) ?? $record
×
597
            );
×
598
        }
599
        return $record;
3✔
600
    }
601

602
    protected function getContentObject(): ?ContentObjectRenderer
603
    {
604
        return ContentObjectFetcher::resolve($this->configurationManager);
×
605
    }
606

607
    protected function getServerRequest(): ServerRequestInterface
608
    {
609
        /** @var ServerRequestInterface $request */
610
        $request = $GLOBALS['TYPO3_REQUEST'];
×
611
        return $request;
×
612
    }
613
}
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