260 lines
7.9 KiB
PHP
260 lines
7.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* This file is part of the TYPO3 CMS project.
|
|
*
|
|
* It is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License, either version 2
|
|
* of the License, or any later version.
|
|
*
|
|
* For the full copyright and license information, please read the
|
|
* LICENSE.txt file that was distributed with this source code.
|
|
*
|
|
* The TYPO3 project - inspiring people to share!
|
|
*/
|
|
|
|
namespace TYPO3\CMS\Backend\View\BackendLayout\Grid;
|
|
|
|
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
|
use TYPO3\CMS\Backend\View\PageLayoutContext;
|
|
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
|
use TYPO3\CMS\Core\Localization\LanguageService;
|
|
use TYPO3\CMS\Core\Page\ContentSlideMode;
|
|
use TYPO3\CMS\Core\Schema\Capability\TcaSchemaCapability;
|
|
use TYPO3\CMS\Core\Schema\TcaSchemaFactory;
|
|
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
|
|
/**
|
|
* Grid Column
|
|
*
|
|
* Object representation (model/proxy) for a single column from a grid defined
|
|
* in a BackendLayout. Stores GridColumnItem representations of content records
|
|
* and provides getter methods which return various properties associated with
|
|
* a single column, e.g. the "edit all elements in content" URL and the "add
|
|
* new content element" URL of the button that is placed in the top of columns
|
|
* in the page layout.
|
|
*
|
|
* Accessed from Fluid templates.
|
|
*
|
|
* @internal
|
|
*/
|
|
class GridColumn
|
|
{
|
|
/**
|
|
* @var GridColumnItem[]
|
|
*/
|
|
protected array $items = [];
|
|
|
|
protected readonly ?int $columnNumber;
|
|
protected readonly string $columnName;
|
|
protected readonly string $icon;
|
|
protected readonly int $colSpan;
|
|
protected readonly int $rowSpan;
|
|
protected readonly ?string $identifier;
|
|
protected readonly ContentSlideMode $slideMode;
|
|
|
|
/**
|
|
* @param array<string, mixed> $definition
|
|
*/
|
|
public function __construct(
|
|
protected readonly PageLayoutContext $context,
|
|
protected readonly array $definition,
|
|
protected readonly string $table = 'tt_content'
|
|
) {
|
|
$this->columnNumber = isset($definition['colPos']) ? (int)$definition['colPos'] : null;
|
|
$this->columnName = (string)($definition['name'] ?? 'default');
|
|
$this->icon = (string)($definition['icon'] ?? '');
|
|
$this->colSpan = (int)($definition['colspan'] ?? 1);
|
|
$this->rowSpan = (int)($definition['rowspan'] ?? 1);
|
|
$this->identifier = isset($definition['identifier']) ? (string)$definition['identifier'] : null;
|
|
$this->slideMode = ContentSlideMode::tryFrom($definition['slideMode'] ?? null);
|
|
}
|
|
|
|
public function getContext(): PageLayoutContext
|
|
{
|
|
return $this->context;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function getDefinition(): array
|
|
{
|
|
return $this->definition;
|
|
}
|
|
|
|
public function isActive(): bool
|
|
{
|
|
return $this->columnNumber !== null && in_array($this->columnNumber, $this->context->getDrawingConfiguration()->getActiveColumns());
|
|
}
|
|
|
|
public function addItem(GridColumnItem $item): void
|
|
{
|
|
$this->items[] = $item;
|
|
}
|
|
|
|
/**
|
|
* @return GridColumnItem[]
|
|
*/
|
|
public function getItems(): iterable
|
|
{
|
|
return $this->items;
|
|
}
|
|
|
|
public function getColumnNumber(): ?int
|
|
{
|
|
return $this->columnNumber;
|
|
}
|
|
|
|
public function getColumnName(): string
|
|
{
|
|
return $this->columnName;
|
|
}
|
|
|
|
public function getIcon(): string
|
|
{
|
|
return $this->icon;
|
|
}
|
|
|
|
public function getColSpan(): int
|
|
{
|
|
if ($this->context->getDrawingConfiguration()->isLanguageComparisonMode()) {
|
|
return 1;
|
|
}
|
|
return $this->colSpan;
|
|
}
|
|
|
|
public function getRowSpan(): int
|
|
{
|
|
if ($this->context->getDrawingConfiguration()->isLanguageComparisonMode()) {
|
|
return 1;
|
|
}
|
|
return $this->rowSpan;
|
|
}
|
|
|
|
public function getIdentifier(): ?string
|
|
{
|
|
return $this->identifier;
|
|
}
|
|
|
|
public function getIdentifierCleaned(): string
|
|
{
|
|
return strtolower((string)preg_replace('/[^a-zA-Z0-9_-]/', '', (string)$this->identifier));
|
|
}
|
|
|
|
public function getSlideMode(): ContentSlideMode
|
|
{
|
|
return $this->slideMode;
|
|
}
|
|
|
|
/**
|
|
* @return int[]
|
|
*/
|
|
public function getAllContainedItemUids(): array
|
|
{
|
|
$uids = [];
|
|
foreach ($this->items as $columnItem) {
|
|
$uids[] = $columnItem->getRecord()->getUid();
|
|
}
|
|
return $uids;
|
|
}
|
|
|
|
public function getEditUrl(): ?string
|
|
{
|
|
if (empty($this->items)) {
|
|
return null;
|
|
}
|
|
$pageRecord = $this->context->getPageRecord();
|
|
if (!$this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
|
|
|| !$this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage())) {
|
|
return null;
|
|
}
|
|
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
|
return (string)$uriBuilder->buildUriFromRoute('record_edit', [
|
|
'edit' => [
|
|
$this->table => [
|
|
implode(',', $this->getAllContainedItemUids()) => 'edit',
|
|
],
|
|
],
|
|
'module' => 'web_layout',
|
|
'returnUrl' => $this->context->getReturnUrl(),
|
|
]);
|
|
}
|
|
|
|
public function getNewContentUrl(): string
|
|
{
|
|
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
|
$pageId = $this->context->getPageId();
|
|
|
|
return (string)$uriBuilder->buildUriFromRoute('new_content_element_wizard', [
|
|
'id' => $pageId,
|
|
'sys_language_uid' => $this->context->getSiteLanguage()->getLanguageId(),
|
|
'colPos' => $this->getColumnNumber(),
|
|
'uid_pid' => $pageId,
|
|
'returnUrl' => $this->context->getReturnUrl(),
|
|
]);
|
|
}
|
|
|
|
public function getTitle(): string
|
|
{
|
|
$columnNumber = $this->getColumnNumber();
|
|
$colTitle = '';
|
|
foreach ($this->context->getBackendLayout()->getUsedColumns() as $colPos => $title) {
|
|
if ($colPos === $columnNumber) {
|
|
$colTitle = $this->getLanguageService()->sL($title);
|
|
}
|
|
}
|
|
return $colTitle;
|
|
}
|
|
|
|
public function getTitleInaccessible(): string
|
|
{
|
|
return $this->getLanguageService()->sL($this->columnName) . ' (' . $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:noAccess') . ')';
|
|
}
|
|
|
|
public function getTitleUnassigned(): string
|
|
{
|
|
return $this->getLanguageService()->sL($this->columnName) . ' (' . $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:notAssigned') . ')';
|
|
}
|
|
|
|
public function isUnassigned(): bool
|
|
{
|
|
return $this->columnName !== 'unused' && $this->columnNumber === null;
|
|
}
|
|
|
|
public function isUnused(): bool
|
|
{
|
|
return $this->columnName === 'unused' && $this->columnNumber === null;
|
|
}
|
|
|
|
public function isContentEditable(): bool
|
|
{
|
|
if ($this->columnName === 'unused' || $this->columnNumber === null) {
|
|
return false;
|
|
}
|
|
if ($this->getBackendUser()->isAdmin()) {
|
|
return true;
|
|
}
|
|
$pageRecord = $this->context->getPageRecord();
|
|
return $this->getBackendUser()->doesUserHaveAccess($pageRecord, Permission::CONTENT_EDIT)
|
|
&& $this->getBackendUser()->checkLanguageAccess($this->context->getSiteLanguage())
|
|
&& (
|
|
!($pagesSchema = GeneralUtility::makeInstance(TcaSchemaFactory::class)->get('pages'))->hasCapability(TcaSchemaCapability::EditLock)
|
|
|| !($pageRecord[$pagesSchema->getCapability(TcaSchemaCapability::EditLock)->getFieldName()] ?? false)
|
|
);
|
|
}
|
|
|
|
protected function getLanguageService(): LanguageService
|
|
{
|
|
return $GLOBALS['LANG'];
|
|
}
|
|
|
|
protected function getBackendUser(): BackendUserAuthentication
|
|
{
|
|
return $GLOBALS['BE_USER'];
|
|
}
|
|
}
|