Passed
Push — master ( 57b5b6...1bd009 )
by
unknown
47:04 queued 32:28
created

FormManagerController   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 544
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 55
eloc 201
dl 0
loc 544
rs 6
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A initializeCreateAction() 0 3 1
A indexAction() 0 12 2
A injectDatabaseService() 0 3 1
A isValidTemplatePath() 0 22 6
A getRecordTitle() 0 3 1
A registerDocheaderButtons() 0 25 1
A getAccessibleFormStorageFolders() 0 20 4
A convertFormNameToIdentifier() 0 8 1
A referencesAction() 0 13 2
A getProcessedReferencesRows() 0 34 5
A getAvailableFormDefinitions() 0 22 5
A getRecord() 0 3 1
A initializeReferencesAction() 0 3 1
A getModuleUrl() 0 5 1
A getFormManagerAppInitialData() 0 19 1
A getPageRenderer() 0 3 1
A getBackendUser() 0 3 1
A deleteAction() 0 31 5
A getLanguageService() 0 3 1
B duplicateAction() 0 45 6
B createAction() 0 51 7
A initializeDuplicateAction() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like FormManagerController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FormManagerController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
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 TYPO3\CMS\Form\Controller;
19
20
use Symfony\Component\Yaml\Yaml;
21
use TYPO3\CMS\Backend\Routing\UriBuilder;
22
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
23
use TYPO3\CMS\Backend\Utility\BackendUtility;
24
use TYPO3\CMS\Backend\View\BackendTemplateView;
25
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
26
use TYPO3\CMS\Core\Charset\CharsetConverter;
27
use TYPO3\CMS\Core\Imaging\Icon;
28
use TYPO3\CMS\Core\Imaging\IconFactory;
29
use TYPO3\CMS\Core\Localization\LanguageService;
30
use TYPO3\CMS\Core\Messaging\AbstractMessage;
31
use TYPO3\CMS\Core\Page\PageRenderer;
32
use TYPO3\CMS\Core\Utility\ArrayUtility;
33
use TYPO3\CMS\Core\Utility\GeneralUtility;
34
use TYPO3\CMS\Extbase\Mvc\View\JsonView;
35
use TYPO3\CMS\Form\Exception as FormException;
36
use TYPO3\CMS\Form\Mvc\Persistence\Exception\PersistenceManagerException;
37
use TYPO3\CMS\Form\Service\DatabaseService;
38
use TYPO3\CMS\Form\Service\TranslationService;
39
40
/**
41
 * The form manager controller
42
 *
43
 * Scope: backend
44
 * @internal
45
 */
46
class FormManagerController extends AbstractBackendController
47
{
48
49
    /**
50
     * @var DatabaseService
51
     */
52
    protected $databaseService;
53
54
    /**
55
     * @param \TYPO3\CMS\Form\Service\DatabaseService $databaseService
56
     * @internal
57
     */
58
    public function injectDatabaseService(DatabaseService $databaseService)
59
    {
60
        $this->databaseService = $databaseService;
61
    }
62
63
    /**
64
     * Default View Container
65
     *
66
     * @var string
67
     */
68
    protected $defaultViewObjectName = BackendTemplateView::class;
69
70
    /**
71
     * Displays the Form Manager
72
     *
73
     * @internal
74
     */
75
    public function indexAction()
76
    {
77
        $this->registerDocheaderButtons();
78
        $this->view->getModuleTemplate()->setModuleName($this->request->getPluginName() . '_' . $this->request->getControllerName());
0 ignored issues
show
Bug introduced by
The method getModuleTemplate() does not exist on TYPO3\CMS\Extbase\Mvc\View\ViewInterface. It seems like you code against a sub-type of TYPO3\CMS\Extbase\Mvc\View\ViewInterface such as TYPO3\CMS\Extbase\Mvc\View\EmptyView or TYPO3\CMS\Backend\View\BackendTemplateView or TYPO3\CMS\Extbase\Mvc\View\NotFoundView. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

78
        $this->view->/** @scrutinizer ignore-call */ 
79
                     getModuleTemplate()->setModuleName($this->request->getPluginName() . '_' . $this->request->getControllerName());
Loading history...
79
        $this->view->getModuleTemplate()->setFlashMessageQueue($this->getFlashMessageQueue());
80
81
        $this->view->assign('forms', $this->getAvailableFormDefinitions());
82
        $this->view->assign('stylesheets', $this->resolveResourcePaths($this->formSettings['formManager']['stylesheets']));
83
        $this->view->assign('dynamicRequireJsModules', $this->formSettings['formManager']['dynamicRequireJsModules']);
84
        $this->view->assign('formManagerAppInitialData', $this->getFormManagerAppInitialData());
85
        if (!empty($this->formSettings['formManager']['javaScriptTranslationFile'])) {
86
            $this->getPageRenderer()->addInlineLanguageLabelFile($this->formSettings['formManager']['javaScriptTranslationFile']);
87
        }
88
    }
89
90
    /**
91
     * Initialize the create action.
92
     * This action uses the Fluid JsonView::class as view.
93
     *
94
     * @internal
95
     */
96
    public function initializeCreateAction()
97
    {
98
        $this->defaultViewObjectName = JsonView::class;
99
    }
100
101
    /**
102
     * Creates a new Form and redirects to the Form Editor
103
     *
104
     * @param string $formName
105
     * @param string $templatePath
106
     * @param string $prototypeName
107
     * @param string $savePath
108
     * @throws FormException
109
     * @throws PersistenceManagerException
110
     * @internal
111
     */
112
    public function createAction(string $formName, string $templatePath, string $prototypeName, string $savePath)
113
    {
114
        if (!$this->formPersistenceManager->isAllowedPersistencePath($savePath)) {
0 ignored issues
show
Bug introduced by
The method isAllowedPersistencePath() does not exist on TYPO3\CMS\Form\Mvc\Persi...istenceManagerInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to TYPO3\CMS\Form\Mvc\Persi...istenceManagerInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

114
        if (!$this->formPersistenceManager->/** @scrutinizer ignore-call */ isAllowedPersistencePath($savePath)) {
Loading history...
115
            throw new PersistenceManagerException(sprintf('Save to path "%s" is not allowed', $savePath), 1614500657);
116
        }
117
118
        if (!$this->isValidTemplatePath($prototypeName, $templatePath)) {
119
            throw new FormException(sprintf('The template path "%s" is not allowed', $templatePath), 1329233410);
120
        }
121
        if (empty($formName)) {
122
            throw new FormException('No form name', 1472312204);
123
        }
124
125
        $templatePath = GeneralUtility::getFileAbsFileName($templatePath);
126
        $form = Yaml::parse((string)file_get_contents($templatePath));
127
        $form['label'] = $formName;
128
        $form['identifier'] = $this->formPersistenceManager->getUniqueIdentifier($this->convertFormNameToIdentifier($formName));
0 ignored issues
show
Bug introduced by
The method getUniqueIdentifier() does not exist on TYPO3\CMS\Form\Mvc\Persi...istenceManagerInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to TYPO3\CMS\Form\Mvc\Persi...istenceManagerInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

128
        /** @scrutinizer ignore-call */ 
129
        $form['identifier'] = $this->formPersistenceManager->getUniqueIdentifier($this->convertFormNameToIdentifier($formName));
Loading history...
129
        $form['prototypeName'] = $prototypeName;
130
131
        $formPersistenceIdentifier = $this->formPersistenceManager->getUniquePersistenceIdentifier($form['identifier'], $savePath);
132
133
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormCreate'] ?? [] as $className) {
134
            $hookObj = GeneralUtility::makeInstance($className);
135
            if (method_exists($hookObj, 'beforeFormCreate')) {
136
                $form = $hookObj->beforeFormCreate(
137
                    $formPersistenceIdentifier,
138
                    $form
139
                );
140
            }
141
        }
142
143
        $response = [
144
            'status' => 'success',
145
            'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor')
146
        ];
147
148
        try {
149
            $this->formPersistenceManager->save($formPersistenceIdentifier, $form);
150
        } catch (PersistenceManagerException $e) {
151
            $response = [
152
                'status' => 'error',
153
                'message' => $e->getMessage(),
154
                'code' => $e->getCode(),
155
            ];
156
        }
157
158
        $this->view->assign('response', $response);
159
        // createAction uses the Extbase JsonView::class.
160
        // That's why we have to set the view variables in this way.
161
        $this->view->setVariablesToRender([
0 ignored issues
show
Bug introduced by
The method setVariablesToRender() does not exist on TYPO3\CMS\Extbase\Mvc\View\ViewInterface. It seems like you code against a sub-type of TYPO3\CMS\Extbase\Mvc\View\ViewInterface such as TYPO3\CMS\Extbase\Mvc\View\EmptyView or TYPO3\CMS\Extbase\Mvc\View\NotFoundView or TYPO3\CMS\Extbase\Mvc\View\JsonView. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

161
        $this->view->/** @scrutinizer ignore-call */ 
162
                     setVariablesToRender([
Loading history...
162
            'response',
163
        ]);
164
    }
165
166
    /**
167
     * Initialize the duplicate action.
168
     * This action uses the Fluid JsonView::class as view.
169
     *
170
     * @internal
171
     */
172
    public function initializeDuplicateAction()
173
    {
174
        $this->defaultViewObjectName = JsonView::class;
175
    }
176
177
    /**
178
     * Duplicates a given formDefinition and redirects to the Form Editor
179
     *
180
     * @param string $formName
181
     * @param string $formPersistenceIdentifier persistence identifier of the form to duplicate
182
     * @param string $savePath
183
     * @throws PersistenceManagerException
184
     * @internal
185
     */
186
    public function duplicateAction(string $formName, string $formPersistenceIdentifier, string $savePath)
187
    {
188
        if (!$this->formPersistenceManager->isAllowedPersistencePath($savePath)) {
189
            throw new PersistenceManagerException(sprintf('Save to path "%s" is not allowed', $savePath), 1614500658);
190
        }
191
        if (!$this->formPersistenceManager->isAllowedPersistencePath($formPersistenceIdentifier)) {
192
            throw new PersistenceManagerException(sprintf('Read of "%s" is not allowed', $formPersistenceIdentifier), 1614500659);
193
        }
194
195
        $formToDuplicate = $this->formPersistenceManager->load($formPersistenceIdentifier);
196
        $formToDuplicate['label'] = $formName;
197
        $formToDuplicate['identifier'] = $this->formPersistenceManager->getUniqueIdentifier($this->convertFormNameToIdentifier($formName));
198
199
        $formPersistenceIdentifier = $this->formPersistenceManager->getUniquePersistenceIdentifier($formToDuplicate['identifier'], $savePath);
200
201
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDuplicate'] ?? [] as $className) {
202
            $hookObj = GeneralUtility::makeInstance($className);
203
            if (method_exists($hookObj, 'beforeFormDuplicate')) {
204
                $formToDuplicate = $hookObj->beforeFormDuplicate(
205
                    $formPersistenceIdentifier,
206
                    $formToDuplicate
207
                );
208
            }
209
        }
210
211
        $response = [
212
            'status' => 'success',
213
            'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor')
214
        ];
215
216
        try {
217
            $this->formPersistenceManager->save($formPersistenceIdentifier, $formToDuplicate);
218
        } catch (PersistenceManagerException $e) {
219
            $response = [
220
                'status' => 'error',
221
                'message' => $e->getMessage(),
222
                'code' => $e->getCode(),
223
            ];
224
        }
225
226
        $this->view->assign('response', $response);
227
        // createAction uses the Extbase JsonView::class.
228
        // That's why we have to set the view variables in this way.
229
        $this->view->setVariablesToRender([
230
            'response',
231
        ]);
232
    }
233
234
    /**
235
     * Initialize the references action.
236
     * This action uses the Fluid JsonView::class as view.
237
     *
238
     * @internal
239
     */
240
    public function initializeReferencesAction()
241
    {
242
        $this->defaultViewObjectName = JsonView::class;
243
    }
244
245
    /**
246
     * Show references to this persistence identifier
247
     *
248
     * @param string $formPersistenceIdentifier persistence identifier of the form to duplicate
249
     * @throws PersistenceManagerException
250
     * @internal
251
     */
252
    public function referencesAction(string $formPersistenceIdentifier)
253
    {
254
        if (!$this->formPersistenceManager->isAllowedPersistencePath($formPersistenceIdentifier)) {
255
            throw new PersistenceManagerException(sprintf('Read from "%s" is not allowed', $formPersistenceIdentifier), 1614500660);
256
        }
257
258
        $this->view->assign('references', $this->getProcessedReferencesRows($formPersistenceIdentifier));
259
        $this->view->assign('formPersistenceIdentifier', $formPersistenceIdentifier);
260
        // referencesAction uses the extbase JsonView::class.
261
        // That's why we have to set the view variables in this way.
262
        $this->view->setVariablesToRender([
263
            'references',
264
            'formPersistenceIdentifier'
265
        ]);
266
    }
267
268
    /**
269
     * Delete a formDefinition identified by the $formPersistenceIdentifier.
270
     *
271
     * @param string $formPersistenceIdentifier persistence identifier to delete
272
     * @throws PersistenceManagerException
273
     * @internal
274
     */
275
    public function deleteAction(string $formPersistenceIdentifier)
276
    {
277
        if (!$this->formPersistenceManager->isAllowedPersistencePath($formPersistenceIdentifier)) {
278
            throw new PersistenceManagerException(sprintf('Delete "%s" is not allowed', $formPersistenceIdentifier), 1614500661);
279
        }
280
281
        if (empty($this->databaseService->getReferencesByPersistenceIdentifier($formPersistenceIdentifier))) {
282
            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDelete'] ?? [] as $className) {
283
                $hookObj = GeneralUtility::makeInstance($className);
284
                if (method_exists($hookObj, 'beforeFormDelete')) {
285
                    $hookObj->beforeFormDelete(
286
                        $formPersistenceIdentifier
287
                    );
288
                }
289
            }
290
291
            $this->formPersistenceManager->delete($formPersistenceIdentifier);
292
        } else {
293
            $controllerConfiguration = TranslationService::getInstance()->translateValuesRecursive(
294
                $this->formSettings['formManager']['controller'],
295
                $this->formSettings['formManager']['translationFiles'] ?? []
296
            );
297
298
            $this->addFlashMessage(
299
                sprintf($controllerConfiguration['deleteAction']['errorMessage'], $formPersistenceIdentifier),
300
                $controllerConfiguration['deleteAction']['errorTitle'],
301
                AbstractMessage::ERROR,
302
                true
303
            );
304
        }
305
        $this->redirect('index');
306
    }
307
308
    /**
309
     * Return a list of all accessible file mountpoints.
310
     *
311
     * Only registered mountpoints from
312
     * TYPO3.CMS.Form.persistenceManager.allowedFileMounts
313
     * are listed. This list will be reduced by the configured
314
     * mountpoints for the current backend user.
315
     *
316
     * @return array
317
     */
318
    protected function getAccessibleFormStorageFolders(): array
319
    {
320
        $preparedAccessibleFormStorageFolders = [];
321
        foreach ($this->formPersistenceManager->getAccessibleFormStorageFolders() as $identifier => $folder) {
322
            $preparedAccessibleFormStorageFolders[] = [
323
                'label' => $folder->getName(),
324
                'value' => $identifier
325
            ];
326
        }
327
328
        if ($this->formSettings['persistenceManager']['allowSaveToExtensionPaths']) {
329
            foreach ($this->formPersistenceManager->getAccessibleExtensionFolders() as $relativePath => $fullPath) {
330
                $preparedAccessibleFormStorageFolders[] = [
331
                    'label' => $relativePath,
332
                    'value' => $relativePath
333
                ];
334
            }
335
        }
336
337
        return $preparedAccessibleFormStorageFolders;
338
    }
339
340
    /**
341
     * Returns the json encoded data which is used by the form editor
342
     * JavaScript app.
343
     *
344
     * @return string
345
     */
346
    protected function getFormManagerAppInitialData(): string
347
    {
348
        $formManagerAppInitialData = [
349
            'selectablePrototypesConfiguration' => $this->formSettings['formManager']['selectablePrototypesConfiguration'],
350
            'accessibleFormStorageFolders' => $this->getAccessibleFormStorageFolders(),
351
            'endpoints' => [
352
                'create' => $this->uriBuilder->uriFor('create'),
353
                'duplicate' => $this->uriBuilder->uriFor('duplicate'),
354
                'delete' => $this->uriBuilder->uriFor('delete'),
355
                'references' => $this->uriBuilder->uriFor('references')
356
            ],
357
        ];
358
359
        $formManagerAppInitialData = ArrayUtility::reIndexNumericArrayKeysRecursive($formManagerAppInitialData);
360
        $formManagerAppInitialData = TranslationService::getInstance()->translateValuesRecursive(
361
            $formManagerAppInitialData,
362
            $this->formSettings['formManager']['translationFiles'] ?? []
363
        );
364
        return json_encode($formManagerAppInitialData);
365
    }
366
367
    /**
368
     * List all formDefinitions which can be loaded through t form persistence
369
     * manager. Enrich this data by a reference counter.
370
     * @return array
371
     */
372
    protected function getAvailableFormDefinitions(): array
373
    {
374
        $allReferencesForFileUid = $this->databaseService->getAllReferencesForFileUid();
375
        $allReferencesForPersistenceIdentifier = $this->databaseService->getAllReferencesForPersistenceIdentifier();
376
377
        $availableFormDefinitions = [];
378
        foreach ($this->formPersistenceManager->listForms() as $formDefinition) {
379
            $referenceCount  = 0;
380
            if (
381
                isset($formDefinition['fileUid'])
382
                && array_key_exists($formDefinition['fileUid'], $allReferencesForFileUid)
383
            ) {
384
                $referenceCount = $allReferencesForFileUid[$formDefinition['fileUid']];
385
            } elseif (array_key_exists($formDefinition['persistenceIdentifier'], $allReferencesForPersistenceIdentifier)) {
386
                $referenceCount = $allReferencesForPersistenceIdentifier[$formDefinition['persistenceIdentifier']];
387
            }
388
389
            $formDefinition['referenceCount'] = $referenceCount;
390
            $availableFormDefinitions[] = $formDefinition;
391
        }
392
393
        return $availableFormDefinitions;
394
    }
395
396
    /**
397
     * Returns an array with information about the references for a
398
     * formDefinition identified by $persistenceIdentifier.
399
     *
400
     * @param string $persistenceIdentifier
401
     * @return array
402
     * @throws \InvalidArgumentException
403
     */
404
    protected function getProcessedReferencesRows(string $persistenceIdentifier): array
405
    {
406
        if (empty($persistenceIdentifier)) {
407
            throw new \InvalidArgumentException('$persistenceIdentifier must not be empty.', 1477071939);
408
        }
409
410
        $references = [];
411
        $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
412
413
        $referenceRows = $this->databaseService->getReferencesByPersistenceIdentifier($persistenceIdentifier);
414
        foreach ($referenceRows as &$referenceRow) {
415
            $record = $this->getRecord($referenceRow['tablename'], $referenceRow['recuid']);
416
            if (!$record) {
417
                continue;
418
            }
419
            $pageRecord = $this->getRecord('pages', $record['pid']);
420
            $urlParameters = [
421
                'edit' => [
422
                    $referenceRow['tablename'] => [
423
                        $referenceRow['recuid'] => 'edit'
424
                    ]
425
                ],
426
                'returnUrl' => $this->getModuleUrl('web_FormFormbuilder')
427
            ];
428
429
            $references[] = [
430
                'recordPageTitle' => is_array($pageRecord) ? $this->getRecordTitle('pages', $pageRecord) : '',
431
                'recordTitle' => $this->getRecordTitle($referenceRow['tablename'], $record, true),
432
                'recordIcon' => $iconFactory->getIconForRecord($referenceRow['tablename'], $record, Icon::SIZE_SMALL)->render(),
433
                'recordUid' => $referenceRow['recuid'],
434
                'recordEditUrl' => $this->getModuleUrl('record_edit', $urlParameters),
435
            ];
436
        }
437
        return $references;
438
    }
439
440
    /**
441
     * Check if a given $templatePath for a given $prototypeName is valid
442
     * and accessible.
443
     *
444
     * Valid template paths has to be configured within
445
     * TYPO3.CMS.Form.formManager.selectablePrototypesConfiguration.[('identifier':  $prototypeName)].newFormTemplates.[('templatePath': $templatePath)]
446
     *
447
     * @param string $prototypeName
448
     * @param string $templatePath
449
     * @return bool
450
     */
451
    protected function isValidTemplatePath(string $prototypeName, string $templatePath): bool
452
    {
453
        $isValid = false;
454
        foreach ($this->formSettings['formManager']['selectablePrototypesConfiguration'] as $prototypesConfiguration) {
455
            if ($prototypesConfiguration['identifier'] !== $prototypeName) {
456
                continue;
457
            }
458
            foreach ($prototypesConfiguration['newFormTemplates'] as $templatesConfiguration) {
459
                if ($templatesConfiguration['templatePath'] !== $templatePath) {
460
                    continue;
461
                }
462
                $isValid = true;
463
                break;
464
            }
465
        }
466
467
        $templatePath = GeneralUtility::getFileAbsFileName($templatePath);
468
        if (!is_file($templatePath)) {
469
            $isValid = false;
470
        }
471
472
        return $isValid;
473
    }
474
475
    /**
476
     * Register document header buttons
477
     *
478
     * @throws \InvalidArgumentException
479
     */
480
    protected function registerDocheaderButtons()
481
    {
482
        /** @var ButtonBar $buttonBar */
483
        $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
484
485
        // Create new
486
        $addFormButton = $buttonBar->makeLinkButton()
487
            ->setDataAttributes(['identifier' => 'newForm'])
488
            ->setHref('#')
489
            ->setTitle($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.create_new_form'))
490
            ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-add', Icon::SIZE_SMALL));
491
        $buttonBar->addButton($addFormButton, ButtonBar::BUTTON_POSITION_LEFT);
492
493
        // Reload
494
        $reloadButton = $buttonBar->makeLinkButton()
495
            ->setHref($GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri())
496
            ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.reload'))
497
            ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-refresh', Icon::SIZE_SMALL));
498
        $buttonBar->addButton($reloadButton, ButtonBar::BUTTON_POSITION_RIGHT);
499
500
        // Shortcut
501
        $shortcutButton = $buttonBar->makeShortcutButton()
502
            ->setRouteIdentifier('web_FormFormbuilder')
503
            ->setDisplayName($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:module.shortcut_name'));
504
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
505
    }
506
507
    /**
508
     * Returns a form identifier which is the lower cased form name.
509
     *
510
     * @param string $formName
511
     * @return string
512
     */
513
    protected function convertFormNameToIdentifier(string $formName): string
514
    {
515
        $csConverter = GeneralUtility::makeInstance(CharsetConverter::class);
516
517
        $formIdentifier = $csConverter->specCharsToASCII('utf-8', $formName);
518
        $formIdentifier = (string)preg_replace('/[^a-zA-Z0-9-_]/', '', $formIdentifier);
519
        $formIdentifier = lcfirst($formIdentifier);
520
        return $formIdentifier;
521
    }
522
523
    /**
524
     * Wrapper used for unit testing.
525
     *
526
     * @param string $table
527
     * @param int $uid
528
     * @return array|null
529
     */
530
    protected function getRecord(string $table, int $uid)
531
    {
532
        return BackendUtility::getRecord($table, $uid);
533
    }
534
535
    /**
536
     * Wrapper used for unit testing.
537
     *
538
     * @param string $table
539
     * @param array $row
540
     * @param bool $prep
541
     * @return string
542
     */
543
    protected function getRecordTitle(string $table, array $row, bool $prep = false): string
544
    {
545
        return BackendUtility::getRecordTitle($table, $row, $prep);
546
    }
547
548
    /**
549
     * Wrapper used for unit testing.
550
     *
551
     * @param string $moduleName
552
     * @param array $urlParameters
553
     * @return string
554
     */
555
    protected function getModuleUrl(string $moduleName, array $urlParameters = []): string
556
    {
557
        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
558
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
559
        return (string)$uriBuilder->buildUriFromRoute($moduleName, $urlParameters);
560
    }
561
562
    /**
563
     * Returns the current BE user.
564
     *
565
     * @return BackendUserAuthentication
566
     */
567
    protected function getBackendUser(): BackendUserAuthentication
568
    {
569
        return $GLOBALS['BE_USER'];
570
    }
571
572
    /**
573
     * Returns the Language Service
574
     *
575
     * @return LanguageService
576
     */
577
    protected function getLanguageService(): LanguageService
578
    {
579
        return $GLOBALS['LANG'];
580
    }
581
582
    /**
583
     * Returns the page renderer
584
     *
585
     * @return PageRenderer
586
     */
587
    protected function getPageRenderer(): PageRenderer
588
    {
589
        return GeneralUtility::makeInstance(PageRenderer::class);
590
    }
591
}
592