Passed
Push — master ( 1e85f0...74899e )
by
unknown
14:10
created

GridColumnItem::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 5
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
    public function __construct(PageLayoutContext $context, GridColumn $column, array $record)
55
    {
56
        parent::__construct($context);
57
        $this->column = $column;
58
        $this->record = $record;
59
    }
60
61
    public function isVersioned(): bool
62
    {
63
        return $this->record['_ORIG_uid'] > 0 || (int)$this->record['t3ver_state'] !== 0;
64
    }
65
66
    public function getPreview(): string
67
    {
68
        $record = $this->getRecord();
69
        $previewRenderer = GeneralUtility::makeInstance(StandardPreviewRendererResolver::class)
70
            ->resolveRendererFor(
71
                'tt_content',
72
                $record,
73
                $this->context->getPageId()
74
            );
75
        $previewHeader = $previewRenderer->renderPageModulePreviewHeader($this);
76
        $previewContent = $previewRenderer->renderPageModulePreviewContent($this);
77
        return $previewRenderer->wrapPageModulePreview($previewHeader, $previewContent, $this);
78
    }
79
80
    public function getWrapperClassName(): string
81
    {
82
        $wrapperClassNames = [];
83
        if ($this->isDisabled()) {
84
            $wrapperClassNames[] = 't3-page-ce-hidden t3js-hidden-record';
85
        } elseif (!in_array($this->record['colPos'], $this->context->getBackendLayout()->getColumnPositionNumbers())) {
86
            $wrapperClassNames[] = 't3-page-ce-warning';
87
        }
88
89
        return implode(' ', $wrapperClassNames);
90
    }
91
92
    public function isDelible(): bool
93
    {
94
        $backendUser = $this->getBackendUser();
95
        if (!$backendUser->doesUserHaveAccess($this->context->getPageRecord(), Permission::CONTENT_EDIT)) {
96
            return false;
97
        }
98
        return !(bool)($backendUser->getTSConfig()['options.']['disableDelete.']['tt_content'] ?? $backendUser->getTSConfig()['options.']['disableDelete'] ?? false);
99
    }
100
101
    public function getDeleteUrl(): string
102
    {
103
        $params = '&cmd[tt_content][' . $this->record['uid'] . '][delete]=1';
104
        return BackendUtility::getLinkToDataHandlerAction($params);
105
    }
106
107
    public function getDeleteTitle(): string
108
    {
109
        return $this->getLanguageService()->getLL('deleteItem');
110
    }
111
112
    public function getDeleteConfirmText(): string
113
    {
114
        return $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:label.confirm.delete_record.title');
115
    }
116
117
    public function getDeleteCancelText(): string
118
    {
119
        return $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:cancel');
120
    }
121
122
    public function getFooterInfo(): string
123
    {
124
        $record = $this->getRecord();
125
        $previewRenderer = GeneralUtility::makeInstance(StandardPreviewRendererResolver::class)
126
            ->resolveRendererFor(
127
                'tt_content',
128
                $record,
129
                $this->context->getPageId()
130
            );
131
        return $previewRenderer->renderPageModulePreviewFooter($this);
132
    }
133
134
    /**
135
     * Renders the language flag and language title, but only if an icon is given, otherwise just the language
136
     *
137
     * @param SiteLanguage $language
138
     * @return string
139
     */
140
    protected function renderLanguageFlag(SiteLanguage $language)
141
    {
142
        $title = htmlspecialchars($language->getTitle());
143
        if ($language->getFlagIdentifier()) {
144
            $icon = $this->iconFactory->getIcon(
145
                $language->getFlagIdentifier(),
146
                Icon::SIZE_SMALL
147
            )->render();
148
            return '<span title="' . $title . '" class="t3js-flag">' . $icon . '</span>&nbsp;<span class="t3js-language-title">' . $title . '</span>';
149
        }
150
        return $title;
151
    }
152
153
    public function getIcons(): string
154
    {
155
        $table = 'tt_content';
156
        $row = $this->record;
157
        $icons = [];
158
159
        $toolTip = BackendUtility::getRecordToolTip($row, $table);
160
        $icon = '<span ' . $toolTip . '>' . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>';
161
        if ($this->getBackendUser()->recordEditAccessInternals($table, $row)) {
162
            $icon = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid']);
163
        }
164
        $icons[] = $icon;
165
        $siteLanguage = $this->context->getSiteLanguage((int)$row['sys_language_uid']);
166
        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...
167
            $icons[] = $this->renderLanguageFlag($siteLanguage);
168
        }
169
170
        if ($lockInfo = BackendUtility::isRecordLocked('tt_content', $row['uid'])) {
171
            $icons[] = '<a href="#" data-toggle="tooltip" data-title="' . htmlspecialchars($lockInfo['msg']) . '">'
172
                . $this->iconFactory->getIcon('warning-in-use', Icon::SIZE_SMALL)->render() . '</a>';
173
        }
174
175
        $_params = ['tt_content', $row['uid'], &$row];
176
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] ?? [] as $_funcRef) {
177
            $icons[] = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
178
        }
179
        return implode(' ', $icons);
180
    }
181
182
    public function getRecord(): array
183
    {
184
        return $this->record;
185
    }
186
187
    public function setRecord(array $record): void
188
    {
189
        $this->record = $record;
190
    }
191
192
    public function getColumn(): GridColumn
193
    {
194
        return $this->column;
195
    }
196
197
    public function isDisabled(): bool
198
    {
199
        $table = 'tt_content';
200
        $row = $this->getRecord();
201
        $enableCols = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'];
202
        return $enableCols['disabled'] && $row[$enableCols['disabled']]
203
            || $enableCols['starttime'] && $row[$enableCols['starttime']] > $GLOBALS['EXEC_TIME']
204
            || $enableCols['endtime'] && $row[$enableCols['endtime']] && $row[$enableCols['endtime']] < $GLOBALS['EXEC_TIME'];
205
    }
206
207
    public function isDeletePlaceholder(): bool
208
    {
209
        return VersionState::cast($this->record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER);
210
    }
211
212
    public function isEditable(): bool
213
    {
214
        $languageId = $this->context->getSiteLanguage()->getLanguageId();
215
        if ($this->getBackendUser()->isAdmin()) {
216
            return true;
217
        }
218
        $pageRecord = $this->context->getPageRecord();
219
        return !$pageRecord['editlock']
220
            && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
221
            && ($languageId === null || $this->getBackendUser()->checkLanguageAccess($languageId));
222
    }
223
224
    public function isDragAndDropAllowed(): bool
225
    {
226
        $pageRecord = $this->context->getPageRecord();
227
        return (int)$this->record['l18n_parent'] === 0 &&
228
            (
229
                $this->getBackendUser()->isAdmin()
230
                || ((int)$this->record['editlock'] === 0 && (int)$pageRecord['editlock'] === 0)
231
                && $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
232
                && $this->getBackendUser()->checkAuthMode('tt_content', 'CType', $this->record['CType'], $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'])
233
            )
234
        ;
235
    }
236
237
    public function getNewContentAfterLinkTitle(): string
238
    {
239
        return $this->getLanguageService()->getLL('newContentElement');
240
    }
241
242
    public function getNewContentAfterTitle(): string
243
    {
244
        return $this->getLanguageService()->getLL('content');
245
    }
246
247
    public function getNewContentAfterUrl(): string
248
    {
249
        $pageId = $this->context->getPageId();
250
        $urlParameters = [
251
            'id' => $pageId,
252
            'sys_language_uid' => $this->context->getSiteLanguage()->getLanguageId(),
253
            'colPos' => $this->column->getColumnNumber(),
254
            'uid_pid' => -$this->record['uid'],
255
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
256
        ];
257
        $routeName = BackendUtility::getPagesTSconfig($pageId)['mod.']['newContentElementWizard.']['override']
258
            ?? 'new_content_element_wizard';
259
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
260
        return (string)$uriBuilder->buildUriFromRoute($routeName, $urlParameters);
261
    }
262
263
    public function getVisibilityToggleUrl(): string
264
    {
265
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
266
        if ($this->record[$hiddenField]) {
267
            $value = 0;
268
        } else {
269
            $value = 1;
270
        }
271
        $params = '&data[tt_content][' . ($this->record['_ORIG_uid'] ?: $this->record['uid'])
272
            . '][' . $hiddenField . ']=' . $value;
273
        return BackendUtility::getLinkToDataHandlerAction($params) . '#element-tt_content-' . $this->record['uid'];
274
    }
275
276
    public function getVisibilityToggleTitle(): string
277
    {
278
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
279
        return $this->getLanguageService()->getLL($this->record[$hiddenField] ? 'unhide' : 'hide');
280
    }
281
282
    public function getVisibilityToggleIconName(): string
283
    {
284
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
285
        return $this->record[$hiddenField] ? 'unhide' : 'hide';
286
    }
287
288
    public function isVisibilityToggling(): bool
289
    {
290
        $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'];
291
        return $hiddenField && $GLOBALS['TCA']['tt_content']['columns'][$hiddenField]
292
            && (
293
                !$GLOBALS['TCA']['tt_content']['columns'][$hiddenField]['exclude']
294
                || $this->getBackendUser()->check('non_exclude_fields', 'tt_content:' . $hiddenField)
295
            )
296
        ;
297
    }
298
299
    public function getEditUrl(): string
300
    {
301
        $urlParameters = [
302
            'edit' => [
303
                'tt_content' => [
304
                    $this->record['uid'] => 'edit',
305
                ]
306
            ],
307
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') . '#element-tt_content-' . $this->record['uid'],
308
        ];
309
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
310
        return (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters) . '#element-tt_content-' . $this->record['uid'];
311
    }
312
}
313