Passed
Push — master ( 844f02...dd001f )
by
unknown
23:08 queued 09:54
created

GridColumnItem::isDeletePlaceholder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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\Backend\View\BackendLayout\Grid;
19
20
use TYPO3\CMS\Backend\Preview\StandardPreviewRendererResolver;
21
use TYPO3\CMS\Backend\Routing\UriBuilder;
22
use TYPO3\CMS\Backend\Utility\BackendUtility;
23
use TYPO3\CMS\Backend\View\PageLayoutContext;
24
use TYPO3\CMS\Core\Imaging\Icon;
25
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
26
use TYPO3\CMS\Core\Type\Bitmask\Permission;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Core\Versioning\VersionState;
29
30
/**
31
 * Grid Column Item
32
 *
33
 * Model/proxy around a single record which appears in a grid column
34
 * in the page layout. Returns titles, urls etc. and performs basic
35
 * assertions on the contained content element record such as
36
 * is-versioned, is-editable, is-delible and so on.
37
 *
38
 * Accessed from Fluid templates.
39
 *
40
 * @internal this is experimental and subject to change in TYPO3 v10 / v11
41
 */
42
class GridColumnItem extends AbstractGridObject
43
{
44
    /**
45
     * @var mixed[]
46
     */
47
    protected $record = [];
48
49
    /**
50
     * @var GridColumn
51
     */
52
    protected $column;
53
54
    /**
55
     * @var GridColumnItem[]
56
     */
57
    protected $translations = [];
58
59
    public function __construct(PageLayoutContext $context, GridColumn $column, array $record)
60
    {
61
        parent::__construct($context);
62
        $this->column = $column;
63
        $this->record = $record;
64
    }
65
66
    public function isVersioned(): bool
67
    {
68
        return $this->record['_ORIG_uid'] > 0 || (int)$this->record['t3ver_state'] !== 0;
69
    }
70
71
    public function getPreview(): string
72
    {
73
        $record = $this->getRecord();
74
        $previewRenderer = GeneralUtility::makeInstance(StandardPreviewRendererResolver::class)
75
            ->resolveRendererFor(
76
                'tt_content',
77
                $record,
78
                $this->context->getPageId()
79
            );
80
        $previewHeader = $previewRenderer->renderPageModulePreviewHeader($this);
81
        $previewContent = $previewRenderer->renderPageModulePreviewContent($this);
82
        return $previewRenderer->wrapPageModulePreview($previewHeader, $previewContent, $this);
83
    }
84
85
    public function getWrapperClassName(): string
86
    {
87
        $wrapperClassNames = [];
88
        if ($this->isDisabled()) {
89
            $wrapperClassNames[] = 't3-page-ce-hidden t3js-hidden-record';
90
        } elseif (!in_array($this->record['colPos'], $this->context->getBackendLayout()->getColumnPositionNumbers())) {
91
            $wrapperClassNames[] = 't3-page-ce-warning';
92
        }
93
94
        return implode(' ', $wrapperClassNames);
95
    }
96
97
    public function isDelible(): bool
98
    {
99
        $backendUser = $this->getBackendUser();
100
        if (!$backendUser->doesUserHaveAccess($this->context->getPageRecord(), Permission::CONTENT_EDIT)) {
101
            return false;
102
        }
103
        return !(bool)($backendUser->getTSConfig()['options.']['disableDelete.']['tt_content'] ?? $backendUser->getTSConfig()['options.']['disableDelete'] ?? false);
104
    }
105
106
    public function getDeleteUrl(): string
107
    {
108
        $params = '&cmd[tt_content][' . $this->record['uid'] . '][delete]=1';
109
        return BackendUtility::getLinkToDataHandlerAction($params);
110
    }
111
112
    public function getDeleteTitle(): string
113
    {
114
        return $this->getLanguageService()->getLL('deleteItem');
115
    }
116
117
    public function getDeleteConfirmText(): string
118
    {
119
        return $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:label.confirm.delete_record.title');
120
    }
121
122
    public function getDeleteCancelText(): string
123
    {
124
        return $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:cancel');
125
    }
126
127
    public function getFooterInfo(): string
128
    {
129
        $record = $this->getRecord();
130
        $previewRenderer = GeneralUtility::makeInstance(StandardPreviewRendererResolver::class)
131
            ->resolveRendererFor(
132
                'tt_content',
133
                $record,
134
                $this->context->getPageId()
135
            );
136
        return $previewRenderer->renderPageModulePreviewFooter($this);
137
    }
138
139
    /**
140
     * Renders the language flag and language title, but only if an icon is given, otherwise just the language
141
     *
142
     * @param SiteLanguage $language
143
     * @return string
144
     */
145
    protected function renderLanguageFlag(SiteLanguage $language)
146
    {
147
        $title = htmlspecialchars($language->getTitle());
148
        if ($language->getFlagIdentifier()) {
149
            $icon = $this->iconFactory->getIcon(
150
                $language->getFlagIdentifier(),
151
                Icon::SIZE_SMALL
152
            )->render();
153
            return '<span title="' . $title . '" class="t3js-flag">' . $icon . '</span>&nbsp;<span class="t3js-language-title">' . $title . '</span>';
154
        }
155
        return $title;
156
    }
157
158
    public function getIcons(): string
159
    {
160
        $table = 'tt_content';
161
        $row = $this->record;
162
        $icons = [];
163
164
        $toolTip = BackendUtility::getRecordToolTip($row, $table);
165
        $icon = '<span ' . $toolTip . '>' . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>';
166
        if ($this->getBackendUser()->recordEditAccessInternals($table, $row)) {
167
            $icon = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid']);
168
        }
169
        $icons[] = $icon;
170
        $siteLanguage = $this->context->getSiteLanguage((int)$row['sys_language_uid']);
171
        if ($siteLanguage instanceof SiteLanguage) {
0 ignored issues
show
introduced by
$siteLanguage is always a sub-type of TYPO3\CMS\Core\Site\Entity\SiteLanguage.
Loading history...
172
            $icons[] = $this->renderLanguageFlag($siteLanguage);
173
        }
174
175
        if ($lockInfo = BackendUtility::isRecordLocked('tt_content', $row['uid'])) {
176
            $icons[] = '<a href="#" data-toggle="tooltip" data-title="' . htmlspecialchars($lockInfo['msg']) . '">'
177
                . $this->iconFactory->getIcon('warning-in-use', Icon::SIZE_SMALL)->render() . '</a>';
178
        }
179
180
        $_params = ['tt_content', $row['uid'], &$row];
181
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] ?? [] as $_funcRef) {
182
            $icons[] = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
183
        }
184
        return implode(' ', $icons);
185
    }
186
187
    public function getRecord(): array
188
    {
189
        return $this->record;
190
    }
191
192
    public function setRecord(array $record): void
193
    {
194
        $this->record = $record;
195
    }
196
197
    public function getColumn(): GridColumn
198
    {
199
        return $this->column;
200
    }
201
202
    public function getTranslations(): array
203
    {
204
        return $this->translations;
205
    }
206
207
    public function addTranslation(int $languageId, GridColumnItem $translation): GridColumnItem
208
    {
209
        $this->translations[$languageId] = $translation;
210
        return $this;
211
    }
212
213
    public function isDisabled(): bool
214
    {
215
        $table = 'tt_content';
216
        $row = $this->getRecord();
217
        $enableCols = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
218
        return $enableCols['disabled'] && $row[$enableCols['disabled']]
219
            || $enableCols['starttime'] && $row[$enableCols['starttime']] > $GLOBALS['EXEC_TIME']
220
            || $enableCols['endtime'] && $row[$enableCols['endtime']] && $row[$enableCols['endtime']] < $GLOBALS['EXEC_TIME'];
221
    }
222
223
    public function isDeletePlaceholder(): bool
224
    {
225
        return VersionState::cast($this->record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER);
226
    }
227
228
    public function isEditable(): bool
229
    {
230
        $languageId = $this->context->getSiteLanguage()->getLanguageId();
231
        if ($this->getBackendUser()->isAdmin()) {
232
            return true;
233
        }
234
        $pageRecord = $this->context->getPageRecord();
235
        return !$pageRecord['editlock']
236
            && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
237
            && ($languageId === null || $this->getBackendUser()->checkLanguageAccess($languageId));
238
    }
239
240
    public function isDragAndDropAllowed(): bool
241
    {
242
        $pageRecord = $this->context->getPageRecord();
243
        return (int)$this->record['l18n_parent'] === 0 &&
244
            (
245
                $this->getBackendUser()->isAdmin()
246
                || ((int)$this->record['editlock'] === 0 && (int)$pageRecord['editlock'] === 0)
247
                && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
248
                && $this->getBackendUser()->checkAuthMode('tt_content', 'CType', $this->record['CType'], $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'])
249
            )
250
        ;
251
    }
252
253
    public function getNewContentAfterLinkTitle(): string
254
    {
255
        return $this->getLanguageService()->getLL('newContentElement');
256
    }
257
258
    public function getNewContentAfterTitle(): string
259
    {
260
        return $this->getLanguageService()->getLL('content');
261
    }
262
263
    public function getNewContentAfterUrl(): string
264
    {
265
        $pageId = $this->context->getPageId();
266
        $urlParameters = [
267
            'id' => $pageId,
268
            'sys_language_uid' => $this->context->getSiteLanguage()->getLanguageId(),
269
            'colPos' => $this->column->getColumnNumber(),
270
            'uid_pid' => -$this->record['uid'],
271
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
272
        ];
273
        $routeName = BackendUtility::getPagesTSconfig($pageId)['mod.']['newContentElementWizard.']['override']
274
            ?? 'new_content_element_wizard';
275
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
276
        return (string)$uriBuilder->buildUriFromRoute($routeName, $urlParameters);
277
    }
278
279
    public function getVisibilityToggleUrl(): string
280
    {
281
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
282
        if ($this->record[$hiddenField]) {
283
            $value = 0;
284
        } else {
285
            $value = 1;
286
        }
287
        $params = '&data[tt_content][' . ($this->record['_ORIG_uid'] ?: $this->record['uid'])
288
            . '][' . $hiddenField . ']=' . $value;
289
        return BackendUtility::getLinkToDataHandlerAction($params) . '#element-tt_content-' . $this->record['uid'];
290
    }
291
292
    public function getVisibilityToggleTitle(): string
293
    {
294
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
295
        return $this->getLanguageService()->getLL($this->record[$hiddenField] ? 'unhide' : 'hide');
296
    }
297
298
    public function getVisibilityToggleIconName(): string
299
    {
300
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
301
        return $this->record[$hiddenField] ? 'unhide' : 'hide';
302
    }
303
304
    public function isVisibilityToggling(): bool
305
    {
306
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
307
        return $hiddenField && $GLOBALS['TCA']['tt_content']['columns'][$hiddenField]
308
            && (
309
                !$GLOBALS['TCA']['tt_content']['columns'][$hiddenField]['exclude']
310
                || $this->getBackendUser()->check('non_exclude_fields', 'tt_content:' . $hiddenField)
311
            )
312
        ;
313
    }
314
315
    public function getEditUrl(): string
316
    {
317
        $urlParameters = [
318
            'edit' => [
319
                'tt_content' => [
320
                    $this->record['uid'] => 'edit',
321
                ]
322
            ],
323
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') . '#element-tt_content-' . $this->record['uid'],
324
        ];
325
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
326
        return (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters) . '#element-tt_content-' . $this->record['uid'];
327
    }
328
}
329