Completed
Push — master ( f66149...a7372c )
by
unknown
130:24 queued 111:56
created

GridColumnItem::getDeleteConfirmText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
declare(strict_types = 1);
3
4
namespace TYPO3\CMS\Backend\View\BackendLayout\Grid;
5
6
/*
7
 * This file is part of the TYPO3 CMS project.
8
 *
9
 * It is free software; you can redistribute it and/or modify it under
10
 * the terms of the GNU General Public License, either version 2
11
 * of the License, or any later version.
12
 *
13
 * For the full copyright and license information, please read the
14
 * LICENSE.txt file that was distributed with this source code.
15
 *
16
 * The TYPO3 project - inspiring people to share!
17
 */
18
19
use TYPO3\CMS\Backend\Routing\UriBuilder;
20
use TYPO3\CMS\Backend\Utility\BackendUtility;
21
use TYPO3\CMS\Backend\View\BackendLayout\BackendLayout;
22
use TYPO3\CMS\Core\Imaging\Icon;
23
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
24
use TYPO3\CMS\Core\Type\Bitmask\Permission;
25
use TYPO3\CMS\Core\Utility\GeneralUtility;
26
use TYPO3\CMS\Core\Versioning\VersionState;
27
28
/**
29
 * Grid Column Item
30
 *
31
 * Model/proxy around a single record which appears in a grid column
32
 * in the page layout. Returns titles, urls etc. and performs basic
33
 * assertions on the contained content element record such as
34
 * is-versioned, is-editable, is-delible and so on.
35
 *
36
 * Accessed from Fluid templates.
37
 */
38
class GridColumnItem extends AbstractGridObject
39
{
40
    protected $record = [];
41
42
    /**
43
     * @var GridColumn
44
     */
45
    protected $column;
46
47
    public function __construct(BackendLayout $backendLayout, GridColumn $column, array $record)
48
    {
49
        parent::__construct($backendLayout);
50
        $this->column = $column;
51
        $this->record = $record;
52
        $backendLayout->getRecordRememberer()->rememberRecordUid($record['uid']);
53
        $backendLayout->getRecordRememberer()->rememberRecordUid($record['l18n_parent']);
54
    }
55
56
    public function isVersioned(): bool
57
    {
58
        return $this->record['_ORIG_uid'] > 0;
59
    }
60
61
    public function getPreview(): string
62
    {
63
        $item = $this;
64
        $row = $item->getRecord();
65
        $configuration = $this->backendLayout->getDrawingConfiguration();
66
        $out = '';
67
        $outHeader = '';
68
69
        if ($row['header']) {
70
            $hiddenHeaderNote = '';
71
            // If header layout is set to 'hidden', display an accordant note:
72
            if ($row['header_layout'] == 100) {
73
                $hiddenHeaderNote = ' <em>[' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.hidden')) . ']</em>';
74
            }
75
            $outHeader = $row['date']
76
                ? htmlspecialchars($configuration->getItemLabels()['date'] . ' ' . BackendUtility::date($row['date'])) . '<br />'
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "?"; newline found
Loading history...
77
                : '';
0 ignored issues
show
Coding Style introduced by
Expected 1 space before ":"; newline found
Loading history...
78
            $outHeader .= '<strong>' . $this->linkEditContent($this->renderText($row['header']), $row)
79
                . $hiddenHeaderNote . '</strong><br />';
80
        }
81
82
        $drawItem = true;
83
84
        // Draw preview of the item depending on its CType (if not disabled by previous hook):
85
        if ($drawItem) {
0 ignored issues
show
introduced by
The condition $drawItem is always true.
Loading history...
86
            switch ($row['CType']) {
87
                case 'header':
88
                    if ($row['subheader']) {
89
                        $out .= $this->linkEditContent($this->renderText($row['subheader']), $row) . '<br />';
90
                    }
91
                    break;
92
                case 'bullets':
93
                case 'table':
94
                    if ($row['bodytext']) {
95
                        $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
96
                    }
97
                    break;
98
                case 'uploads':
99
                    if ($row['media']) {
100
                        $out .= $this->linkEditContent($this->getThumbCodeUnlinked($row, 'tt_content', 'media'), $row) . '<br />';
101
                    }
102
                    break;
103
                case 'shortcut':
104
                    if (!empty($row['records'])) {
105
                        $shortcutContent = [];
106
                        $recordList = explode(',', $row['records']);
107
                        foreach ($recordList as $recordIdentifier) {
108
                            $split = BackendUtility::splitTable_Uid($recordIdentifier);
109
                            $tableName = empty($split[0]) ? 'tt_content' : $split[0];
110
                            $shortcutRecord = BackendUtility::getRecord($tableName, $split[1]);
0 ignored issues
show
Bug introduced by
$split[1] of type string is incompatible with the type integer expected by parameter $uid of TYPO3\CMS\Backend\Utilit...endUtility::getRecord(). ( Ignorable by Annotation )

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

110
                            $shortcutRecord = BackendUtility::getRecord($tableName, /** @scrutinizer ignore-type */ $split[1]);
Loading history...
111
                            if (is_array($shortcutRecord)) {
112
                                $icon = $this->iconFactory->getIconForRecord($tableName, $shortcutRecord, Icon::SIZE_SMALL)->render();
113
                                $icon = BackendUtility::wrapClickMenuOnIcon(
114
                                    $icon,
115
                                    $tableName,
116
                                    $shortcutRecord['uid']
117
                                );
118
                                $shortcutContent[] = $icon
119
                                    . htmlspecialchars(BackendUtility::getRecordTitle($tableName, $shortcutRecord));
120
                            }
121
                        }
122
                        $out .= implode('<br />', $shortcutContent) . '<br />';
123
                    }
124
                    break;
125
                case 'list':
126
                    $hookOut = '';
127
                    $_params = ['pObj' => &$this, 'row' => $row, 'infoArr' => []];
128
                    foreach (
0 ignored issues
show
Coding Style introduced by
Space found after opening bracket of FOREACH loop
Loading history...
Coding Style introduced by
Space found before closing bracket of FOREACH loop
Loading history...
129
                        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info'][$row['list_type']] ??
130
                        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info']['_DEFAULT'] ??
131
                        [] as $_funcRef
132
                    ) {
133
                        $hookOut .= GeneralUtility::callUserFunction($_funcRef, $_params, $this);
134
                    }
135
                    if ((string)$hookOut !== '') {
136
                        $out .= $hookOut;
137
                    } elseif (!empty($row['list_type'])) {
138
                        $label = BackendUtility::getLabelFromItemListMerged($row['pid'], 'tt_content', 'list_type', $row['list_type']);
139
                        if (!empty($label)) {
140
                            $out .= $this->linkEditContent('<strong>' . htmlspecialchars($this->getLanguageService()->sL($label)) . '</strong>', $row) . '<br />';
141
                        } else {
142
                            $message = sprintf($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'), $row['list_type']);
143
                            $out .= '<span class="label label-warning">' . htmlspecialchars($message) . '</span>';
144
                        }
145
                    } else {
146
                        $out .= '<strong>' . $this->getLanguageService()->getLL('noPluginSelected') . '</strong>';
147
                    }
148
                    $out .= htmlspecialchars($this->getLanguageService()->sL(
149
                        BackendUtility::getLabelFromItemlist('tt_content', 'pages', $row['pages'])
150
                    )) . '<br />';
151
                    break;
152
                default:
153
                    $contentType = $this->backendLayout->getDrawingConfiguration()->getContentTypeLabels()[$row['CType']];
154
                    if (!isset($contentType)) {
155
                        $contentType =  BackendUtility::getLabelFromItemListMerged($row['pid'], 'tt_content', 'CType', $row['CType']);
156
                    }
157
158
                    if ($contentType) {
159
                        $out .= $this->linkEditContent('<strong>' . htmlspecialchars($contentType) . '</strong>', $row) . '<br />';
160
                        if ($row['bodytext']) {
161
                            $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
162
                        }
163
                        if ($row['image']) {
164
                            $out .= $this->linkEditContent($this->getThumbCodeUnlinked($row, 'tt_content', 'image'), $row) . '<br />';
165
                        }
166
                    } else {
167
                        $message = sprintf(
168
                            $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.noMatchingValue'),
169
                            $row['CType']
170
                        );
171
                        $out .= '<span class="label label-warning">' . htmlspecialchars($message) . '</span>';
172
                    }
173
            }
174
        }
175
        $out = '<span class="exampleContent">' . $out . '</span>';
176
        $out = $outHeader . $out;
177
        if ($item->isDisabled()) {
178
            return '<span class="text-muted">' . $out . '</span>';
179
        }
180
        return $out;
181
    }
182
183
    public function getWrapperClassName(): string
184
    {
185
        $wrapperClassNames = [];
186
        if ($this->isDisabled()) {
187
            $wrapperClassNames[] = 't3-page-ce-hidden t3js-hidden-record';
188
        } elseif (!in_array($this->record['colPos'], $this->backendLayout->getColumnPositionNumbers())) {
189
            $wrapperClassNames[] = 't3-page-ce-warning';
190
        }
191
192
        return implode(' ', $wrapperClassNames);
193
    }
194
195
    public function isDelible(): bool
196
    {
197
        $backendUser = $this->getBackendUser();
198
        if (!$backendUser->doesUserHaveAccess($this->pageinfo, Permission::CONTENT_EDIT)) {
0 ignored issues
show
Bug Best Practice introduced by
The property pageinfo does not exist on TYPO3\CMS\Backend\View\B...out\Grid\GridColumnItem. Did you maybe forget to declare it?
Loading history...
199
            return false;
200
        }
201
        return !(bool)($backendUser->getTSConfig()['options.']['disableDelete.']['tt_content'] ?? $backendUser->getTSConfig()['options.']['disableDelete'] ?? false);
202
    }
203
204
    public function getDeleteUrl(): string
205
    {
206
        $params = '&cmd[tt_content][' . $this->record['uid'] . '][delete]=1';
207
        return BackendUtility::getLinkToDataHandlerAction($params);
208
    }
209
210
    public function getDeleteTitle(): string
211
    {
212
        return $this->getLanguageService()->getLL('deleteItem');
213
    }
214
215
    public function getDeleteConfirmText(): string
216
    {
217
        return $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:label.confirm.delete_record.title');
218
    }
219
220
    public function getDeleteCancelText(): string
221
    {
222
        return $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:cancel');
223
    }
224
225
    public function getFooterInfo(): iterable
226
    {
227
        $info = [];
228
        $this->getProcessedValue('starttime,endtime,fe_group,space_before_class,space_after_class', $info);
229
230
        if (!empty($GLOBALS['TCA']['tt_content']['ctrl']['descriptionColumn']) && !empty($this->record[$GLOBALS['TCA']['tt_content']['ctrl']['descriptionColumn']])) {
231
            $info[] = $this->record[$GLOBALS['TCA']['tt_content']['ctrl']['descriptionColumn']];
232
        }
233
234
        return $info;
235
    }
236
237
    /**
238
     * Renders the language flag and language title, but only if an icon is given, otherwise just the language
239
     *
240
     * @param SiteLanguage $language
241
     * @return string
242
     */
243
    protected function renderLanguageFlag(SiteLanguage $language)
244
    {
245
        $title = htmlspecialchars($language->getTitle());
246
        if ($language->getFlagIdentifier()) {
247
            $icon = $this->iconFactory->getIcon(
248
                $language->getFlagIdentifier(),
249
                Icon::SIZE_SMALL
250
            )->render();
251
            return '<span title="' . $title . '">' . $icon . '</span>&nbsp;' . $title;
252
        }
253
        return $title;
254
    }
255
256
    /**
257
     * Create thumbnail code for record/field but not linked
258
     *
259
     * @param mixed[] $row Record array
260
     * @param string $table Table (record is from)
261
     * @param string $field Field name for which thumbnail are to be rendered.
262
     * @return string HTML for thumbnails, if any.
263
     */
264
    protected function getThumbCodeUnlinked($row, $table, $field)
265
    {
266
        return BackendUtility::thumbCode($row, $table, $field, '', '', null, 0, '', '', false);
267
    }
268
269
    /**
270
     * Will create a link on the input string and possibly a big button after the string which links to editing in the RTE.
271
     * Used for content element content displayed so the user can click the content / "Edit in Rich Text Editor" button
272
     *
273
     * @param string $str String to link. Must be prepared for HTML output.
274
     * @param array $row The row.
275
     * @return string If the whole thing was editable $str is return with link around. Otherwise just $str.
276
     */
277
    public function linkEditContent($str, $row)
278
    {
279
        if ($this->getBackendUser()->recordEditAccessInternals('tt_content', $row)) {
280
            $urlParameters = [
281
                'edit' => [
282
                    'tt_content' => [
283
                        $row['uid'] => 'edit'
284
                    ]
285
                ],
286
                'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') . '#element-tt_content-' . $row['uid']
287
            ];
288
            $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
289
            $url = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
290
            return '<a href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($this->getLanguageService()->getLL('edit')) . '">' . $str . '</a>';
291
        }
292
        return $str;
293
    }
294
295
    /**
296
     * Processing of larger amounts of text (usually from RTE/bodytext fields) with word wrapping etc.
297
     *
298
     * @param string $input Input string
299
     * @return string Output string
300
     */
301
    public function renderText($input): string
302
    {
303
        $input = strip_tags($input);
304
        $input = GeneralUtility::fixed_lgd_cs($input, 1500);
305
        return nl2br(htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8', false));
306
    }
307
308
    protected function getProcessedValue(string $fieldList, array &$info): void
309
    {
310
        $itemLabels = $this->backendLayout->getDrawingConfiguration()->getItemLabels();
311
        $fieldArr = explode(',', $fieldList);
312
        foreach ($fieldArr as $field) {
313
            if ($this->record[$field]) {
314
                $info[] = '<strong>' . htmlspecialchars($itemLabels[$field]) . '</strong> '
315
                    . htmlspecialchars(BackendUtility::getProcessedValue('tt_content', $field, $this->record[$field]));
316
            }
317
        }
318
    }
319
320
    public function getIcons(): string
321
    {
322
        $table = 'tt_content';
323
        $row = $this->record;
324
        $icons = [];
325
326
        if ($this->getBackendUser()->recordEditAccessInternals($table, $row)) {
327
            $toolTip = BackendUtility::getRecordToolTip($row, $table);
328
            $icon = '<span ' . $toolTip . '>' . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>';
329
            $icons[] = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid']);
330
        }
331
        $icons[] = $this->renderLanguageFlag($this->backendLayout->getDrawingConfiguration()->getSiteLanguage((int)$row['sys_language_uid']));
0 ignored issues
show
Bug introduced by
It seems like $this->backendLayout->ge...ow['sys_language_uid']) can also be of type null; however, parameter $language of TYPO3\CMS\Backend\View\B...m::renderLanguageFlag() does only seem to accept TYPO3\CMS\Core\Site\Entity\SiteLanguage, maybe add an additional type check? ( Ignorable by Annotation )

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

331
        $icons[] = $this->renderLanguageFlag(/** @scrutinizer ignore-type */ $this->backendLayout->getDrawingConfiguration()->getSiteLanguage((int)$row['sys_language_uid']));
Loading history...
332
333
        if ($lockInfo = BackendUtility::isRecordLocked('tt_content', $row['uid'])) {
334
            $icons[] = '<a href="#" data-toggle="tooltip" data-title="' . htmlspecialchars($lockInfo['msg']) . '">'
335
                . $this->iconFactory->getIcon('warning-in-use', Icon::SIZE_SMALL)->render() . '</a>';
336
        }
337
338
        $_params = ['tt_content', $row['uid'], &$row];
339
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] ?? [] as $_funcRef) {
340
            $icons[] = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
341
        }
342
        return implode(' ', $icons);
343
    }
344
345
    public function getRecord(): array
346
    {
347
        return $this->record;
348
    }
349
350
    public function getColumn(): GridColumn
351
    {
352
        return $this->column;
353
    }
354
355
    public function isDisabled(): bool
356
    {
357
        $table = 'tt_content';
358
        $row = $this->getRecord();
359
        $enableCols = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
360
        return $enableCols['disabled'] && $row[$enableCols['disabled']]
361
            || $enableCols['starttime'] && $row[$enableCols['starttime']] > $GLOBALS['EXEC_TIME']
362
            || $enableCols['endtime'] && $row[$enableCols['endtime']] && $row[$enableCols['endtime']] < $GLOBALS['EXEC_TIME'];
363
    }
364
365
    public function hasTranslation(): bool
366
    {
367
        $contentElements = $this->column->getRecords();
368
        $id = $this->backendLayout->getDrawingConfiguration()->getPageId();
369
        $language = $this->backendLayout->getDrawingConfiguration()->getLanguageColumnsPointer();
370
        // If in default language, you may always create new entries
371
        // Also, you may override this strict behavior via user TS Config
372
        // If you do so, you're on your own and cannot rely on any support by the TYPO3 core.
373
        $allowInconsistentLanguageHandling = (bool)(BackendUtility::getPagesTSconfig($id)['mod.']['web_layout.']['allowInconsistentLanguageHandling'] ?? false);
374
        if ($language === 0 || $allowInconsistentLanguageHandling) {
375
            return false;
376
        }
377
378
        return $this->backendLayout->getContentFetcher()->getTranslationData($contentElements, $language)['hasTranslations'] ?? false;
379
    }
380
381
    public function isDeletePlaceholder(): bool
382
    {
383
        return VersionState::cast($this->record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER);
384
    }
385
386
    public function isEditable(): bool
387
    {
388
        $languageId = $this->backendLayout->getDrawingConfiguration()->getLanguageColumnsPointer();
389
        if ($this->getBackendUser()->isAdmin()) {
390
            return true;
391
        }
392
        $pageRecord = $this->backendLayout->getDrawingConfiguration()->getPageRecord();
393
        return !$pageRecord['editlock']
394
            && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
395
            && ($languageId === null || $this->getBackendUser()->checkLanguageAccess($languageId));
396
    }
397
398
    public function isDragAndDropAllowed(): bool
399
    {
400
        $pageRecord = $this->backendLayout->getDrawingConfiguration()->getPageRecord();
401
        return (int)$this->record['l18n_parent'] === 0 &&
402
            (
403
                $this->getBackendUser()->isAdmin()
404
                || ((int)$this->record['editlock'] === 0 && (int)$pageRecord['editlock'] === 0)
405
                && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
406
                && $this->getBackendUser()->checkAuthMode('tt_content', 'CType', $this->record['CType'], $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'])
407
            )
408
        ;
0 ignored issues
show
Coding Style introduced by
Space found before semicolon; expected ");" but found ")
;"
Loading history...
409
    }
410
411
    public function getNewContentAfterLinkTitle(): string
412
    {
413
        return $this->getLanguageService()->getLL('newContentElement');
414
    }
415
416
    public function getNewContentAfterTitle(): string
417
    {
418
        return $this->getLanguageService()->getLL('content');
419
    }
420
421
    public function getNewContentAfterUrl(): string
422
    {
423
        $pageId = $this->backendLayout->getDrawingConfiguration()->getPageId();
424
        $urlParameters = [
425
            'id' => $pageId,
426
            'sys_language_uid' => $this->backendLayout->getDrawingConfiguration()->getLanguageColumnsPointer(),
427
            'colPos' => $this->column->getColumnNumber(),
428
            'uid_pid' => -$this->record['uid'],
429
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
430
        ];
431
        $routeName = BackendUtility::getPagesTSconfig($pageId)['mod.']['newContentElementWizard.']['override']
432
            ?? 'new_content_element_wizard';
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "??"; newline found
Loading history...
433
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
434
        return (string)$uriBuilder->buildUriFromRoute($routeName, $urlParameters);
435
    }
436
437
    public function getVisibilityToggleUrl(): string
438
    {
439
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
440
        if ($this->record[$hiddenField]) {
441
            $value = 0;
442
        } else {
443
            $value = 1;
444
        }
445
        $params = '&data[tt_content][' . ($this->record['_ORIG_uid'] ?: $this->record['uid'])
446
            . '][' . $hiddenField . ']=' . $value;
447
        return BackendUtility::getLinkToDataHandlerAction($params) . '#element-tt_content-' . $this->record['uid'];
448
    }
449
450
    public function getVisibilityToggleTitle(): string
451
    {
452
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
453
        return $this->getLanguageService()->getLL($this->record[$hiddenField] ? 'unhide' : 'hide');
454
    }
455
456
    public function getVisibilityToggleIconName(): string
457
    {
458
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
459
        return $this->record[$hiddenField] ? 'unhide' : 'hide';
460
    }
461
462
    public function isVisibilityToggling(): bool
463
    {
464
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
465
        return $hiddenField && $GLOBALS['TCA']['tt_content']['columns'][$hiddenField]
466
            && (
467
                !$GLOBALS['TCA']['tt_content']['columns'][$hiddenField]['exclude']
468
                || $this->getBackendUser()->check('non_exclude_fields', 'tt_content:' . $hiddenField)
469
            )
470
        ;
0 ignored issues
show
Coding Style introduced by
Space found before semicolon; expected ");" but found ")
;"
Loading history...
471
    }
472
473
    public function getEditUrl(): string
474
    {
475
        $urlParameters = [
476
            'edit' => [
477
                'tt_content' => [
478
                    $this->record['uid'] => 'edit',
479
                ]
480
            ],
481
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') . '#element-tt_content-' . $this->record['uid'],
482
        ];
483
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
484
        return (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters) . '#element-tt_content-' . $this->record['uid'];
485
    }
486
}
487