/** * Draw the header for a single tt_content element * * @param array $row Record array * @param int $space Amount of pixel space above the header. UNUSED * @param bool $disableMoveAndNewButtons If set the buttons for creating new elements and moving up and down are not shown. * @param bool $langMode If set, we are in language mode and flags will be shown for languages * @param bool $dragDropEnabled If set the move button must be hidden * @return string HTML table with the record header. */ public function tt_content_drawHeader($row, $space = 0, $disableMoveAndNewButtons = false, $langMode = false, $dragDropEnabled = false) { $out = ''; // If show info is set...; if ($this->tt_contentConfig['showInfo'] && $this->getBackendUser()->recordEditAccessInternals('tt_content', $row)) { // Render control panel for the element: if ($this->tt_contentConfig['showCommands'] && $this->doEdit) { // Edit content element: $params = '&edit[tt_content][' . $this->tt_contentData['nextThree'][$row['uid']] . ']=edit'; $out .= '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, '', GeneralUtility::getIndpEnv('REQUEST_URI') . '#element-tt_content-' . $row['uid'])) . '" title="' . htmlspecialchars($this->nextThree > 1 ? sprintf($this->getLanguageService()->getLL('nextThree'), $this->nextThree) : $this->getLanguageService()->getLL('edit')) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>'; // Hide element: $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled']; if ($hiddenField && $GLOBALS['TCA']['tt_content']['columns'][$hiddenField] && (!$GLOBALS['TCA']['tt_content']['columns'][$hiddenField]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', 'tt_content:' . $hiddenField))) { if ($row[$hiddenField]) { $value = 0; $label = 'unHide'; } else { $value = 1; $label = 'hide'; } $params = '&data[tt_content][' . ($row['_ORIG_uid'] ? $row['_ORIG_uid'] : $row['uid']) . '][' . $hiddenField . ']=' . $value; $out .= '<a class="btn btn-default" href="' . htmlspecialchars(BackendUtility::getLinkToDataHandlerAction($params)) . '" title="' . $this->getLanguageService()->getLL($label, true) . '">' . $this->iconFactory->getIcon('actions-edit-' . strtolower($label), Icon::SIZE_SMALL)->render() . '</a>'; } // Delete $params = '&cmd[tt_content][' . $row['uid'] . '][delete]=1'; $confirm = $this->getLanguageService()->getLL('deleteWarning') . BackendUtility::translationCount('tt_content', $row['uid'], ' ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.translationsOfRecord')); $out .= '<a class="btn btn-default t3js-modal-trigger" href="' . htmlspecialchars(BackendUtility::getLinkToDataHandlerAction($params)) . '"' . ' data-severity="warning"' . ' data-title="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_alt_doc.xlf:label.confirm.delete_record.title')) . '"' . ' data-content="' . htmlspecialchars($confirm) . '" ' . ' data-button-close-text="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_common.xlf:cancel')) . '"' . ' title="' . $this->getLanguageService()->getLL('deleteItem', true) . '">' . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . '</a>'; if ($out && $this->getBackendUser()->doesUserHaveAccess($this->pageinfo, Permission::CONTENT_EDIT)) { $out = '<div class="btn-group btn-group-sm" role="group">' . $out . '</div>'; } else { $out = ''; } if (!$disableMoveAndNewButtons) { $moveButtonContent = ''; $displayMoveButtons = false; // Move element up: if ($this->tt_contentData['prev'][$row['uid']]) { $params = '&cmd[tt_content][' . $row['uid'] . '][move]=' . $this->tt_contentData['prev'][$row['uid']]; $moveButtonContent .= '<a class="btn btn-default" href="' . htmlspecialchars(BackendUtility::getLinkToDataHandlerAction($params)) . '" title="' . $this->getLanguageService()->getLL('moveUp', true) . '">' . $this->iconFactory->getIcon('actions-move-up', Icon::SIZE_SMALL)->render() . '</a>'; if (!$dragDropEnabled) { $displayMoveButtons = true; } } else { $moveButtonContent .= '<span class="btn btn-default disabled">' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>'; } // Move element down: if ($this->tt_contentData['next'][$row['uid']]) { $params = '&cmd[tt_content][' . $row['uid'] . '][move]= ' . $this->tt_contentData['next'][$row['uid']]; $moveButtonContent .= '<a class="btn btn-default" href="' . htmlspecialchars(BackendUtility::getLinkToDataHandlerAction($params)) . '" title="' . $this->getLanguageService()->getLL('moveDown', true) . '">' . $this->iconFactory->getIcon('actions-move-down', Icon::SIZE_SMALL)->render() . '</a>'; if (!$dragDropEnabled) { $displayMoveButtons = true; } } else { $moveButtonContent .= '<span class="btn btn-default disabled">' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>'; } if ($displayMoveButtons) { $out .= '<div class="btn-group btn-group-sm" role="group">' . $moveButtonContent . '</div>'; } } } } $additionalIcons = array(); $additionalIcons[] = $this->getIcon('tt_content', $row) . ' '; $additionalIcons[] = $langMode ? $this->languageFlag($row['sys_language_uid'], false) : ''; // Get record locking status: if ($lockInfo = BackendUtility::isRecordLocked('tt_content', $row['uid'])) { $additionalIcons[] = '<a href="#" onclick="alert(' . GeneralUtility::quoteJSvalue($lockInfo['msg']) . ');return false;" title="' . htmlspecialchars($lockInfo['msg']) . '">' . $this->iconFactory->getIcon('status-warning-in-use', Icon::SIZE_SMALL)->render() . '</a>'; } // Call stats information hook if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) { $_params = array('tt_content', $row['uid'], &$row); foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) { $additionalIcons[] = GeneralUtility::callUserFunction($_funcRef, $_params, $this); } } // Wrap the whole header // NOTE: end-tag for <div class="t3-page-ce-body"> is in getTable_tt_content() return '<div class="t3-page-ce-header ' . ($this->isDragAndDropAllowed($row) ? 't3-page-ce-header-draggable t3js-page-ce-draghandle' : '') . '"> <div class="t3-page-ce-header-icons-left">' . implode('', $additionalIcons) . '</div> <div class="t3-page-ce-header-icons-right">' . ($out ? '<div class="btn-toolbar">' . $out . '</div>' : '') . '</div> </div> <div class="t3-page-ce-body">'; }
/** * Adding CM element for Delete * * @param string $table Table name * @param integer $uid UID for the current record. * @param array $elInfo Label for including in the confirmation message, EXT:lang/locallang_core.php:mess.delete * @return array Item array, element in $menuItems * @internal * @todo Define visibility */ public function DB_delete($table, $uid, $elInfo) { $editOnClick = ''; $loc = 'top.content.list_frame'; if ($GLOBALS['BE_USER']->jsConfirmation(4)) { $conf = 'confirm(' . $GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.delete'), $elInfo[0]) . \TYPO3\CMS\Backend\Utility\BackendUtility::referenceCount($table, $uid, ' (There are %s reference(s) to this record!)') . \TYPO3\CMS\Backend\Utility\BackendUtility::translationCount($table, $uid, ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.translationsOfRecord'))) . ')'; } else { $conf = '1==1'; } $editOnClick = 'if(' . $loc . ' && ' . $conf . ' ){' . $loc . '.location.href=top.TS.PATH_typo3+\'tce_db.php?redirect=\'+top.rawurlencode(' . $this->frameLocation($loc . '.document') . '.pathname+' . $this->frameLocation($loc . '.document') . '.search)+\'' . '&cmd[' . $table . '][' . $uid . '][delete]=1&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . \TYPO3\CMS\Backend\Utility\BackendUtility::getUrlToken('tceAction') . '\';}hideCM();top.nav.refresh.defer(500, top.nav);'; return $this->linkItem($this->label('delete'), $this->excludeIcon(\TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-delete')), $editOnClick . 'return false;'); }
/** * Creates the control panel for a single record in the listing. * * @param string $table The table * @param array $row The record for which to make the control panel. * * @return string HTML table with the control panel (unless disabled) * @throws UnexpectedValueException If hook was of wrong interface */ public function makeControl($table, array $row) { $backendUser = $this->getBackendUser(); $language = $this->getLanguageService(); if ($this->dontShowClipControlPanels) { return ''; } $rowUid = $row['uid']; if (ExtensionManagementUtility::isLoaded('version') && isset($row['_ORIG_uid'])) { $rowUid = $row['_ORIG_uid']; } $cells = array(); // If the listed table is 'pages' we have to request // the permission settings for each page: $localCalcPerms = 0; if ($table == 'tx_commerce_categories' || $table == 'tx_commerce_products') { /** * Utility * * @var \CommerceTeam\Commerce\Utility\BackendUserUtility $utility */ $utility = GeneralUtility::makeInstance('CommerceTeam\\Commerce\\Utility\\BackendUserUtility'); $localCalcPerms = $utility->calcPerms((array) BackendUtility::getRecord('tx_commerce_categories', $this->parentUid)); } // This expresses the edit permissions for this particular element: $permsEdit = $table == 'tx_commerce_categories' && $localCalcPerms & 2 || $table != 'tx_commerce_categories' && $this->calcPerms & 16; // "Show" link (only tx_commerce_categories and tx_commerce_products elements) if ($table == 'tx_commerce_categories' || $table == 'tx_commerce_products') { $cells['view'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($table === 'tx_commerce_products' ? $this->id : $row['uid'], $this->backPath, '', $table === 'tx_commerce_products' ? '#' . $row['uid'] : '')) . '" title="' . $language->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-view') . '</a>'; } elseif (!$this->table) { $cells['view'] = $this->spaceIcon; } // "Edit" link: ( Only if permissions to edit the page-record of // the content of the parent page ($this->id) if ($permsEdit) { $params = '&edit[' . $table . '][' . $row['uid'] . ']=edit'; $cells['edit'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, $this->backPath, -1)) . '" title="' . $language->getLL('edit', TRUE) . '">' . ($GLOBALS['TCA'][$table]['ctrl']['readOnly'] ? IconUtility::getSpriteIcon('actions-document-open-read-only') : IconUtility::getSpriteIcon('actions-document-open')) . '</a>'; } elseif (!$this->table) { $cells['edit'] = $this->spaceIcon; } // "Move" wizard link for tx_commerce_categories/tx_commerce_products elements: if ($table == 'tx_commerce_products' && $permsEdit || $table == 'tx_commerce_categories') { $options = array('title' => $language->getLL('move_' . ($table == 'tx_commerce_products' ? 'record' : 'page'), TRUE)); $cells['move'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'move_el.php?table=' . $table . '&uid=' . $row['uid'] . '\');') . '">' . ($table == 'tx_commerce_products' ? IconUtility::getSpriteIcon('actions-document-move', $options) : IconUtility::getSpriteIcon('actions-page-move', $options)) . '</a>'; } elseif (!$this->table) { $cells['move'] = $this->spaceIcon; } // If the extended control panel is enabled OR if we are seeing a single table: if ($GLOBALS['SOBE']->MOD_SETTINGS['bigControlPanel'] || $this->table) { // "Info": (All records) $cells['viewBig'] = '<a href="#" onclick="' . htmlspecialchars('top.launchView(\'' . $table . '\', \'' . $row['uid'] . '\'); return false;') . '" title="' . $language->getLL('showInfo', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-info') . '</a>'; // If the table is NOT a read-only table, then show these links: if (!$GLOBALS['TCA'][$table]['ctrl']['readOnly']) { // "Revert" link (history/undo) $cells['history'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'show_rechis.php?element=' . rawurlencode($table . ':' . $row['uid']) . '\',\'#latest\');') . '" title="' . $language->getLL('history', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>'; // Versioning: if (ExtensionManagementUtility::isLoaded('version') && !ExtensionManagementUtility::isLoaded('workspaces')) { $vers = BackendUtility::selectVersionsOfRecord($table, $row['uid'], 'uid', $this->getBackendUser()->workspace, FALSE, $row); // If table can be versionized. if (is_array($vers)) { $versionIcon = 'no-version'; if (count($vers) > 1) { $versionIcon = count($vers) - 1; } $cells['version'] = '<a href="' . htmlspecialchars($this->backPath . ExtensionManagementUtility::extRelPath('version') . 'cm1/index.php?table=' . rawurlencode($table) . '&uid=' . rawurlencode($row['uid'])) . '" title="' . $language->getLL('displayVersions', TRUE) . '">' . IconUtility::getSpriteIcon('status-version-' . $versionIcon) . '</a>'; } elseif (!$this->table) { $cells['version'] = $this->spaceIcon; } } // "Edit Perms" link: if ($table == 'tx_commerce_categories' && $backendUser->check('modules', 'txcommerceM1_permission')) { $cells['perms'] = '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('txcommerceM1_permission') . '&control[tx_commerce_categories][uid]=' . $row['uid'] . '&return_id=' . $row['uid'] . '&edit=1') . '">' . IconUtility::getSpriteIcon('status-status-locked', array('titel' => $language->getLL('permissions', TRUE))) . '</a>'; } elseif (!$this->table && $backendUser->check('modules', 'web_perm')) { $cells['perms'] = $this->spaceIcon; } // "New record after" link (ONLY if the records in the table are sorted // by a "sortby"-row or if default values can depend on previous record): if ($GLOBALS['TCA'][$table]['ctrl']['sortby'] || $GLOBALS['TCA'][$table]['ctrl']['useColumnsForDefaultValues']) { if ($table != 'tx_commerce_categories' && $this->calcPerms & 16 || $table == 'tx_commerce_categories' && $this->calcPerms & 8) { if ($this->showNewRecLink($table) && $this->parentUid) { $params = '&edit[' . $table . '][' . -($row['_MOVE_PLH'] ? $row['_MOVE_PLH_uid'] : $row['uid']) . ']=new'; $options = array('title' => $language->getLL('new' . ($table == 'tx_commerce_categories' ? 'Category' : 'Record'), TRUE)); $cells['new'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, $this->backPath, -1)) . '"' . ($table == 'tx_commerce_categories' ? IconUtility::getSpriteIcon('actions-page-new', $options) : IconUtility::getSpriteIcon('actions-document-new', $options)) . '</a>'; } } } elseif (!$this->table) { $cells['new'] = $this->spaceIcon; } // "Up/Down" links if ($permsEdit && $GLOBALS['TCA'][$table]['ctrl']['sortby'] && !$this->sortField && !$this->searchLevels) { // Up if (isset($this->currentTable['prev'][$row['uid']])) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prev'][$row['uid']]; $cells['moveUp'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $language->getLL('moveUp', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-up') . '</a>'; } else { $cells['moveUp'] = $this->spaceIcon; } // Down if ($this->currentTable['next'][$row['uid']]) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['next'][$row['uid']]; $cells['moveDown'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $language->getLL('moveDown', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-down') . '</a>'; } else { $cells['moveDown'] = $this->spaceIcon; } } elseif (!$this->table) { $cells['moveUp'] = $this->spaceIcon; $cells['moveDown'] = $this->spaceIcon; } // "Hide/Unhide" links: $hiddenField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']; if ($permsEdit && $hiddenField && $GLOBALS['TCA'][$table]['columns'][$hiddenField] && (!$GLOBALS['TCA'][$table]['columns'][$hiddenField]['exclude'] || $backendUser->check('non_exclude_fields', $table . ':' . $hiddenField))) { if ($row[$hiddenField]) { $params = '&data[' . $table . '][' . $rowUid . '][' . $hiddenField . ']=0'; $cells['hide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $language->getLL('unHide' . ($table == 'tx_commerce_categories' ? 'Category' : ''), TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-unhide') . '</a>'; } else { $params = '&data[' . $table . '][' . $rowUid . '][' . $hiddenField . ']=1'; $cells['hide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $language->getLL('hide' . ($table == 'tx_commerce_categories' ? 'Category' : ''), TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-hide') . '</a>'; } } elseif (!$this->table) { $cells['hide'] = $this->spaceIcon; } // "Delete" link: if ($table == 'tx_commerce_categories' && $localCalcPerms & 4 || $table != 'tx_commerce_categories' && $this->calcPerms & 16) { $titleOrig = BackendUtility::getRecordTitle($table, $row, FALSE, TRUE); $title = GeneralUtility::slashJS(GeneralUtility::fixed_lgd_cs($titleOrig, $this->fixedL), 1); $params = '&cmd[' . $table . '][' . $row['uid'] . '][delete]=1'; $refCountMsg = BackendUtility::referenceCount($table, $row['uid'], ' ' . $language->sL('LLL:EXT:lang/locallang_core.xml:labels.referencesToRecord'), $this->getReferenceCount($table, $row['uid'])) . BackendUtility::translationCount($table, $row['uid'], ' ' . $language->sL('LLL:EXT:lang/locallang_core.xml:labels.translationsOfRecord')); $cells['delete'] = '<a href="#" onclick="' . htmlspecialchars('if (confirm(' . $language->JScharCode($language->getLL('deleteWarning') . ' "' . $title . '" ' . $refCountMsg) . ')) {jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');} return false;') . '">' . IconUtility::getSpriteIcon('actions-edit-delete', array('title' => $language->getLL('delete', TRUE))) . '</a>'; } elseif (!$this->table) { $cells['delete'] = $this->spaceIcon; } // "Levels" links: Moving pages into new levels... // @todo make moving left and right working with custom wizard if ($permsEdit && $table == 'pages' && !$this->searchLevels) { // Up (Paste as the page right after the current parent page) if ($this->calcPerms & 8) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . -$this->id; $cells['moveLeft'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $language->getLL('prevLevel', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-left') . '</a>'; } // Down (Paste as subpage to the page right above) if ($this->currentTable['prevUid'][$row['uid']]) { $localCalcPerms = $backendUser->calcPerms(BackendUtility::getRecord('tx_commerce_categories', $this->currentTable['prevUid'][$row['uid']])); if ($localCalcPerms & 8) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prevUid'][$row['uid']]; $cells['moveRight'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $language->getLL('nextLevel', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-right') . '</a>'; } else { $cells['moveRight'] = $this->spaceIcon; } } else { $cells['moveRight'] = $this->spaceIcon; } } elseif (!$this->table) { $cells['moveLeft'] = $this->spaceIcon; $cells['moveRight'] = $this->spaceIcon; } } } /** * Record stat info hooks: Allows to insert HTML * before record icons on various places * @date 2007-09-22 * @request Kasper Skårhøj <*****@*****.**> */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) { $stat = ''; $parameter = array($table, $row['uid']); foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $functionReference) { $stat .= GeneralUtility::callUserFunction($functionReference, $parameter, $this); } $cells['stat'] = $stat; } /** * Make control Hook: Allows to change control icons of records in list-module * @date 2007-11-20 * @request Bernhard Kraft <*****@*****.**> * @usage This hook method gets passed the current $cells * array as third parameter. This array contains values for the * icons/actions generated for each record in Web>List. * Each array entry is accessible by an index-key. The order of the * icons is dependend on the order of those array entries. */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) { $hookObject = GeneralUtility::getUserObj($classData); if (!$hookObject instanceof \TYPO3\CMS\Recordlist\RecordList\RecordListHookInterface) { throw new UnexpectedValueException('$hookObject must implement interface \\TYPO3\\CMS\\Recordlist\\RecordList\\RecordListHookInterface', 1195567840); } $cells = $hookObject->makeControl($table, $row, $cells, $this); } } // Compile items into a DIV-element: return ' <!-- CONTROL PANEL: ' . $table . ':' . $row['uid'] . ' --> <div class="typo3-DBctrl">' . implode('', $cells) . '</div>'; }
/** * Creates the control panel for a single record in the listing. * * @param string $table The table * @param mixed[] $row The record for which to make the control panel. * @throws \UnexpectedValueException * @return string HTML table with the control panel (unless disabled) */ public function makeControl($table, $row) { $module = $this->getModule(); $rowUid = $row['uid']; if (ExtensionManagementUtility::isLoaded('version') && isset($row['_ORIG_uid'])) { $rowUid = $row['_ORIG_uid']; } $cells = array('primary' => array(), 'secondary' => array()); // If the listed table is 'pages' we have to request the permission settings for each page: $localCalcPerms = 0; if ($table == 'pages') { $localCalcPerms = $this->getBackendUserAuthentication()->calcPerms(BackendUtility::getRecord('pages', $row['uid'])); } $permsEdit = $table === 'pages' && $this->getBackendUserAuthentication()->checkLanguageAccess(0) && $localCalcPerms & Permission::PAGE_EDIT || $table !== 'pages' && $this->calcPerms & Permission::CONTENT_EDIT; $permsEdit = $this->overlayEditLockPermissions($table, $row, $permsEdit); // "Show" link (only pages and tt_content elements) if ($table == 'pages' || $table == 'tt_content') { $viewAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($table === 'tt_content' ? $this->id : $row['uid'], '', '', $table === 'tt_content' ? '#' . $row['uid'] : '')) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', true) . '">' . $this->iconFactory->getIcon('actions-view', Icon::SIZE_SMALL)->render() . '</a>'; $this->addActionToCellGroup($cells, $viewAction, 'view'); } // "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id) if ($permsEdit) { $params = '&edit[' . $table . '][' . $row['uid'] . ']=edit'; $iconIdentifier = 'actions-open'; $overlayIdentifier = !$this->isEditable($table) ? 'overlay-readonly' : null; $editAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, '', -1)) . '" title="' . $this->getLanguageService()->getLL('edit', true) . '">' . $this->iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL, $overlayIdentifier)->render() . '</a>'; } else { $editAction = $this->spaceIcon; } $this->addActionToCellGroup($cells, $editAction, 'edit'); // "Info": (All records) $onClick = 'top.launchView(' . GeneralUtility::quoteJSvalue($table) . ', ' . (int) $row['uid'] . '); return false;'; $viewBigAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $this->getLanguageService()->getLL('showInfo', true) . '">' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . '</a>'; $this->addActionToCellGroup($cells, $viewBigAction, 'viewBig'); // "Move" wizard link for pages/tt_content elements: if ($permsEdit && ($table === 'tt_content' || $table === 'pages')) { $onClick = 'return jumpExt(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('move_element') . '&table=' . $table . '&uid=' . $row['uid']) . ');'; $linkTitleLL = $this->getLanguageService()->getLL('move_' . ($table === 'tt_content' ? 'record' : 'page'), true); $icon = $table == 'pages' ? $this->iconFactory->getIcon('actions-page-move', Icon::SIZE_SMALL) : $this->iconFactory->getIcon('actions-document-move', Icon::SIZE_SMALL); $moveAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $linkTitleLL . '">' . $icon->render() . '</a>'; $this->addActionToCellGroup($cells, $moveAction, 'move'); } // If the table is NOT a read-only table, then show these links: if ($this->isEditable($table)) { // "Revert" link (history/undo) $moduleUrl = BackendUtility::getModuleUrl('record_history', array('element' => $table . ':' . $row['uid'])); $onClick = 'return jumpExt(' . GeneralUtility::quoteJSvalue($moduleUrl) . ',\'#latest\');'; $historyAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $this->getLanguageService()->getLL('history', true) . '">' . $this->iconFactory->getIcon('actions-document-history-open', Icon::SIZE_SMALL)->render() . '</a>'; $this->addActionToCellGroup($cells, $historyAction, 'history'); // Versioning: if (ExtensionManagementUtility::isLoaded('version') && !ExtensionManagementUtility::isLoaded('workspaces')) { $vers = BackendUtility::selectVersionsOfRecord($table, $row['uid'], 'uid', $this->getBackendUserAuthentication()->workspace, false, $row); // If table can be versionized. if (is_array($vers)) { $href = BackendUtility::getModuleUrl('web_txversionM1', array('table' => $table, 'uid' => $row['uid'])); $versionAction = '<a class="btn btn-default" href="' . htmlspecialchars($href) . '" title="' . $this->getLanguageService()->getLL('displayVersions', true) . '">' . $this->iconFactory->getIcon('actions-version-page-open', Icon::SIZE_SMALL)->render() . '</a>'; $this->addActionToCellGroup($cells, $versionAction, 'version'); } } // "Edit Perms" link: if ($table === 'pages' && $this->getBackendUserAuthentication()->check('modules', 'system_BeuserTxPermission') && ExtensionManagementUtility::isLoaded('beuser')) { $href = BackendUtility::getModuleUrl('system_BeuserTxPermission') . '&id=' . $row['uid'] . '&return_id=' . $row['uid'] . '&edit=1'; $permsAction = '<a class="btn btn-default" href="' . htmlspecialchars($href) . '" title="' . $this->getLanguageService()->getLL('permissions', true) . '">' . $this->iconFactory->getIcon('status-status-locked', Icon::SIZE_SMALL)->render() . '</a>'; $this->addActionToCellGroup($cells, $permsAction, 'perms'); } // "New record after" link (ONLY if the records in the table are sorted by a "sortby"-row // or if default values can depend on previous record): if (($GLOBALS['TCA'][$table]['ctrl']['sortby'] || $GLOBALS['TCA'][$table]['ctrl']['useColumnsForDefaultValues']) && $permsEdit) { if ($table !== 'pages' && $this->calcPerms & Permission::CONTENT_EDIT || $table === 'pages' && $this->calcPerms & Permission::PAGE_NEW) { if ($this->showNewRecLink($table)) { $params = '&edit[' . $table . '][' . -($row['_MOVE_PLH'] ? $row['_MOVE_PLH_uid'] : $row['uid']) . ']=new'; $icon = $table == 'pages' ? $this->iconFactory->getIcon('actions-page-new', Icon::SIZE_SMALL) : $this->iconFactory->getIcon('actions-add', Icon::SIZE_SMALL); $newAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, '', -1)) . '" title="' . $this->getLanguageService()->getLL('new' . ($table == 'pages ' ? 'Page' : 'Record'), true) . '">' . $icon->render() . '</a>'; $this->addActionToCellGroup($cells, $newAction, 'new'); } } } // "Up/Down" links if ($permsEdit && $GLOBALS['TCA'][$table]['ctrl']['sortby'] && !$this->sortField && !$this->searchLevels) { if (isset($this->currentTable['prev'][$row['uid']])) { // Up $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prev'][$row['uid']]; $moveUpAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars('return jumpToUrl(' . BackendUtility::getLinkToDataHandlerAction($params, -1) . ');') . '" title="' . $this->getLanguageService()->getLL('moveUp', true) . '">' . $this->iconFactory->getIcon('actions-move-up', Icon::SIZE_SMALL)->render() . '</a>'; } else { $moveUpAction = $this->spaceIcon; } $this->addActionToCellGroup($cells, $moveUpAction, 'moveUp'); if ($this->currentTable['next'][$row['uid']]) { // Down $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['next'][$row['uid']]; $moveDownAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars('return jumpToUrl(' . BackendUtility::getLinkToDataHandlerAction($params, -1) . ');') . '" title="' . $this->getLanguageService()->getLL('moveDown', true) . '">' . $this->iconFactory->getIcon('actions-move-down', Icon::SIZE_SMALL)->render() . '</a>'; } else { $moveDownAction = $this->spaceIcon; } $this->addActionToCellGroup($cells, $moveDownAction, 'moveDown'); } // "Hide/Unhide" links: $hiddenField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']; if ($permsEdit && $hiddenField && $GLOBALS['TCA'][$table]['columns'][$hiddenField] && (!$GLOBALS['TCA'][$table]['columns'][$hiddenField]['exclude'] || $this->getBackendUserAuthentication()->check('non_exclude_fields', $table . ':' . $hiddenField))) { if ($this->isRecordCurrentBackendUser($table, $row)) { $hideAction = $this->spaceIcon; } else { $hideTitle = $this->getLanguageService()->getLL('hide' . ($table == 'pages' ? 'Page' : ''), true); $unhideTitle = $this->getLanguageService()->getLL('unHide' . ($table == 'pages' ? 'Page' : ''), true); if ($row[$hiddenField]) { $params = 'data[' . $table . '][' . $rowUid . '][' . $hiddenField . ']=0'; $hideAction = '<a class="btn btn-default t3js-record-hide" data-state="hidden" href="#"' . ' data-params="' . htmlspecialchars($params) . '"' . ' title="' . $unhideTitle . '"' . ' data-toggle-title="' . $hideTitle . '">' . $this->iconFactory->getIcon('actions-edit-unhide', Icon::SIZE_SMALL)->render() . '</a>'; } else { $params = 'data[' . $table . '][' . $rowUid . '][' . $hiddenField . ']=1'; $hideAction = '<a class="btn btn-default t3js-record-hide" data-state="visible" href="#"' . ' data-params="' . htmlspecialchars($params) . '"' . ' title="' . $hideTitle . '"' . ' data-toggle-title="' . $unhideTitle . '">' . $this->iconFactory->getIcon('actions-edit-hide', Icon::SIZE_SMALL)->render() . '</a>'; } } $this->addActionToCellGroup($cells, $hideAction, 'hide'); } // "Delete" link: if ($permsEdit && ($table === 'pages' && $localCalcPerms & Permission::PAGE_DELETE || $table !== 'pages' && $this->calcPerms & Permission::CONTENT_EDIT)) { // Check if the record version is in "deleted" state, because that will switch the action to "restore" if ($this->getBackendUserAuthentication()->workspace > 0 && isset($row['t3ver_state']) && (int) $row['t3ver_state'] === 2) { $actionName = 'restore'; $refCountMsg = ''; } else { $actionName = 'delete'; $refCountMsg = BackendUtility::referenceCount($table, $row['uid'], ' ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.referencesToRecord'), $this->getReferenceCount($table, $row['uid'])) . BackendUtility::translationCount($table, $row['uid'], ' ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.translationsOfRecord')); } if ($this->isRecordCurrentBackendUser($table, $row)) { $deleteAction = $this->spaceIcon; } else { $titleOrig = BackendUtility::getRecordTitle($table, $row, false, true); $title = GeneralUtility::slashJS(GeneralUtility::fixed_lgd_cs($titleOrig, $this->fixedL), true); $warningText = $this->getLanguageService()->getLL($actionName . 'Warning') . ' "' . $title . '" ' . '[' . $table . ':' . $row['uid'] . ']' . $refCountMsg; $params = 'cmd[' . $table . '][' . $row['uid'] . '][delete]=1'; $icon = $this->iconFactory->getIcon('actions-edit-' . $actionName, Icon::SIZE_SMALL)->render(); $linkTitle = $this->getLanguageService()->getLL($actionName, true); $deleteAction = '<a class="btn btn-default t3js-record-delete" href="#" ' . ' data-l10parent="' . htmlspecialchars($row['l10n_parent']) . '"' . ' data-params="' . htmlspecialchars($params) . '" data-title="' . htmlspecialchars($titleOrig) . '"' . ' data-message="' . htmlspecialchars($warningText) . '" title="' . $linkTitle . '"' . '>' . $icon . '</a>'; } } else { $deleteAction = $this->spaceIcon; } $this->addActionToCellGroup($cells, $deleteAction, 'delete'); // "Levels" links: Moving pages into new levels... if ($permsEdit && $table == 'pages' && !$this->searchLevels) { // Up (Paste as the page right after the current parent page) if ($this->calcPerms & Permission::PAGE_NEW) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . -$this->id; $moveLeftAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars('return jumpToUrl(' . BackendUtility::getLinkToDataHandlerAction($params, -1) . ');') . '" title="' . $this->getLanguageService()->getLL('prevLevel', true) . '">' . $this->iconFactory->getIcon('actions-move-left', Icon::SIZE_SMALL)->render() . '</a>'; $this->addActionToCellGroup($cells, $moveLeftAction, 'moveLeft'); } // Down (Paste as subpage to the page right above) if ($this->currentTable['prevUid'][$row['uid']]) { $localCalcPerms = $this->getBackendUserAuthentication()->calcPerms(BackendUtility::getRecord('pages', $this->currentTable['prevUid'][$row['uid']])); if ($localCalcPerms & Permission::PAGE_NEW) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prevUid'][$row['uid']]; $moveRightAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars('return jumpToUrl(' . BackendUtility::getLinkToDataHandlerAction($params, -1) . ');') . '" title="' . $this->getLanguageService()->getLL('nextLevel', true) . '">' . $this->iconFactory->getIcon('actions-move-right', Icon::SIZE_SMALL)->render() . '</a>'; } else { $moveRightAction = $this->spaceIcon; } } else { $moveRightAction = $this->spaceIcon; } $this->addActionToCellGroup($cells, $moveRightAction, 'moveRight'); } } /** * @hook recStatInfoHooks: Allows to insert HTML before record icons on various places */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) { $stat = ''; $_params = array($table, $row['uid']); foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) { $stat .= GeneralUtility::callUserFunction($_funcRef, $_params, $this); } $this->addActionToCellGroup($cells, $stat, 'stat'); } /** * @hook makeControl: Allows to change control icons of records in list-module * @usage This hook method gets passed the current $cells array as third parameter. * This array contains values for the icons/actions generated for each record in Web>List. * Each array entry is accessible by an index-key. * The order of the icons is depending on the order of those array entries. */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) { // for compatibility reason, we move all icons to the rootlevel // before calling the hooks foreach ($cells as $section => $actions) { foreach ($actions as $actionKey => $action) { $cells[$actionKey] = $action; } } foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) { $hookObject = GeneralUtility::getUserObj($classData); if (!$hookObject instanceof RecordListHookInterface) { throw new \UnexpectedValueException('$hookObject must implement interface ' . RecordListHookInterface::class, 1195567840); } $cells = $hookObject->makeControl($table, $row, $cells, $this); } // now sort icons again into primary and secondary sections // after all hooks are processed $hookCells = $cells; foreach ($hookCells as $key => $value) { if ($key === 'primary' || $key === 'secondary') { continue; } $this->addActionToCellGroup($cells, $value, $key); } } $output = '<!-- CONTROL PANEL: ' . $table . ':' . $row['uid'] . ' -->'; foreach ($cells as $classification => $actions) { $visibilityClass = $classification !== 'primary' && !$module->MOD_SETTINGS['bigControlPanel'] ? 'collapsed' : 'expanded'; if ($visibilityClass === 'collapsed') { $cellOutput = ''; foreach ($actions as $action) { $cellOutput .= $action; } $output .= ' <div class="btn-group">' . '<span id="actions_' . $table . '_' . $row['uid'] . '" class="btn-group collapse collapse-horizontal width">' . $cellOutput . '</span>' . '<a href="#actions_' . $table . '_' . $row['uid'] . '" class="btn btn-default collapsed" data-toggle="collapse" aria-expanded="false"><span class="t3-icon fa fa-ellipsis-h"></span></a>' . '</div>'; } else { $output .= ' <div class="btn-group" role="group">' . implode('', $actions) . '</div>'; } } return $output; }
/** * Adding CM element for Delete * * @param string $table Table name * @param int $uid UID for the current record. * @param array $elInfo Label for including in the confirmation message, EXT:lang/locallang_core.xlf:mess.delete * @return array Item array, element in $menuItems * @internal */ public function DB_delete($table, $uid, $elInfo) { $loc = 'top.content.list_frame'; if ($this->backendUser->jsConfirmation(JsConfirmation::DELETE)) { $conf = 'confirm(' . GeneralUtility::quoteJSvalue(sprintf($this->languageService->sL('LLL:EXT:lang/locallang_core.xlf:mess.delete'), $elInfo[0]) . BackendUtility::referenceCount($table, $uid, ' ' . $this->languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.referencesToRecord')) . BackendUtility::translationCount($table, $uid, ' ' . $this->languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.translationsOfRecord'))) . ')'; } else { $conf = '1==1'; } $editOnClick = 'if(' . $loc . ' && ' . $conf . ' ){' . $loc . '.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('tce_db') . '&redirect=') . '+top.rawurlencode(' . $this->frameLocation($loc . '.document') . '.pathname+' . $this->frameLocation($loc . '.document') . '.search)+' . GeneralUtility::quoteJSvalue('&cmd[' . $table . '][' . $uid . '][delete]=1&prErr=1&vC=' . $this->backendUser->veriCode()) . ';};'; if ($table === 'pages') { $editOnClick .= 'top.nav.refresh.defer(500, top.nav);'; } return $this->linkItem($this->label('delete'), $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render(), $editOnClick . 'return false;'); }
/** * Draw the header for a single tt_content element * * @param array $row Record array * @param integer $space Amount of pixel space above the header. UNUSED * @param boolean $disableMoveAndNewButtons If set the buttons for creating new elements and moving up and down are not shown. * @param boolean $langMode If set, we are in language mode and flags will be shown for languages * @param boolean $dragDropEnabled If set the move button must be hidden * @return string HTML table with the record header. * @todo Define visibility */ public function tt_content_drawHeader($row, $space = 0, $disableMoveAndNewButtons = FALSE, $langMode = FALSE, $dragDropEnabled = FALSE) { $out = ''; // If show info is set...; if ($this->tt_contentConfig['showInfo'] && $this->getBackendUser()->recordEditAccessInternals('tt_content', $row)) { // Render control panel for the element: if ($this->tt_contentConfig['showCommands'] && $this->doEdit) { // Edit content element: $params = '&edit[tt_content][' . $this->tt_contentData['nextThree'][$row['uid']] . ']=edit'; $out .= '<a href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, $this->backPath, GeneralUtility::getIndpEnv('REQUEST_URI') . '#element-tt_content-' . $row['uid'])) . '" title="' . htmlspecialchars($this->nextThree > 1 ? sprintf($this->getLanguageService()->getLL('nextThree'), $this->nextThree) : $this->getLanguageService()->getLL('edit')) . '">' . IconUtility::getSpriteIcon('actions-document-open') . '</a>'; // Hide element: $hiddenField = $GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled']; if ($hiddenField && $GLOBALS['TCA']['tt_content']['columns'][$hiddenField] && (!$GLOBALS['TCA']['tt_content']['columns'][$hiddenField]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', 'tt_content:' . $hiddenField))) { if ($row[$hiddenField]) { $value = 0; $label = 'unHide'; } else { $value = 1; $label = 'hide'; } $params = '&data[tt_content][' . ($row['_ORIG_uid'] ? $row['_ORIG_uid'] : $row['uid']) . '][' . $hiddenField . ']=' . $value; $out .= '<a href="' . htmlspecialchars($this->getPageLayoutController()->doc->issueCommand($params)) . '" title="' . $this->getLanguageService()->getLL($label, TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-' . strtolower($label)) . '</a>'; } // Delete $params = '&cmd[tt_content][' . $row['uid'] . '][delete]=1'; $confirm = GeneralUtility::quoteJSvalue($this->getLanguageService()->getLL('deleteWarning') . BackendUtility::translationCount('tt_content', $row['uid'], ' ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.translationsOfRecord'))); $out .= '<a href="' . htmlspecialchars($this->getPageLayoutController()->doc->issueCommand($params)) . '" onclick="' . htmlspecialchars('return confirm(' . $confirm . ');') . '" title="' . $this->getLanguageService()->getLL('deleteItem', TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>'; if (!$disableMoveAndNewButtons) { $moveButtonContent = ''; $displayMoveButtons = FALSE; // Move element up: if ($this->tt_contentData['prev'][$row['uid']]) { $params = '&cmd[tt_content][' . $row['uid'] . '][move]=' . $this->tt_contentData['prev'][$row['uid']]; $moveButtonContent .= '<a href="' . htmlspecialchars($this->getPageLayoutController()->doc->issueCommand($params)) . '" title="' . $this->getLanguageService()->getLL('moveUp', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-up') . '</a>'; if (!$dragDropEnabled) { $displayMoveButtons = TRUE; } } else { $moveButtonContent .= IconUtility::getSpriteIcon('empty-empty'); } // Move element down: if ($this->tt_contentData['next'][$row['uid']]) { $params = '&cmd[tt_content][' . $row['uid'] . '][move]= ' . $this->tt_contentData['next'][$row['uid']]; $moveButtonContent .= '<a href="' . htmlspecialchars($this->getPageLayoutController()->doc->issueCommand($params)) . '" title="' . $this->getLanguageService()->getLL('moveDown', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-down') . '</a>'; if (!$dragDropEnabled) { $displayMoveButtons = TRUE; } } else { $moveButtonContent .= IconUtility::getSpriteIcon('empty-empty'); } if ($displayMoveButtons) { $out .= '<span class="t3-page-ce-icons-move">' . $moveButtonContent . '</span>'; } } } } $additionalIcons = array(); $additionalIcons[] = $this->getIcon('tt_content', $row) . ' '; $additionalIcons[] = $langMode ? $this->languageFlag($row['sys_language_uid'], FALSE) : ''; // Get record locking status: if ($lockInfo = BackendUtility::isRecordLocked('tt_content', $row['uid'])) { $additionalIcons[] = '<a href="#" onclick="alert(' . GeneralUtility::quoteJSvalue($lockInfo['msg']) . ');return false;" title="' . htmlspecialchars($lockInfo['msg']) . '">' . IconUtility::getSpriteIcon('status-warning-in-use') . '</a>'; } // Call stats information hook if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) { $_params = array('tt_content', $row['uid'], &$row); foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) { $additionalIcons[] = GeneralUtility::callUserFunction($_funcRef, $_params, $this); } } // Wrap the whole header // NOTE: end-tag for <div class="t3-page-ce-body"> is in getTable_tt_content() return '<h4 class="t3-page-ce-header"> <div class="t3-row-header"> <span class="ce-icons-left">' . implode('', $additionalIcons) . '</span> <span class="ce-icons"> ' . $out . ' </span></div> </h4> <div class="t3-page-ce-body">'; }
/** * Creates the control panel for a single record in the listing. * * @param string $table The table * @param array $row The record for which to make the control panel. * @param string $level * @return string HTML table with the control panel (unless disabled) */ public function makeControl($table, $row, $level) { if ($this->dontShowClipControlPanels) { return ''; } $rowUid = $row['uid']; if (ExtensionManagementUtility::isLoaded('version') && isset($row['_ORIG_uid'])) { $rowUid = $row['_ORIG_uid']; } $cells = array(); // If the listed table is 'pages' we have to request the permission settings for each page: if ($table == 'pages') { $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(BackendUtility::getRecord('pages', $row['uid'])); } // This expresses the edit permissions for this particular element: $permsEdit = $table == 'pages' && $localCalcPerms & 2 || $table != 'pages' && $this->calcPerms & 16; // "Show" link (only pages and tt_content elements) if ($table == 'pages' || $table == 'tt_content') { $cells['view'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($table === 'tt_content' ? $this->id : $row['uid'], $this->backPath, '', $table === 'tt_content' ? '#' . $row['uid'] : '')) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-view') . '</a>'; } elseif (!$this->table) { $cells['view'] = $this->spaceIcon; } // "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id) if ($permsEdit) { $params = '&edit[' . $table . '][' . $row['uid'] . ']=edit'; $cells['edit'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, $this->backPath, -1)) . '" title="' . $GLOBALS['LANG']->getLL('edit', TRUE) . '">' . ($GLOBALS['TCA'][$table]['ctrl']['readOnly'] ? IconUtility::getSpriteIcon('actions-document-open-read-only') : IconUtility::getSpriteIcon('actions-document-open')) . '</a>'; } elseif (!$this->table) { $cells['edit'] = $this->spaceIcon; } // "Move" wizard link for pages/tt_content elements: if (($table == 'tt_content' && $permsEdit || $table == 'pages') && $level == 0) { $cells['move'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'move_el.php?table=' . $table . '&uid=' . $row['uid'] . '\');') . '" title="' . $GLOBALS['LANG']->getLL('move_' . ($table == 'tt_content' ? 'record' : 'page'), TRUE) . '">' . ($table == 'tt_content' ? IconUtility::getSpriteIcon('actions-document-move') : IconUtility::getSpriteIcon('actions-page-move')) . '</a>'; } elseif (!$this->table || $level > 0) { $cells['move'] = $this->spaceIcon; } // If the extended control panel is enabled OR if we are seeing a single table: if ($GLOBALS['SOBE']->MOD_SETTINGS['bigControlPanel'] || $this->table) { // "Info": (All records) $cells['viewBig'] = '<a href="#" onclick="' . htmlspecialchars('top.launchView(\'' . $table . '\', \'' . $row['uid'] . '\'); return false;') . '" title="' . $GLOBALS['LANG']->getLL('showInfo', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-info') . '</a>'; // If the table is NOT a read-only table, then show these links: if (!$GLOBALS['TCA'][$table]['ctrl']['readOnly']) { // "Revert" link (history/undo) $cells['history'] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(' . GeneralUtility::quoteJSvalue($this->backPath . BackendUtility::getModuleUrl('record_history', array('element' => $table . ':' . $row['uid']))) . ',\'#latest\');') . '" title="' . $GLOBALS['LANG']->getLL('history', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>'; // Versioning: if (ExtensionManagementUtility::isLoaded('version') && !ExtensionManagementUtility::isLoaded('workspaces')) { $vers = BackendUtility::selectVersionsOfRecord($table, $row['uid'], 'uid', $GLOBALS['BE_USER']->workspace, FALSE, $row); // If table can be versionized. if (is_array($vers)) { $versionIcon = 'no-version'; if (count($vers) > 1) { $versionIcon = count($vers) - 1; } $cells['version'] = '<a href="' . htmlspecialchars($this->backPath . BackendUtility::getModuleUrl('web_txversionM1', array('table' => $table, 'uid' => $row['uid']))) . '" title="' . $GLOBALS['LANG']->getLL('displayVersions', TRUE) . '">' . IconUtility::getSpriteIcon('status-version-' . $versionIcon) . '</a>'; } elseif (!$this->table) { $cells['version'] = $this->spaceIcon; } } // "Edit Perms" link: if ($table == 'pages' && $GLOBALS['BE_USER']->check('modules', 'web_perm') && ExtensionManagementUtility::isLoaded('perm')) { $cells['perms'] = '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('web_perm') . '&id=' . $row['uid'] . '&return_id=' . $row['uid'] . '&edit=1') . '" title="' . $GLOBALS['LANG']->getLL('permissions', TRUE) . '">' . IconUtility::getSpriteIcon('status-status-locked') . '</a>'; } elseif ((!$this->table || $level > 0) && $GLOBALS['BE_USER']->check('modules', 'web_perm')) { $cells['perms'] = $this->spaceIcon; } // "New record after" link (ONLY if the records in the table are sorted by a "sortby"-row or if default values can depend on previous record): if ($GLOBALS['TCA'][$table]['ctrl']['sortby'] || $GLOBALS['TCA'][$table]['ctrl']['useColumnsForDefaultValues']) { if ($table != 'pages' && $this->calcPerms & 16 || $table == 'pages' && $this->calcPerms & 8) { if ($this->showNewRecLink($table)) { $params = '&edit[' . $table . '][' . -($row['_MOVE_PLH'] ? $row['_MOVE_PLH_uid'] : $row['uid']) . ']=new'; $cells['new'] = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, $this->backPath, -1)) . '" title="' . $GLOBALS['LANG']->getLL('new' . ($table == 'pages ' ? 'Page' : 'Record'), TRUE) . '">' . ($table == 'pages' ? IconUtility::getSpriteIcon('actions-page-new') : IconUtility::getSpriteIcon('actions-document-new')) . '</a>'; } } } elseif (!$this->table) { $cells['new'] = $this->spaceIcon; } // "Up/Down" links if ($permsEdit && $GLOBALS['TCA'][$table]['ctrl']['sortby'] && !$this->sortField && !$this->searchLevels) { if (isset($this->currentTable['prev'][$row['uid']]) && $this->showMoveUp === TRUE) { // Up if ($this->lastMoveDownParams) { $params = $this->lastMoveDownParams; } else { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prev'][$row['uid']]; } $cells['moveUp'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('moveUp', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-up') . '</a>'; } else { $cells['moveUp'] = $this->spaceIcon; } if ($this->currentTable['next'][$row['uid']] && $this->showMoveDown === TRUE) { // Down $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['next'][$row['uid']]; $this->lastMoveDownParams = $params; $cells['moveDown'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('moveDown', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-down') . '</a>'; } else { $cells['moveDown'] = $this->spaceIcon; } } elseif (!$this->table) { $cells['moveUp'] = $this->spaceIcon; $cells['moveDown'] = $this->spaceIcon; } // "Hide/Unhide" links: $hiddenField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']; if ($permsEdit && $hiddenField && $GLOBALS['TCA'][$table]['columns'][$hiddenField] && (!$GLOBALS['TCA'][$table]['columns'][$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $table . ':' . $hiddenField))) { if ($row[$hiddenField]) { $params = '&data[' . $table . '][' . $rowUid . '][' . $hiddenField . ']=0'; $cells['hide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('unHide' . ($table == 'pages' ? 'Page' : ''), TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-unhide') . '</a>'; } else { $params = '&data[' . $table . '][' . $rowUid . '][' . $hiddenField . ']=1'; $cells['hide'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('hide' . ($table == 'pages' ? 'Page' : ''), TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-hide') . '</a>'; } } elseif (!$this->table) { $cells['hide'] = $this->spaceIcon; } // "Delete" link: if ($table == 'pages' && $localCalcPerms & 4 || $table != 'pages' && $this->calcPerms & 16) { // Check if the record version is in "deleted" state, because that will switch the action to "restore" if ($GLOBALS['BE_USER']->workspace > 0 && isset($row['t3ver_state']) && (int) $row['t3ver_state'] === 2) { $actionName = 'restore'; $refCountMsg = ''; } else { $actionName = 'delete'; $refCountMsg = BackendUtility::referenceCount($table, $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.referencesToRecord'), $this->getReferenceCount($table, $row['uid'])) . BackendUtility::translationCount($table, $row['uid'], ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.translationsOfRecord')); } $titleOrig = BackendUtility::getRecordTitle($table, $row, FALSE, TRUE); $title = GeneralUtility::slashJS(GeneralUtility::fixed_lgd_cs($titleOrig, $this->fixedL), 1); $warningText = GeneralUtility::quoteJSvalue($GLOBALS['LANG']->getLL($actionName . 'Warning') . ' "' . $title . '" ' . $refCountMsg); $params = '&cmd[' . $table . '][' . $row['uid'] . '][delete]=1'; $onClick = htmlspecialchars('if (confirm(' . $warningText . ')) {jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');} return false;'); $icon = IconUtility::getSpriteIcon('actions-edit-' . $actionName); $linkTitle = $GLOBALS['LANG']->getLL($actionName, TRUE); $cells['delete'] = '<a href="#" onclick="' . $onClick . '" title="' . $linkTitle . '">' . $icon . '</a>'; } elseif (!$this->table) { $cells['delete'] = $this->spaceIcon; } // "Levels" links: Moving pages into new levels... if ($permsEdit && $table == 'pages' && !$this->searchLevels) { // Up (Paste as the page right after the current parent page) if ($this->calcPerms & 8) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . -$this->id; $cells['moveLeft'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('prevLevel', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-left') . '</a>'; } // Down (Paste as subpage to the page right above) if ($this->currentTable['prevUid'][$row['uid']]) { $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(BackendUtility::getRecord('pages', $this->currentTable['prevUid'][$row['uid']])); if ($localCalcPerms & 8) { $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prevUid'][$row['uid']]; $cells['moveRight'] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '" title="' . $GLOBALS['LANG']->getLL('nextLevel', TRUE) . '">' . IconUtility::getSpriteIcon('actions-move-right') . '</a>'; } else { $cells['moveRight'] = $this->spaceIcon; } } else { $cells['moveRight'] = $this->spaceIcon; } } elseif (!$this->table) { $cells['moveLeft'] = $this->spaceIcon; $cells['moveRight'] = $this->spaceIcon; } } } /** * @hook recStatInfoHooks: Allows to insert HTML before record icons on various places * @date 2007-09-22 * @request Kasper Skårhøj <*****@*****.**> */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) { $stat = ''; $_params = array($table, $row['uid']); foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) { $stat .= GeneralUtility::callUserFunction($_funcRef, $_params, $this); } $cells['stat'] = $stat; } /** * @hook makeControl: Allows to change control icons of records in list-module * @date 2007-11-20 * @request Bernhard Kraft <*****@*****.**> * @usage This hook method gets passed the current $cells array as third parameter. This array contains values for the icons/actions generated for each record in Web>List. Each array entry is accessible by an index-key. The order of the icons is dependend on the order of those array entries. */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['actions'] as $classData) { $hookObject = GeneralUtility::getUserObj($classData); if (!$hookObject instanceof \TYPO3\CMS\Recordlist\RecordList\RecordListHookInterface) { throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Recordlist\\RecordList\\RecordListHookInterface', 1195567840); } $cells = $hookObject->makeControl($table, $row, $cells, $this); } } // Compile items into a DIV-element: return ' <!-- CONTROL PANEL: ' . $table . ':' . $row['uid'] . ' --> <div class="typo3-DBctrl">' . implode('', $cells) . '</div>'; }
/** * Adding CM element for Delete * * @param string $table Table name * @param int $uid UID for the current record. * @param array $elInfo Label for including in the confirmation message, EXT:lang/Resources/Private/Language/locallang_core.xlf:mess.delete * @return array Item array, element in $menuItems * @internal */ public function DB_delete($table, $uid, $elInfo) { $loc = 'top.list_frame'; $jsCode = $loc . '.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('tce_db') . '&redirect=') . '+top.rawurlencode(' . $this->frameLocation($loc . '.document') . '.pathname+' . $this->frameLocation($loc . '.document') . '.search)+' . GeneralUtility::quoteJSvalue('&cmd[' . $table . '][' . $uid . '][delete]=1&prErr=1&vC=' . $this->backendUser->veriCode()); if ($table === 'pages') { $jsCode .= 'top.nav.refresh.defer(500, top.nav);'; } if ($this->backendUser->jsConfirmation(JsConfirmation::DELETE)) { $title = $this->languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:delete'); $confirmMessage = sprintf($this->languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:mess.delete'), $elInfo[0]); $confirmMessage .= BackendUtility::referenceCount($table, $uid, ' ' . $this->languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.referencesToRecord')); $confirmMessage .= BackendUtility::translationCount($table, $uid, ' ' . $this->languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.translationsOfRecord')); $jsCode = 'top.TYPO3.Modal.confirm(' . GeneralUtility::quoteJSvalue($title) . ', ' . GeneralUtility::quoteJSvalue($confirmMessage) . ')' . '.on(\'button.clicked\', function(e) { if (e.target.name === \'ok\') {' . $jsCode . '} top.TYPO3.Modal.dismiss(); });'; } $editOnClick = 'if(' . $loc . ') { ' . $jsCode . ' }'; return $this->linkItem($this->label('delete'), $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render(), $editOnClick . 'return false;'); }