backendLayoutView = $backendLayoutView; } /** * Creates a linked position icon * * @param array|null $row The record row. If this is an array the link will cause an insert after this * content element, otherwise the link will insert at the first position in the column. * @param int $colPos Column position value. * @param int $pid PID value. * @return string HTML */ abstract protected function insertPositionIcon(?array $row, int $colPos, int $pid): string; /** * Create content element header (includes record type (CType) icon, content element title, etc.) * * @param array $row The element row * @return string HTML */ abstract protected function getRecordHeader(array $row): string; /** * Creates HTML for inserting/moving content elements. * * @param int $pid page id onto which to insert content element. * @return string HTML */ public function printContentElementColumns(int $pid, array $pageInfo, ServerRequestInterface $request): string { $lines = []; $columnsConfiguration = $this->getColumnsConfiguration($pid); foreach ($columnsConfiguration as $columnConfiguration) { if ($columnConfiguration['isRestricted']) { // Do not fetch records of restricted columns continue; } $colPos = $columnConfiguration['colPos']; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); $queryBuilder ->getRestrictions() ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->getBackendUser()->workspace)) ->removeByType(HiddenRestriction::class) ->removeByType(StartTimeRestriction::class) ->removeByType(EndTimeRestriction::class); $queryBuilder ->select('*') ->from('tt_content') ->where( $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pid, Connection::PARAM_INT)), $queryBuilder->expr()->eq('colPos', $queryBuilder->createNamedParameter($colPos, Connection::PARAM_INT)) ) ->orderBy('sorting'); $queryBuilder->andWhere( $queryBuilder->expr()->eq( 'sys_language_uid', $queryBuilder->createNamedParameter($this->cur_sys_language, Connection::PARAM_INT) ) ); $res = $queryBuilder->executeQuery(); $lines[$colPos] = [ $this->insertPositionIcon(null, $colPos, $pid), ]; while ($row = $res->fetchAssociative()) { BackendUtility::workspaceOL('tt_content', $row); if (is_array($row)) { $lines[$colPos][] = $this->getRecordHeader($row); $lines[$colPos][] = $this->insertPositionIcon($row, $colPos, $pid); } } } return $this->printRecordMap($lines, $columnsConfiguration, $pid); } /** * Creates the table with the content columns * * @param array $lines Array with arrays of lines for each column * @param array $tcaColumnsConfiguration Column configuration array * @param int $pid The id of the page * @return string HTML */ protected function printRecordMap(array $lines, array $tcaColumnsConfiguration, int $pid): string { $lang = $this->getLanguageService(); $hideRestrictedColumns = (bool)(BackendUtility::getPagesTSconfig($pid)['mod.']['web_layout.']['hideRestrictedCols'] ?? false); $backendLayout = $this->backendLayoutView->getSelectedBackendLayout($pid); if (isset($backendLayout['__config']['backend_layout.'])) { // Build position map based on the fetched backend layout $colCount = (int)($backendLayout['__config']['backend_layout.']['colCount'] ?? 0); $rowCount = (int)($backendLayout['__config']['backend_layout.']['rowCount'] ?? 0); // Cycle through rows $tableRows = []; for ($row = 1; $row <= $rowCount; $row++) { $rowConfig = $backendLayout['__config']['backend_layout.']['rows.'][$row . '.'] ?? null; if (!$rowConfig) { // Skip empty rows continue; } // Cycle through cells $tableCells = []; for ($col = 1; $col <= $colCount; $col++) { $columnConfig = $rowConfig['columns.'][$col . '.'] ?? null; if (!$columnConfig) { // Skip empty columns continue; } // Set table cell attributes $tableCellAttributes = [ 'class' => 'col-nowrap col-min', ]; if (isset($columnConfig['colspan'])) { $tableCellAttributes['colspan'] = $columnConfig['colspan']; } if (isset($columnConfig['rowspan'])) { $tableCellAttributes['rowspan'] = $columnConfig['rowspan']; } $columnKey = null; $columnTitle = ''; $isRestricted = false; $isUnassigned = true; if (isset($columnConfig['colPos'])) { // If colPos is defined, initialize column information (e.g. title and restricted state) $columnKey = (int)$columnConfig['colPos']; foreach ($tcaColumnsConfiguration as $tcaColumnConfiguration) { if ($tcaColumnConfiguration['colPos'] === $columnKey) { $columnTitle = '' . htmlspecialchars($lang->sL($tcaColumnConfiguration['title'])) . ''; $isRestricted = $tcaColumnConfiguration['isRestricted']; $isUnassigned = false; } } } // Generate the cell content, based on the columns' state (e.g. restricted or unassigned) $cellContent = ''; if ($isRestricted) { if ($hideRestrictedColumns) { // Hide in case this column is not accessible and hideRestrictedColumns is set $tableCellAttributes['class'] = 'hidden'; } else { $cellContent = '
' . $columnTitle . ' (' . htmlspecialchars($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:noAccess')) . ')
'; $tableCellAttributes['class'] .= ' danger'; } } elseif ($isUnassigned) { if ($hideRestrictedColumns) { // Hide in case this column is not assigned and hideRestrictedColumns is set $tableCellAttributes['class'] = 'hidden'; } else { $cellContent = ' ' . htmlspecialchars($lang->sL($columnConfig['name']) ?: '') . ' ' . ' (' . htmlspecialchars($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:notAssigned')) . ')' . ' '; $tableCellAttributes['class'] .= ' warning'; } } else { // If not restricted and not unassigned, wrap column title and render list (if available) $cellContent = '' . $columnTitle . '
'; if (!empty($lines[$columnKey])) { $cellContent .= '' . $columnTitle . ' (' . htmlspecialchars($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:noAccess')) . ')
'; } else { // If not restricted, wrap column title and render list (if available) $cellContent = '' . $columnTitle . '
'; if (!empty($lines[$tcaColumnConfiguration['colPos']])) { $cellContent .= '