2 namespace TYPO3\CMS\Backend\View;
36 class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRecordList
86 public $agePrefixes =
' min| hrs| days| yrs| min| hour| day| year';
122 'languageColsPointer' => 0,
125 'sys_language_uid' => 0,
128 'activeCols' =>
'1,0,2,3'
143 'nextThree' => array(),
218 parent::__construct();
221 $pageRenderer->addInlineLanguageLabelFile(
'EXT:backend/Resources/Private/Language/locallang_layout.xlf');
222 $pageRenderer->loadRequireJsModule(
'TYPO3/CMS/Backend/Tooltip');
223 $pageRenderer->loadRequireJsModule(
'TYPO3/CMS/Backend/Localization');
242 if (isset($this->externalTables[
$table])) {
251 return $this->getTable_tt_content(
$id);
273 $fList = $this->externalTables[
$table][$type][
'fList'];
276 $icon = $this->externalTables[
$table][$type][
'icon'];
277 $addWhere = $this->externalTables[
$table][$type][
'addWhere'];
301 $result = $this->
getDatabase()->exec_SELECTquery(
'*',
'pages',
'uid=' . (
int)
$id . $delClause);
302 $row = $this->
getDatabase()->sql_fetch_assoc($result);
306 if (is_array($row)) {
311 $this->fieldArray = array(
'title',
'uid') + array_keys($this->
cleanTableNames());
314 $this->fieldArray = array(
328 $this->fieldArray = array(
344 $this->no_noWrap = 0;
356 $editUids[] = $row[
'uid'];
360 foreach ($theRows as $sRow) {
362 $editUids[] = $sRow[
'uid'];
370 $editIdList = implode(
',', $editUids);
372 foreach ($this->fieldArray as $field) {
373 if ($editIdList && isset(
$GLOBALS[
'TCA'][
'pages'][
'columns'][$field]) && $field !=
'uid' && !$this->pages_noEditColumns) {
374 $params =
'&edit[pages][' . $editIdList .
']=edit&columnsOnly=' . $field;
380 .
'" title="' . htmlspecialchars($iTitle) .
'">'
381 . $this->iconFactory->getIcon(
'actions-document-open',
Icon::SIZE_SMALL)->render() .
'</a>';
387 $theData[$field] =
' <strong>'
392 $theData[$field] =
' <strong>ID:</strong>';
395 if (substr($field, 0, 6) ==
'table_') {
396 $f2 = substr($field, 6);
398 $theData[$field] =
' ' .
'<span title="' . $this->
getLanguageService()->sL(
$GLOBALS[
'TCA'][$f2][
'ctrl'][
'title'],
true) .
'">' . $this->iconFactory->getIconForRecord($f2, array(),
Icon::SIZE_SMALL)->render() .
'</span>';
401 $theData[$field] =
' <strong>'
409 <div class="table-fit">
410 <table class="table table-striped table-hover typo3-page-pages">' .
429 public function getTable_tt_content(
$id)
438 $pageRenderer->loadRequireJsModule(
'TYPO3/CMS/Backend/LayoutModule/DragDrop');
439 $pageRenderer->loadRequireJsModule(
'TYPO3/CMS/Backend/Modal');
440 $userCanEditPage = $this->ext_CALC_PERMS &
Permission::PAGE_EDIT && !empty($this->
id) && ($backendUser->isAdmin() || (int)$this->pageinfo[
'editlock'] === 0);
441 if ($this->tt_contentConfig[
'languageColsPointer'] > 0) {
442 $userCanEditPage = $this->
getBackendUser()->check(
'tables_modify',
'pages_language_overlay');
444 if ($userCanEditPage) {
445 $pageRenderer->loadRequireJsModule(
'TYPO3/CMS/Backend/PageActions',
'function(PageActions) {
446 PageActions.setPageId(' . (
int)$this->
id .
');
447 PageActions.setLanguageOverlayId(' . $this->tt_contentConfig[
'languageColsPointer'] .
');
448 PageActions.initializePageTitleRenaming();
452 $this->CType_labels = array();
453 foreach (
$GLOBALS[
'TCA'][
'tt_content'][
'columns'][
'CType'][
'config'][
'items'] as $val) {
456 $this->itemLabels = array();
457 foreach (
$GLOBALS[
'TCA'][
'tt_content'][
'columns'] as $name => $val) {
460 $languageColumn = array();
464 $langList = $this->tt_contentConfig[
'sys_language_uid'];
465 if ($this->tt_contentConfig[
'languageMode']) {
466 if ($this->tt_contentConfig[
'languageColsPointer']) {
467 $langList =
'0,' . $this->tt_contentConfig[
'languageColsPointer'];
469 $langList = implode(
',', array_keys($this->tt_contentConfig[
'languageCols']));
471 $languageColumn = array();
474 $defLanguageCount = array();
478 foreach ($langListArr as $lP) {
481 if (!isset($this->contentElementCache[$lP])) {
482 $this->contentElementCache[$lP] = array();
485 if (count($langListArr) === 1 || $lP === 0) {
486 $showLanguage =
' AND sys_language_uid IN (' . $lP .
',-1)';
488 $showLanguage =
' AND sys_language_uid=' . $lP;
490 $cList = explode(
',', $this->tt_contentConfig[
'cols']);
497 foreach ($cList as $key) {
498 if (!isset($this->contentElementCache[$lP][$key])) {
499 $this->contentElementCache[$lP][$key] = array();
503 $defLanguageCount[$key] = array();
506 $content[$key] .=
'<div data-colpos="' . $key .
'" data-language-uid="' . $lP .
'" class="t3js-sortable t3js-sortable-lang t3js-sortable-lang-' . $lP .
' t3-page-ce-wrapper';
507 if (empty($contentRecordsPerColumn[$key])) {
508 $content[$key] .=
' t3-page-ce-empty';
510 $content[$key] .=
'">';
518 .
'" title="' . $this->
getLanguageService()->getLL(
'newContentElement',
true) .
'" class="btn btn-default btn-sm">'
519 . $this->iconFactory->getIcon(
'actions-document-new',
Icon::SIZE_SMALL)->render()
525 <div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-' . $key .
'-' .
'page-' .
$id .
'-' .
StringUtility::getUniqueId() .
'">'
528 <div class="t3-page-ce-dropzone-available t3js-page-ce-dropzone-available"></div>
532 $rowArr = $contentRecordsPerColumn[$key];
535 foreach ((array)$rowArr as $rKey => $row) {
536 $this->contentElementCache[$lP][$key][$row[
'uid']] = $row;
537 if ($this->tt_contentConfig[
'languageMode']) {
538 $languageColumn[$key][$lP] = $head[$key] . $content[$key];
539 if (!$this->defLangBinding) {
548 $singleElementHTML =
'';
549 if (!$lP && ($this->defLangBinding || $row[
'sys_language_uid'] != -1)) {
550 $defLanguageCount[$key][] = (isset($row[
'_ORIG_uid']) ? $row[
'_ORIG_uid'] : $row[
'uid']);
552 $editUidList .= $row[
'uid'] .
',';
553 $disableMoveAndNewButtons = $this->defLangBinding && $lP > 0;
554 if (!$this->tt_contentConfig[
'languageMode']) {
559 $this->tt_contentConfig[
'showInfo'] ? 15 : 5,
560 $disableMoveAndNewButtons,
561 !$this->tt_contentConfig[
'languageMode'],
564 $innerContent =
'<div ' . ($row[
'_ORIG_uid'] ?
' class="ver-element"' :
'') .
'>'
565 . $this->tt_content_drawItem($row) .
'</div>';
566 $singleElementHTML .=
'<div class="t3-page-ce-body-inner">' . $innerContent .
'</div>'
568 $isDisabled = $this->
isDisabled(
'tt_content', $row);
569 $statusHidden = $isDisabled ?
' t3-page-ce-hidden t3js-hidden-record' :
'';
570 $displayNone = !$this->tt_contentConfig[
'showHidden'] && $isDisabled ?
' style="display: none;"' :
'';
571 $highlightHeader =
false;
573 $highlightHeader =
true;
575 $singleElementHTML =
'<div class="t3-page-ce ' . ($highlightHeader ?
't3-page-ce-danger' :
'') .
' t3js-page-ce t3js-page-ce-sortable ' . $statusHidden .
'" id="element-tt_content-'
576 . $row[
'uid'] .
'" data-table="tt_content" data-uid="' . $row[
'uid'] .
'"' . $displayNone .
'>' . $singleElementHTML .
'</div>';
578 if ($this->tt_contentConfig[
'languageMode']) {
579 $singleElementHTML .=
'<div class="t3-page-ce t3js-page-ce">';
581 $singleElementHTML .=
'<div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-' . $key .
'-' .
'page-' .
$id .
584 if (!$disableMoveAndNewButtons
590 if ($this->option_newWizard) {
591 $onClick =
'window.location.href=' .
GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl(
'new_content_element') .
'&id=' . $row[
'pid']
592 .
'&sys_language_uid=' . $row[
'sys_language_uid'] .
'&colPos=' . $row[
'colPos']
593 .
'&uid_pid=' . -$row[
'uid'] .
596 $params =
'&edit[tt_content][' . -$row[
'uid'] .
']=new';
599 $singleElementHTML .=
'
600 <a href="#" onclick="' . htmlspecialchars($onClick) .
'" title="'
601 . $this->
getLanguageService()->getLL(
'newContentElement',
true) .
'" class="btn btn-default btn-sm">'
602 . $this->iconFactory->getIcon(
'actions-document-new',
Icon::SIZE_SMALL)->render()
607 $singleElementHTML .=
'</div></div><div class="t3-page-ce-dropzone-available t3js-page-ce-dropzone-available"></div></div>';
608 if ($this->defLangBinding && $this->tt_contentConfig[
'languageMode']) {
609 $defLangBinding[$key][$lP][$row[$lP ?
'l18n_parent' :
'uid']] = $singleElementHTML;
611 $content[$key] .= $singleElementHTML;
614 unset($rowArr[$rKey]);
617 $content[$key] .=
'</div>';
620 $colTitle = BackendUtility::getProcessedValue(
'tt_content',
'colPos', $key);
622 foreach ($tcaItems as $item) {
623 if ($item[1] == $key) {
628 $pasteP = array(
'colPos' => $key,
'sys_language_uid' => $lP);
629 $editParam = $this->doEdit && !empty($rowArr)
630 ?
'&edit[tt_content][' . $editUidList .
']=edit' . $pageTitleParamForAltDoc
636 if ($this->tt_contentConfig[
'languageMode']) {
638 $sortedLanguageColumn = array();
639 foreach ($cList as $key) {
640 $languageColumn[$key][$lP] = $head[$key] . $content[$key];
641 if (!$this->defLangBinding) {
649 $sortedLanguageColumn[$key] = $languageColumn[$key];
651 $languageColumn = $sortedLanguageColumn;
655 $grid =
'<div class="t3-grid-container"><table border="0" cellspacing="0" cellpadding="0" width="100%" class="t3-page-columns t3-grid-table t3js-page-columns">';
657 $colCount = (int)$backendLayout[
'__config'][
'backend_layout.'][
'colCount'];
658 $rowCount = (int)$backendLayout[
'__config'][
'backend_layout.'][
'rowCount'];
659 $grid .=
'<colgroup>';
660 for ($i = 0; $i < $colCount; $i++) {
661 $grid .=
'<col style="width:' . 100 / $colCount .
'%"></col>';
663 $grid .=
'</colgroup>';
665 for ($row = 1; $row <= $rowCount; $row++) {
666 $rowConfig = $backendLayout[
'__config'][
'backend_layout.'][
'rows.'][$row .
'.'];
667 if (!isset($rowConfig)) {
671 for ($col = 1; $col <= $colCount; $col++) {
672 $columnConfig = $rowConfig[
'columns.'][$col .
'.'];
673 if (!isset($columnConfig)) {
677 $columnKey = (int)$columnConfig[
'colPos'];
679 $colSpan = (int)$columnConfig[
'colspan'];
680 $rowSpan = (int)$columnConfig[
'rowspan'];
681 $grid .=
'<td valign="top"' .
682 ($colSpan > 0 ?
' colspan="' . $colSpan .
'"' :
'') .
683 ($rowSpan > 0 ?
' rowspan="' . $rowSpan .
'"' :
'') .
684 ' data-colpos="' . (int)$columnConfig[
'colPos'] .
'" data-language-uid="' . $lP .
'" class="t3js-page-lang-column-' . $lP .
' t3js-page-column t3-grid-cell t3-page-column t3-page-column-' . $columnKey .
685 ((!isset($columnConfig[
'colPos']) || $columnConfig[
'colPos'] ===
'') ?
' t3-grid-cell-unassigned' :
'') .
686 ((isset($columnConfig[
'colPos']) && $columnConfig[
'colPos'] !==
'' && !$head[$columnKey]) || !
GeneralUtility::inList($this->tt_contentConfig[
'activeCols'], $columnConfig[
'colPos']) ?
' t3-grid-cell-restricted' :
'') .
687 ($colSpan > 0 ?
' t3-gridCell-width' . $colSpan :
'') .
688 ($rowSpan > 0 ?
' t3-gridCell-height' . $rowSpan :
'') .
'">';
692 if (isset($columnConfig[
'colPos']) && $columnConfig[
'colPos'] !==
'' && $head[$columnKey]
695 $grid .= $head[$columnKey] . $content[$columnKey];
696 }
elseif (isset($columnConfig[
'colPos']) && $columnConfig[
'colPos'] !==
''
700 }
elseif (isset($columnConfig[
'colPos']) && $columnConfig[
'colPos'] !==
''
705 }
elseif (isset($columnConfig[
'name']) && $columnConfig[
'name'] !==
'') {
716 $out .= $grid .
'</table></div>';
724 if ($this->tt_contentConfig[
'languageMode']) {
732 foreach ($langListArr as $lP) {
736 <td valign="top" class="t3-page-column" data-language-uid="' . $lP .
'">
737 <h2>' . htmlspecialchars($this->tt_contentConfig[
'languageCols'][$lP]) .
'</h2>
744 $viewLink =
'<a href="#" class="btn btn-default btn-sm" onclick="' . htmlspecialchars($onClick) .
'" title="' . $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.showPage',
true) .
'">' . $this->iconFactory->getIcon(
'actions-view',
Icon::SIZE_SMALL)->render() .
'</a>';
750 $params =
'&edit[pages_language_overlay][' . $lpRecord[
'uid'] .
']=edit&overrideVals[pages_language_overlay][sys_language_uid]=' . $lP;
752 $this->iconFactory->getIconForRecord(
'pages_language_overlay', $lpRecord,
Icon::SIZE_SMALL)->render(),
753 'pages_language_overlay',
756 $editLink = ($this->
getBackendUser()->check(
'tables_modify',
'pages_language_overlay')
759 . $this->iconFactory->getIcon(
'actions-open',
Icon::SIZE_SMALL)->render() .
'</a>'
764 '<div class="btn-group">'
770 $params =
'&edit[pages][' . $this->
id .
']=edit';
773 $this->iconFactory->getIconForRecord(
'pages', $this->pageRecord,
Icon::SIZE_SMALL)->render(),
777 $editLink = ($this->
getBackendUser()->check(
'tables_modify',
'pages_language_overlay')
780 . $this->iconFactory->getIcon(
'actions-open',
Icon::SIZE_SMALL)->render() .
'</a>'
785 '<div class="btn-group">'
792 <td nowrap="nowrap" class="t3-page-column t3-page-lang-label">' . $lPLabel .
'</td>';
795 $out .=
'<tr>' . implode($cCont) .
'</tr>';
796 $out .=
'<tr>' . implode($sCont) .
'</tr>';
797 unset($cCont, $sCont);
800 foreach ($languageColumn as $cKey => $cCont) {
802 foreach ($cCont as $languageId => $columnContent) {
803 $out .=
'<td valign="top" class="t3-grid-cell t3-page-column t3js-page-column t3js-page-lang-column t3js-page-lang-column-' . $languageId .
'">' . $columnContent .
'</td>';
806 if ($this->defLangBinding) {
808 foreach ($defLanguageCount[$cKey] as $defUid) {
810 foreach ($langListArr as $lP) {
819 <td valign="top" class="t3-grid-cell">' . implode((
'</td>' .
'
820 <td valign="top" class="t3-grid-cell">'), $cCont) .
'</td>
826 $out = $languageSelector .
'
827 <div class="t3-grid-container">
828 <table cellpadding="0" cellspacing="0" class="t3-page-columns t3-grid-table t3js-page-columns">
862 if ($this->totalItems) {
863 $result = $this->
getDatabase()->exec_SELECT_queryArray($queryParts);
865 $dbCount = $this->
getDatabase()->sql_num_rows($result);
878 $out .=
'<tr class="t3-row-header">' .
'<th class="col-icon"></th>'
879 .
'<th colspan="' . (count($theData) - 2) .
'"><span class="c-table">'
880 . $localizedTableTitle .
'</span> (' . $dbCount .
')</td>' .
'<td class="col-icon"></td>'
885 $theData[
'__cmds__'] =
'<a href="#" onclick="' . htmlspecialchars($onClick) .
'" '
887 . $this->iconFactory->getIcon(
'actions-document-new',
Icon::SIZE_SMALL)->render() .
'</a>';
889 $out .= $this->
addElement(1,
'', $theData,
' class="c-headLine"', 15,
'',
'th');
892 while ($row = $this->
getDatabase()->sql_fetch_assoc($result)) {
894 if (is_array($row)) {
898 $params =
'&edit[' . $table .
'][' . $row[
'uid'] .
']=edit';
902 $Nrow[
'__cmds__'] = $this->
getIcon($table, $row);
905 $Nrow = $this->
dataFields($this->fieldArray, $table, $row, $Nrow);
910 . $this->iconFactory->getIcon(
'actions-document-open',
Icon::SIZE_SMALL)->render() .
'</a>';
912 $Nrow[
'__editIconLink__'] = $this->
noEditIcon();
923 Standard list of table "' . $table .
'"
925 <div class="table-fit"><table class="table table-striped">
954 foreach ($fieldArr as $fieldName) {
955 if (
$GLOBALS[
'TCA'][$table][
'columns'][$fieldName]) {
958 if ($fieldName == $thumbsCol) {
959 $out[$fieldName] = $this->
thumbCode($row, $table, $fieldName);
963 BackendUtility::getProcessedValue($table, $fieldName, $row[$fieldName], 0, 0, 0, $row[
'uid']),
970 $theFields = explode(
';', $fieldName);
972 foreach ($theFields as $fName2) {
973 if (
$GLOBALS[
'TCA'][$table][
'columns'][$fName2]) {
975 $GLOBALS[
'TCA'][$table][
'columns'][$fName2][
'label'],
978 BackendUtility::getProcessedValue($table, $fName2, $row[$fName2], 0, 0, 0, $row[
'uid']),
985 if (!$out[$fieldName]) {
986 $out[$fieldName] =
' ';
990 $out[$fieldName] =
'<span class="text-muted">' . $out[$fieldName] .
'</span>';
1007 foreach ($fieldArr as $fieldName) {
1009 $out[$fieldName] = $ll ? $ll :
' ';
1026 $columns = array_map(
'intval', $columns);
1027 $contentRecordsPerColumn = array_fill_keys($columns, array());
1029 $queryParts = $this->
makeQueryArray(
'tt_content',
$id,
'AND colPos IN (' . implode(
',', $columns) .
')' . $additionalWhereClause);
1030 $result = $this->
getDatabase()->exec_SELECT_queryArray($queryParts);
1034 foreach ($rowArr as $record) {
1035 $columnValue = $record[
'colPos'];
1036 $contentRecordsPerColumn[$columnValue][] = $record;
1039 return $contentRecordsPerColumn;
1061 $res = $this->
getDatabase()->exec_SELECTquery(
'*',
'pages',
'pid=' . (
int)$pid . $qWhere,
'',
'sorting');
1064 while ($row = $this->
getDatabase()->sql_fetch_assoc($res)) {
1066 if (is_array($row)) {
1068 $row[
'treeIcons'] = $treeIcons .
'<span class="treeline-icon treeline-icon-join' . ($rc === $c ?
'bottom' :
'') .
'"></span>';
1071 $spaceOutIcons =
'<span class="treeline-icon treeline-icon-' . ($rc === $c ?
'clear' :
'line') .
'"></span>';
1072 $theRows = $this->
pages_getTree($theRows, $row[
'uid'], $qWhere, $treeIcons . $spaceOutIcons, $row[
'php_tree_stop'] ? 0 : $depth);
1076 $count = $this->
getDatabase()->exec_SELECTcountRows(
'uid',
'pages',
'pid=' . (
int)$pid . $qWhere);
1078 $this->plusPages[$pid] = $count;
1094 $theIcon = $this->
getIcon(
'pages', $row);
1097 foreach ($fieldArr as $field) {
1100 $red = $this->plusPages[$row[
'uid']] ?
'<span class="text-danger"><strong>+</strong></span>' :
'';
1101 $pTitle = htmlspecialchars(BackendUtility::getProcessedValue(
'pages', $field, $row[$field], 20));
1103 $pTitle =
'<a href="'
1104 . htmlspecialchars($this->script . ((strpos($this->script,
'?') !==
false) ?
'&' :
'?')
1105 .
'id=' . $row[
'uid']) .
'">' . $pTitle .
'</a>';
1107 $theData[$field] = $row[
'treeIcons'] . $theIcon . $red . $pTitle .
' ';
1109 case 'php_tree_stop':
1112 $theData[$field] = $row[$field] ?
' <strong>x</strong>' :
' ';
1116 $params =
'&edit[pages][' . $row[
'uid'] .
']=edit';
1117 $eI =
'<a href="#" onclick="'
1120 . $this->iconFactory->getIcon(
'actions-document-open',
Icon::SIZE_SMALL)->render() .
'</a>';
1124 $theData[$field] =
'<span align="right">' . $row[
'uid'] . $eI .
'</span>';
1127 case 'shortcut_mode':
1128 if ((
int)$row[
'doktype'] === \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_SHORTCUT) {
1133 if (substr($field, 0, 6) ==
'table_') {
1134 $f2 = substr($field, 6);
1137 $theData[$field] =
' ' . ($c ? $c :
'');
1144 $this->addElement_tdParams[
'title'] = $row[
'_CSSCLASS'] ?
' class="' . $row[
'_CSSCLASS'] .
'"' :
'';
1158 return ' ' . htmlspecialchars(BackendUtility::getProcessedValue(
'pages', $field, $row[$field]));
1177 $iconsArr = array();
1179 if ($this->tt_contentConfig[
'showCommands']) {
1182 $iconsArr[
'edit'] =
'<a href="#" onclick="'
1185 . $this->iconFactory->getIcon(
'actions-document-open',
Icon::SIZE_SMALL)->render() .
'</a>';
1188 $elFromTable = $this->clipboard->elFromTable(
'tt_content');
1190 $iconsArr[
'paste'] =
'<a href="'
1191 . htmlspecialchars($this->clipboard->pasteUrl(
'tt_content', $this->id,
true, $pasteParams))
1192 .
'" onclick="' . htmlspecialchars((
'return '
1193 . $this->clipboard->confirmMsg(
'pages', $this->pageRecord,
'into', $elFromTable, $colName)))
1195 . $this->iconFactory->getIcon(
'actions-document-paste-into',
Icon::SIZE_SMALL)->render() .
'</a>';
1200 if (!empty($iconsArr)) {
1201 $icons =
'<div class="t3-page-column-header-icons">' . implode(
'', $iconsArr) .
'</div>';
1204 $out =
'<div class="t3-page-column-header">
1206 <div class="t3-page-column-header-label">' . htmlspecialchars($colName) .
'</div>
1223 $this->
getProcessedValue(
'tt_content',
'starttime,endtime,fe_group,spaceBefore,spaceAfter', $row, $info);
1226 if (!empty(
$GLOBALS[
'TCA'][
'tt_content'][
'ctrl'][
'descriptionColumn'])) {
1227 $info[] = htmlspecialchars($row[
$GLOBALS[
'TCA'][
'tt_content'][
'ctrl'][
'descriptionColumn']]);
1231 $drawFooterHooks = &
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'cms/layout/class.tx_cms_layout.php'][
'tt_content_drawFooter'];
1232 if (is_array($drawFooterHooks)) {
1233 foreach ($drawFooterHooks as $hookClass) {
1236 throw new \UnexpectedValueException(
'$hookObject must implement interface TYPO3\\CMS\\Backend\\View\\PageLayoutViewDrawFooterHookInterface', 1404378171);
1238 $hookObject->preProcess($this, $info, $row);
1243 if (!empty($info)) {
1244 $content =
'<div class="t3-page-ce-info">
1245 ' . implode(
'<br>', $info) .
'
1249 if (!empty($content)) {
1250 $content =
'<div class="t3-page-ce-footer">' . $content .
'</div>';
1265 public function tt_content_drawHeader($row, $space = 0, $disableMoveAndNewButtons =
false, $langMode =
false, $dragDropEnabled =
false)
1269 if ($this->tt_contentConfig[
'showInfo'] && $this->
getBackendUser()->recordEditAccessInternals(
'tt_content', $row)) {
1271 if ($this->tt_contentConfig[
'showCommands'] && $this->doEdit) {
1273 $params =
'&edit[tt_content][' . $this->tt_contentData[
'nextThree'][$row[
'uid']] .
']=edit';
1278 )) .
'" title="' . htmlspecialchars($this->nextThree > 1
1281 .
'">' . $this->iconFactory->getIcon(
'actions-document-open',
Icon::SIZE_SMALL)->render() .
'</a>';
1283 $hiddenField =
$GLOBALS[
'TCA'][
'tt_content'][
'ctrl'][
'enablecolumns'][
'disabled'];
1284 if ($hiddenField &&
$GLOBALS[
'TCA'][
'tt_content'][
'columns'][$hiddenField]
1285 && (!
$GLOBALS[
'TCA'][
'tt_content'][
'columns'][$hiddenField][
'exclude']
1286 || $this->
getBackendUser()->check(
'non_exclude_fields',
'tt_content:' . $hiddenField))
1288 if ($row[$hiddenField]) {
1295 $params =
'&data[tt_content][' . ($row[
'_ORIG_uid'] ? $row[
'_ORIG_uid'] : $row[
'uid'])
1296 .
'][' . $hiddenField .
']=' . $value;
1299 . $this->iconFactory->getIcon(
'actions-edit-' . strtolower($label),
Icon::SIZE_SMALL)->render() .
'</a>';
1302 $params =
'&cmd[tt_content][' . $row[
'uid'] .
'][delete]=1';
1305 . $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.translationsOfRecord')));
1307 .
' data-severity="warning"'
1308 .
' data-title="' . htmlspecialchars($this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_alt_doc.xlf:label.confirm.delete_record.title')) .
'"'
1309 .
' data-content="' . htmlspecialchars($confirm) .
'" '
1310 .
' data-button-close-text="' . htmlspecialchars($this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_common.xlf:cancel')) .
'"'
1312 . $this->iconFactory->getIcon(
'actions-edit-delete',
Icon::SIZE_SMALL)->render() .
'</a>';
1314 $out =
'<div class="btn-group btn-group-sm" role="group">' . $out .
'</div>';
1318 if (!$disableMoveAndNewButtons) {
1319 $moveButtonContent =
'';
1320 $displayMoveButtons =
false;
1322 if ($this->tt_contentData[
'prev'][$row[
'uid']]) {
1323 $params =
'&cmd[tt_content][' . $row[
'uid'] .
'][move]=' . $this->tt_contentData[
'prev'][$row[
'uid']];
1324 $moveButtonContent .=
'<a class="btn btn-default" href="'
1327 . $this->iconFactory->getIcon(
'actions-move-up',
Icon::SIZE_SMALL)->render() .
'</a>';
1328 if (!$dragDropEnabled) {
1329 $displayMoveButtons =
true;
1332 $moveButtonContent .=
'<span class="btn btn-default disabled">' . $this->iconFactory->getIcon(
'empty-empty',
Icon::SIZE_SMALL)->render() .
'</span>';
1335 if ($this->tt_contentData[
'next'][$row[
'uid']]) {
1336 $params =
'&cmd[tt_content][' . $row[
'uid'] .
'][move]= ' . $this->tt_contentData[
'next'][$row[
'uid']];
1337 $moveButtonContent .=
'<a class="btn btn-default" href="'
1340 . $this->iconFactory->getIcon(
'actions-move-down',
Icon::SIZE_SMALL)->render() .
'</a>';
1341 if (!$dragDropEnabled) {
1342 $displayMoveButtons =
true;
1345 $moveButtonContent .=
'<span class="btn btn-default disabled">' . $this->iconFactory->getIcon(
'empty-empty',
Icon::SIZE_SMALL)->render() .
'</span>';
1347 if ($displayMoveButtons) {
1348 $out .=
'<div class="btn-group btn-group-sm" role="group">' . $moveButtonContent .
'</div>';
1354 $additionalIcons = array();
1356 $disabledClickMenuItems =
'new,move';
1357 $allowDragAndDrop =
false;
1359 $additionalIcons[] = $this->
getIcon(
'tt_content', $row, $disabledClickMenuItems) .
' ';
1360 $additionalIcons[] = $langMode ? $this->
languageFlag($row[
'sys_language_uid'],
false) :
'';
1364 .
');return false;" title="' . htmlspecialchars($lockInfo[
'msg']) .
'">'
1365 . $this->iconFactory->getIcon(
'status-warning-in-use',
Icon::SIZE_SMALL)->render() .
'</a>';
1368 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'GLOBAL'][
'recStatInfoHooks'])) {
1369 $_params = array(
'tt_content', $row[
'uid'], &$row);
1370 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'GLOBAL'][
'recStatInfoHooks'] as $_funcRef) {
1376 return '<div class="t3-page-ce-header ' . ($allowDragAndDrop ?
't3-page-ce-header-draggable t3js-page-ce-draghandle' :
'') .
'">
1377 <div class="t3-page-ce-header-icons-left">' . implode(
'', $additionalIcons) .
'</div>
1378 <div class="t3-page-ce-header-icons-right">' . ($out ?
'<div class="btn-toolbar">' .$out .
'</div>' :
'') .
'</div>
1380 <div class="t3-page-ce-body">';
1392 || ((
int)$row[
'editlock'] === 0 && (
int)$this->pageinfo[
'editlock'] === 0)
1407 public function tt_content_drawItem($row)
1413 if ($row[
'header']) {
1415 $this->
getProcessedValue(
'tt_content',
'header_position,header_layout,header_link', $row, $infoArr);
1416 $hiddenHeaderNote =
'';
1418 if ($row[
'header_layout'] == 100) {
1419 $hiddenHeaderNote =
' <em>[' . $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.hidden',
true) .
']</em>';
1421 $outHeader = $row[
'date']
1422 ? htmlspecialchars($this->itemLabels[
'date'] .
' ' .
BackendUtility::date($row[
'date'])) .
'<br />'
1425 . $hiddenHeaderNote .
'</strong><br />';
1431 $drawItemHooks = &
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'cms/layout/class.tx_cms_layout.php'][
'tt_content_drawItem'];
1432 if (is_array($drawItemHooks)) {
1433 foreach ($drawItemHooks as $hookClass) {
1435 if (!$hookObject instanceof PageLayoutViewDrawItemHookInterface) {
1436 throw new \UnexpectedValueException(
'$hookObject must implement interface ' . \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface::class, 1218547409);
1438 $hookObject->preProcess($this, $drawItem, $outHeader, $out, $row);
1448 if (!empty($tsConfig[
'properties'][$row[
'CType']])) {
1449 $fluidTemplateFile = $tsConfig[
'properties'][$row[
'CType']];
1451 if ($fluidTemplateFile) {
1455 $view->setTemplatePathAndFilename($fluidTemplateFile);
1456 $view->assignMultiple($row);
1457 if (!empty($row[
'pi_flexform'])) {
1460 $view->assign(
'pi_flexform_transformed', $flexFormService->convertFlexFormContentToArray($row[
'pi_flexform']));
1462 $out = $view->render();
1464 }
catch (\Exception $e) {
1473 switch ($row[
'CType']) {
1475 if ($row[
'subheader']) {
1481 if ($row[
'bodytext']) {
1486 if ($row[
'media']) {
1491 $contentType = $this->CType_labels[$row[
'CType']];
1492 $out .= $this->
linkEditContent(
'<strong>' . htmlspecialchars($contentType) .
'</strong>', $row) .
'<br />';
1497 $menuTypeLabel = $menuTypeLabel ?:
'invalid menu type';
1499 if ($row[
'menu_type'] !==
'2' && ($row[
'pages'] || $row[
'selected_categories'])) {
1505 if (!empty($row[
'records'])) {
1506 $shortcutContent = array();
1507 $recordList = explode(
',', $row[
'records']);
1508 foreach ($recordList as $recordIdentifier) {
1510 $tableName = empty($split[0]) ?
'tt_content' : $split[0];
1512 if (is_array($shortcutRecord)) {
1513 $icon = $this->iconFactory->getIconForRecord($tableName, $shortcutRecord,
Icon::SIZE_SMALL)->render();
1517 $shortcutRecord[
'uid'],
1520 '+copy,info,edit,view'
1522 $shortcutContent[] = $icon
1526 $out .= implode(
'<br />', $shortcutContent) .
'<br />';
1532 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'cms/layout/class.tx_cms_layout.php'][
'list_type_Info'][$row[
'list_type']])) {
1533 $hookArr =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'cms/layout/class.tx_cms_layout.php'][
'list_type_Info'][$row[
'list_type']];
1534 }
elseif (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'cms/layout/class.tx_cms_layout.php'][
'list_type_Info'][
'_DEFAULT'])) {
1535 $hookArr =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'cms/layout/class.tx_cms_layout.php'][
'list_type_Info'][
'_DEFAULT'];
1537 if (!empty($hookArr)) {
1538 $_params = array(
'pObj' => &$this,
'row' => $row,
'infoArr' => $infoArr);
1539 foreach ($hookArr as $_funcRef) {
1543 if ((
string)$hookOut !==
'') {
1545 }
elseif (!empty($row[
'list_type'])) {
1547 if (!empty($label)) {
1550 $message = sprintf($this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue'), $row[
'list_type']);
1552 FlashMessage::class,
1553 htmlspecialchars($message),
1558 }
elseif (!empty($row[
'select_key'])) {
1560 .
' ' . $row[
'select_key'] .
'<br />';
1562 $out .=
'<strong>' . $this->
getLanguageService()->getLL(
'noPluginSelected') .
'</strong>';
1570 $contentType = $this->CType_labels[$row[
'CType']];
1572 if (isset($contentType)) {
1573 $out .= $this->
linkEditContent(
'<strong>' . htmlspecialchars($contentType) .
'</strong>', $row) .
'<br />';
1574 if ($row[
'bodytext']) {
1577 if ($row[
'image']) {
1582 $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue'),
1586 FlashMessage::class,
1587 htmlspecialchars($message),
1596 <span class="exampleContent">' . $out .
'</span>';
1598 $out = $outHeader . $out;
1601 return '<span class="text-muted">' . $out .
'</span>';
1618 if (strpos($row[
'menu_type'],
'categorized_') !==
false) {
1620 $field =
'selected_categories';
1622 if (trim($row[$field]) ===
'') {
1626 $uidList = explode(
',', $row[$field]);
1627 foreach ($uidList as $uid) {
1630 $content .=
'<br>' . $record[
'title'] .
' (' .$uid.
')';
1647 if ($lP && !empty($defLanguageCount)) {
1649 $where =
'sys_language_uid=' . intval($lP) .
' AND l18n_parent IN ('
1650 . implode(
',', $defLanguageCount) .
')'
1652 $rowArr = $this->
getDatabase()->exec_SELECTgetRows(
'*',
'tt_content', $where);
1655 $defLanguageCount = array_flip($defLanguageCount);
1657 foreach ($rowArr as $row) {
1659 unset($defLanguageCount[$row[
'l18n_parent']]);
1662 $defLanguageCount = array_keys($defLanguageCount);
1664 return $defLanguageCount;
1678 if (!$this->doEdit || !$lP) {
1683 if (!empty($defLanguageCount)) {
1686 .
' class="btn btn-default t3js-localize"'
1689 .
' value="' . htmlspecialchars($this->
getLanguageService()->getLL(
'newPageContent_translate',
true)) .
'"'
1690 .
' data-has-elements="' . (int)!empty($this->contentElementCache[$lP][$colPos]) .
'"'
1691 .
' data-table="tt_content"'
1693 .
' data-language-id="' . $lP .
'"'
1694 .
' data-language-name="' . htmlspecialchars($this->tt_contentConfig[
'languageCols'][$lP]) .
'"'
1695 .
' data-colpos-id="' . $colPos .
'"'
1696 .
' data-colpos-name="' . BackendUtility::getProcessedValue(
'tt_content',
'colPos', $colPos) .
'"'
1700 return '<div class="t3-page-lang-copyce">' . $theNewButton .
'</div>';
1714 if ($this->option_newWizard) {
1715 $onClick =
'window.location.href=' .
GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl(
'new_content_element') .
'&id=' .
$id .
'&colPos=' . $colPos
1716 .
'&sys_language_uid=' . $sys_language .
'&uid_pid=' .
$id
1720 . $colPos .
'&defVals[tt_content][sys_language_uid]=' . $sys_language);
1738 if ($this->doEdit && $this->
getBackendUser()->recordEditAccessInternals(
'tt_content', $row)) {
1743 return $onClick ?
'<a href="#" onclick="' . htmlspecialchars($onClick)
1744 .
'" title="' . $this->
getLanguageService()->getLL(
'edit',
true) .
'">' . $str .
'</a>' . $addButton : $str;
1758 if ($this->
getBackendUser()->check(
'tables_modify',
'pages_language_overlay')) {
1761 $langSelItems = array();
1762 $langSelItems[0] =
'
1763 <option value="0"></option>';
1764 while ($row = $this->
getDatabase()->sql_fetch_assoc($res)) {
1766 $langSelItems[$row[
'uid']] =
'
1767 <option value="' . $row[
'uid'] .
'">' . htmlspecialchars($row[
'title']) .
'</option>';
1772 while ($row = $this->
getDatabase()->sql_fetch_assoc($res)) {
1773 unset($langSelItems[$row[
'uid']]);
1776 if (count($langSelItems) > 1
1778 && $this->
getBackendUser()->groupData[
'allowed_languages'] !==
''
1780 $allowed_languages = array_flip(explode(
',', $this->
getBackendUser()->groupData[
'allowed_languages']));
1781 if (!empty($allowed_languages)) {
1782 foreach ($langSelItems as $key => $value) {
1783 if (!isset($allowed_languages[$key]) && $key != 0) {
1784 unset($langSelItems[$key]);
1794 if (!empty($langSelItems) && !empty($disableLanguages)) {
1795 foreach ($disableLanguages as $language) {
1796 if ($language != 0 && isset($langSelItems[$language])) {
1797 unset($langSelItems[$language]);
1802 if (count($langSelItems) > 1) {
1803 $url = BackendUtility::getModuleUrl(
'record_edit', array(
1804 'edit[pages_language_overlay]['.
$id .
']' =>
'new',
1805 'overrideVals[pages_language_overlay][doktype]' => (
int)$this->pageRecord[
'doktype'],
1808 $onChangeContent =
'window.location.href=' .
GeneralUtility::quoteJSvalue(
$url .
'&overrideVals[pages_language_overlay][sys_language_uid]=') .
'+this.options[this.selectedIndex].value';
1809 return '<div class="form-inline form-inline-spaced">'
1810 .
'<div class="form-group">'
1811 .
'<label for="createNewLanguage">'
1814 .
'<select class="form-control input-sm" name="createNewLanguage" onchange="' . htmlspecialchars($onChangeContent) .
'">'
1815 . implode(
'', $langSelItems)
1816 .
'</select></div></div>';
1833 while ($row = $this->
getDatabase()->sql_fetch_assoc($result)) {
1866 $this->clipboard->initializeClipboard();
1869 $this->clipboard->lockToNormal();
1872 $this->clipboard->cleanCurrent();
1875 $this->clipboard->endClipboard();
1886 if (empty($this->tt_contentData)) {
1887 $this->tt_contentData = array(
1888 'nextThree' => array(),
1893 foreach ($rowArray as $key => $value) {
1896 if (isset($rowArray[$key - $i])
1897 && !
GeneralUtility::inList($this->tt_contentData[
'nextThree'][$rowArray[$key - $i][
'uid']], $value[
'uid'])
1899 $this->tt_contentData[
'nextThree'][$rowArray[$key - $i][
'uid']] .= $value[
'uid'] .
',';
1904 if (isset($rowArray[$key - 1])) {
1905 if (isset($rowArray[$key - 2])) {
1906 $this->tt_contentData[
'prev'][$value[
'uid']] = -$rowArray[$key - 2][
'uid'];
1908 $this->tt_contentData[
'prev'][$value[
'uid']] = $value[
'pid'];
1910 $this->tt_contentData[
'next'][$rowArray[$key - 1][
'uid']] = -$value[
'uid'];
1927 $count = $this->
getDatabase()->exec_SELECTcountRows(
'uid', $table, $where);
1940 $input = strip_tags($input);
1942 return nl2br(htmlspecialchars(trim($input), ENT_QUOTES,
'UTF-8',
false));
1957 $icon =
'<span ' . $toolTip .
'>' . $this->iconFactory->getIconForRecord(
$table, $row,
Icon::SIZE_SMALL)->render() .
'</span>';
1979 $fieldArr = explode(
',', $fieldList);
1981 foreach ($fieldArr as $field) {
1983 $info[] =
'<strong>' . htmlspecialchars($this->itemLabels[$field]) .
'</strong> '
1984 . htmlspecialchars(BackendUtility::getProcessedValue(
$table, $field, $row[$field]));
1999 return $enableCols[
'disabled'] && $row[$enableCols[
'disabled']]
2000 || $enableCols[
'starttime'] && $row[$enableCols[
'starttime']] >
$GLOBALS[
'EXEC_TIME']
2001 || $enableCols[
'endtime'] && $row[$enableCols[
'endtime']] && $row[$enableCols[
'endtime']] <
$GLOBALS[
'EXEC_TIME'];
2015 return '<span title="' . $title .
'">' . $this->iconFactory->getIcon(
'status-status-edit-read-only',
Icon::SIZE_SMALL)->render() .
'</span>';
2028 $tableNames = array_flip(array_keys(
$GLOBALS[
'TCA']));
2030 unset($tableNames[
'pages']);
2031 unset($tableNames[
'static_template']);
2032 unset($tableNames[
'sys_filemounts']);
2033 unset($tableNames[
'sys_action']);
2034 unset($tableNames[
'sys_workflows']);
2035 unset($tableNames[
'be_users']);
2036 unset($tableNames[
'be_groups']);
2037 $allowedTableNames = array();
2039 if (is_array($tableNames)) {
2040 foreach ($tableNames as $k => $v) {
2042 $allowedTableNames[
'table_' . $k] = $k;
2046 return $allowedTableNames;
2066 $this->activeTables = array();
2067 $theTables = array(
'tt_content');
2069 if (is_array($this->externalTables)) {
2070 $theTables = array_unique(array_merge($theTables, array_keys($this->externalTables)));
2074 foreach ($theTables as $tName) {
2077 && (isset($this->externalTables[$tName])
2079 || \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($tName)
2083 $c = $this->
getDatabase()->exec_SELECTcountRows(
'uid', $tName,
'pid=' . (
int)
$id
2089 <td><a href="#' . $tName .
'" title="' . $this->
getLanguageService()->sL(
$GLOBALS[
'TCA'][$tName][
'ctrl'][
'title'],
true) .
'"></a>'
2090 . $this->iconFactory->getIconForRecord($tName, array(),
Icon::SIZE_SMALL)->render()
2095 $this->activeTables[$tName] =
'<span title="' . $title.
'">'
2096 . $this->iconFactory->getIconForRecord($tName, array(),
Icon::SIZE_SMALL)->render()
2105 Menu of tables on the page (table menu)
2107 <table border="0" cellpadding="0" cellspacing="0" id="typo3-page-tblMenu">
2125 return BackendUtility::thumbCode($row,
$table, $field,
'',
'', null, 0,
'',
'',
false);
2143 if ($language === 0 || $allowInconsistentLanguageHandling[
'value'] ===
'1') {
2149 if (!isset($this->languageHasTranslationsCache[$language])) {
2150 foreach ($contentElements as $columns) {
2151 foreach ($columns as $contentElement) {
2152 if ((
int)$contentElement[
'l18n_parent'] === 0) {
2153 $this->languageHasTranslationsCache[$language][
'hasStandAloneContent'] =
true;
2155 if ((
int)$contentElement[
'l18n_parent'] > 0) {
2156 $this->languageHasTranslationsCache[$language][
'hasTranslations'] =
true;
2161 if ($this->languageHasTranslationsCache[$language][
'hasStandAloneContent']
2162 && $this->languageHasTranslationsCache[$language][
'hasTranslations']
2165 FlashMessage::class,
2166 sprintf($this->
getLanguageService()->getLL(
'staleTranslationWarning'), $this->languageIconTitles[$language][
'title']),
2167 sprintf($this->
getLanguageService()->getLL(
'staleTranslationWarningTitle'), $this->languageIconTitles[$language][
'title']),
2171 $queue = $service->getMessageQueueByIdentifier();
2172 $queue->addMessage($message);
2175 if ($this->languageHasTranslationsCache[$language][
'hasTranslations']) {