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

FluidTYPO3 / flux / 12937935992

23 Jan 2025 08:58PM UTC coverage: 93.28% (-0.01%) from 93.294%
12937935992

push

github

NamelessCoder
[TASK] Clean up DataAccessTrait test case

7038 of 7545 relevant lines covered (93.28%)

56.3 hits per line

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

88.45
/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\Hooks\HookHandler;
15
use FluidTYPO3\Flux\Integration\NormalizedData\DataAccessTrait;
16
use FluidTYPO3\Flux\Integration\Resolver;
17
use FluidTYPO3\Flux\Provider\Interfaces\ControllerProviderInterface;
18
use FluidTYPO3\Flux\Provider\Interfaces\DataStructureProviderInterface;
19
use FluidTYPO3\Flux\Provider\Interfaces\FluidProviderInterface;
20
use FluidTYPO3\Flux\Provider\ProviderResolver;
21
use FluidTYPO3\Flux\Service\TypoScriptService;
22
use FluidTYPO3\Flux\Service\WorkspacesAwareRecordService;
23
use FluidTYPO3\Flux\Utility\ContentObjectFetcher;
24
use FluidTYPO3\Flux\Utility\ExtensionNamingUtility;
25
use FluidTYPO3\Flux\Utility\RecursiveArrayUtility;
26
use FluidTYPO3\Flux\ViewHelpers\FormViewHelper;
27
use Psr\Http\Message\ResponseFactoryInterface;
28
use Psr\Http\Message\ServerRequestInterface;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
30
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
31
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
32
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
33
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
34
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerInterface;
35
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
36
use TYPO3\CMS\Extbase\Mvc\Request;
37
use TYPO3\CMS\Extbase\Mvc\Response;
38
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
39
use TYPO3\CMS\Fluid\View\TemplatePaths;
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 ?ControllerProviderInterface $provider = null;
71

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

87
        /** @var Arguments $arguments */
88
        $arguments = GeneralUtility::makeInstance(Arguments::class);
132✔
89
        $this->arguments = $arguments;
132✔
90

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

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

120
        if ($this->provider instanceof DataStructureProviderInterface) {
6✔
121
            $this->data = $this->provider->getFlexFormValues($row);
6✔
122
        }
123

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

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

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

186
    protected function initializeViewVariables(ViewInterface $view): void
187
    {
188
        $contentObject = $this->getContentObject();
6✔
189
        $row = $this->getRecord();
6✔
190

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

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

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

230
    protected function initializeAction(): void
231
    {
232
        $this->initializeProvider();
6✔
233
        $this->initializeSettings();
6✔
234
        $this->initializeOverriddenSettings();
6✔
235
    }
236

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

254
        /** @var TemplatePaths $templatePaths */
255
        $templatePaths = GeneralUtility::makeInstance(TemplatePaths::class, $extensionKey);
12✔
256

257
        /** @var RenderingContextInterface $renderingContext */
258
        $renderingContext = $view->getRenderingContext();
12✔
259

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

272
        $view->setRenderingContext($renderingContext);
12✔
273

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

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

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

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

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

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

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

384
                if (method_exists($this->request, 'setControllerExtensionName')) {
6✔
385
                    $this->request->setControllerExtensionName($vendorLessExtensionName);
4✔
386
                }
387

388
                if (method_exists($this->request, 'withControllerExtensionName')) {
6✔
389
                    $this->request = $this->request->withControllerExtensionName($vendorLessExtensionName);
5✔
390
                }
391

392
                if (method_exists($renderingContext, 'setRequest')) {
6✔
393
                    $renderingContext->setRequest($this->request);
×
394
                }
395

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

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

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

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

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

487
        /** @var ControllerInterface $potentialControllerInstance */
488
        $potentialControllerInstance = GeneralUtility::makeInstance($controllerClassName);
6✔
489

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

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

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

529
        return $response;
6✔
530
    }
531

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

542
    protected function getFluxRecordField(): ?string
543
    {
544
        return $this->fluxRecordField;
18✔
545
    }
546

547
    protected function getFluxTableName(): ?string
548
    {
549
        return $this->fluxTableName;
30✔
550
    }
551

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

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

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

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

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

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