Completed
Push — master ( 7e342e...13c67c )
by
unknown
19:15
created

GridColumnItem::getDeleteTitle()   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\Preview\StandardPreviewRendererResolver;
20
use TYPO3\CMS\Backend\Routing\UriBuilder;
21
use TYPO3\CMS\Backend\Utility\BackendUtility;
22
use TYPO3\CMS\Backend\View\BackendLayout\BackendLayout;
23
use TYPO3\CMS\Core\Imaging\Icon;
24
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
25
use TYPO3\CMS\Core\Type\Bitmask\Permission;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Core\Versioning\VersionState;
28
29
/**
30
 * Grid Column Item
31
 *
32
 * Model/proxy around a single record which appears in a grid column
33
 * in the page layout. Returns titles, urls etc. and performs basic
34
 * assertions on the contained content element record such as
35
 * is-versioned, is-editable, is-delible and so on.
36
 *
37
 * Accessed from Fluid templates.
38
 */
39
class GridColumnItem extends AbstractGridObject
40
{
41
    protected $record = [];
42
43
    /**
44
     * @var GridColumn
45
     */
46
    protected $column;
47
48
    public function __construct(BackendLayout $backendLayout, GridColumn $column, array $record)
49
    {
50
        parent::__construct($backendLayout);
51
        $this->column = $column;
52
        $this->record = $record;
53
        $backendLayout->getRecordRememberer()->rememberRecordUid((int)$record['uid']);
54
        $backendLayout->getRecordRememberer()->rememberRecordUid((int)$record['l18n_parent']);
55
    }
56
57
    public function isVersioned(): bool
58
    {
59
        return $this->record['_ORIG_uid'] > 0;
60
    }
61
62
    public function getPreview(): string
63
    {
64
        $record = $this->getRecord();
65
        $previewRenderer = GeneralUtility::makeInstance(StandardPreviewRendererResolver::class)
66
            ->resolveRendererFor(
67
                'tt_content',
68
                $record,
69
                $this->backendLayout->getDrawingConfiguration()->getPageId()
70
            );
71
        $previewHeader = $previewRenderer->renderPageModulePreviewHeader($this);
72
        $previewContent = $previewRenderer->renderPageModulePreviewContent($this);
73
        return $previewRenderer->wrapPageModulePreview($previewHeader, $previewContent, $this);
74
    }
75
76
    public function getWrapperClassName(): string
77
    {
78
        $wrapperClassNames = [];
79
        if ($this->isDisabled()) {
80
            $wrapperClassNames[] = 't3-page-ce-hidden t3js-hidden-record';
81
        } elseif (!in_array($this->record['colPos'], $this->backendLayout->getColumnPositionNumbers())) {
82
            $wrapperClassNames[] = 't3-page-ce-warning';
83
        }
84
85
        return implode(' ', $wrapperClassNames);
86
    }
87
88
    public function isDelible(): bool
89
    {
90
        $backendUser = $this->getBackendUser();
91
        if (!$backendUser->doesUserHaveAccess($this->backendLayout->getDrawingConfiguration()->getPageRecord(), Permission::CONTENT_EDIT)) {
92
            return false;
93
        }
94
        return !(bool)($backendUser->getTSConfig()['options.']['disableDelete.']['tt_content'] ?? $backendUser->getTSConfig()['options.']['disableDelete'] ?? false);
95
    }
96
97
    public function getDeleteUrl(): string
98
    {
99
        $params = '&cmd[tt_content][' . $this->record['uid'] . '][delete]=1';
100
        return BackendUtility::getLinkToDataHandlerAction($params);
101
    }
102
103
    public function getDeleteTitle(): string
104
    {
105
        return $this->getLanguageService()->getLL('deleteItem');
106
    }
107
108
    public function getDeleteConfirmText(): string
109
    {
110
        return $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:label.confirm.delete_record.title');
111
    }
112
113
    public function getDeleteCancelText(): string
114
    {
115
        return $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:cancel');
116
    }
117
118
    public function getFooterInfo(): string
119
    {
120
        $record = $this->getRecord();
121
        $previewRenderer = GeneralUtility::makeInstance(StandardPreviewRendererResolver::class)
122
            ->resolveRendererFor(
123
                'tt_content',
124
                $record,
125
                $this->backendLayout->getDrawingConfiguration()->getPageId()
126
            );
127
        return $previewRenderer->renderPageModulePreviewFooter($this);
128
    }
129
130
    /**
131
     * Renders the language flag and language title, but only if an icon is given, otherwise just the language
132
     *
133
     * @param SiteLanguage $language
134
     * @return string
135
     */
136
    protected function renderLanguageFlag(SiteLanguage $language)
137
    {
138
        $title = htmlspecialchars($language->getTitle());
139
        if ($language->getFlagIdentifier()) {
140
            $icon = $this->iconFactory->getIcon(
141
                $language->getFlagIdentifier(),
142
                Icon::SIZE_SMALL
143
            )->render();
144
            return '<span title="' . $title . '">' . $icon . '</span>&nbsp;' . $title;
145
        }
146
        return $title;
147
    }
148
149
    public function getIcons(): string
150
    {
151
        $table = 'tt_content';
152
        $row = $this->record;
153
        $icons = [];
154
155
        if ($this->getBackendUser()->recordEditAccessInternals($table, $row)) {
156
            $toolTip = BackendUtility::getRecordToolTip($row, $table);
157
            $icon = '<span ' . $toolTip . '>' . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>';
158
            $icons[] = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid']);
159
        }
160
        $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

160
        $icons[] = $this->renderLanguageFlag(/** @scrutinizer ignore-type */ $this->backendLayout->getDrawingConfiguration()->getSiteLanguage((int)$row['sys_language_uid']));
Loading history...
161
162
        if ($lockInfo = BackendUtility::isRecordLocked('tt_content', $row['uid'])) {
163
            $icons[] = '<a href="#" data-toggle="tooltip" data-title="' . htmlspecialchars($lockInfo['msg']) . '">'
164
                . $this->iconFactory->getIcon('warning-in-use', Icon::SIZE_SMALL)->render() . '</a>';
165
        }
166
167
        $_params = ['tt_content', $row['uid'], &$row];
168
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] ?? [] as $_funcRef) {
169
            $icons[] = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
170
        }
171
        return implode(' ', $icons);
172
    }
173
174
    public function getRecord(): array
175
    {
176
        return $this->record;
177
    }
178
179
    public function getColumn(): GridColumn
180
    {
181
        return $this->column;
182
    }
183
184
    public function isDisabled(): bool
185
    {
186
        $table = 'tt_content';
187
        $row = $this->getRecord();
188
        $enableCols = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
189
        return $enableCols['disabled'] && $row[$enableCols['disabled']]
190
            || $enableCols['starttime'] && $row[$enableCols['starttime']] > $GLOBALS['EXEC_TIME']
191
            || $enableCols['endtime'] && $row[$enableCols['endtime']] && $row[$enableCols['endtime']] < $GLOBALS['EXEC_TIME'];
192
    }
193
194
    public function hasTranslation(): bool
195
    {
196
        $contentElements = $this->column->getRecords();
197
        $id = $this->backendLayout->getDrawingConfiguration()->getPageId();
198
        $language = $this->backendLayout->getDrawingConfiguration()->getLanguageColumnsPointer();
199
        // If in default language, you may always create new entries
200
        // Also, you may override this strict behavior via user TS Config
201
        // If you do so, you're on your own and cannot rely on any support by the TYPO3 core.
202
        $allowInconsistentLanguageHandling = (bool)(BackendUtility::getPagesTSconfig($id)['mod.']['web_layout.']['allowInconsistentLanguageHandling'] ?? false);
203
        if ($language === 0 || $allowInconsistentLanguageHandling) {
204
            return false;
205
        }
206
207
        return $this->backendLayout->getContentFetcher()->getTranslationData($contentElements, $language)['hasTranslations'] ?? false;
208
    }
209
210
    public function isDeletePlaceholder(): bool
211
    {
212
        return VersionState::cast($this->record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER);
213
    }
214
215
    public function isEditable(): bool
216
    {
217
        $languageId = $this->backendLayout->getDrawingConfiguration()->getLanguageColumnsPointer();
218
        if ($this->getBackendUser()->isAdmin()) {
219
            return true;
220
        }
221
        $pageRecord = $this->backendLayout->getDrawingConfiguration()->getPageRecord();
222
        return !$pageRecord['editlock']
223
            && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
224
            && ($languageId === null || $this->getBackendUser()->checkLanguageAccess($languageId));
225
    }
226
227
    public function isDragAndDropAllowed(): bool
228
    {
229
        $pageRecord = $this->backendLayout->getDrawingConfiguration()->getPageRecord();
230
        return (int)$this->record['l18n_parent'] === 0 &&
231
            (
232
                $this->getBackendUser()->isAdmin()
233
                || ((int)$this->record['editlock'] === 0 && (int)$pageRecord['editlock'] === 0)
234
                && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
235
                && $this->getBackendUser()->checkAuthMode('tt_content', 'CType', $this->record['CType'], $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'])
236
            )
237
        ;
0 ignored issues
show
Coding Style introduced by
Space found before semicolon; expected ");" but found ")
;"
Loading history...
238
    }
239
240
    public function getNewContentAfterLinkTitle(): string
241
    {
242
        return $this->getLanguageService()->getLL('newContentElement');
243
    }
244
245
    public function getNewContentAfterTitle(): string
246
    {
247
        return $this->getLanguageService()->getLL('content');
248
    }
249
250
    public function getNewContentAfterUrl(): string
251
    {
252
        $pageId = $this->backendLayout->getDrawingConfiguration()->getPageId();
253
        $urlParameters = [
254
            'id' => $pageId,
255
            'sys_language_uid' => $this->backendLayout->getDrawingConfiguration()->getLanguageColumnsPointer(),
256
            'colPos' => $this->column->getColumnNumber(),
257
            'uid_pid' => -$this->record['uid'],
258
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
259
        ];
260
        $routeName = BackendUtility::getPagesTSconfig($pageId)['mod.']['newContentElementWizard.']['override']
261
            ?? 'new_content_element_wizard';
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "??"; newline found
Loading history...
262
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
263
        return (string)$uriBuilder->buildUriFromRoute($routeName, $urlParameters);
264
    }
265
266
    public function getVisibilityToggleUrl(): string
267
    {
268
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
269
        if ($this->record[$hiddenField]) {
270
            $value = 0;
271
        } else {
272
            $value = 1;
273
        }
274
        $params = '&data[tt_content][' . ($this->record['_ORIG_uid'] ?: $this->record['uid'])
275
            . '][' . $hiddenField . ']=' . $value;
276
        return BackendUtility::getLinkToDataHandlerAction($params) . '#element-tt_content-' . $this->record['uid'];
277
    }
278
279
    public function getVisibilityToggleTitle(): string
280
    {
281
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
282
        return $this->getLanguageService()->getLL($this->record[$hiddenField] ? 'unhide' : 'hide');
283
    }
284
285
    public function getVisibilityToggleIconName(): string
286
    {
287
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
288
        return $this->record[$hiddenField] ? 'unhide' : 'hide';
289
    }
290
291
    public function isVisibilityToggling(): bool
292
    {
293
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
294
        return $hiddenField && $GLOBALS['TCA']['tt_content']['columns'][$hiddenField]
295
            && (
296
                !$GLOBALS['TCA']['tt_content']['columns'][$hiddenField]['exclude']
297
                || $this->getBackendUser()->check('non_exclude_fields', 'tt_content:' . $hiddenField)
298
            )
299
        ;
0 ignored issues
show
Coding Style introduced by
Space found before semicolon; expected ");" but found ")
;"
Loading history...
300
    }
301
302
    public function getEditUrl(): string
303
    {
304
        $urlParameters = [
305
            'edit' => [
306
                'tt_content' => [
307
                    $this->record['uid'] => 'edit',
308
                ]
309
            ],
310
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') . '#element-tt_content-' . $this->record['uid'],
311
        ];
312
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
313
        return (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters) . '#element-tt_content-' . $this->record['uid'];
314
    }
315
}
316