Completed
Push — master ( 88ade1...553837 )
by
unknown
19:18 queued 05:52
created

GridColumnItem::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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