From bfa7649317e64305d92f544e41bf995ba9affd68 Mon Sep 17 00:00:00 2001 From: Georg Ringer Date: Wed, 3 Jul 2013 16:48:24 +0200 Subject: [PATCH] [TASK] Improve feedit The frontend editing + admin panel needs some polishing. Following changes are included: General ======= - Reformat code - Use Sprite API which means using the correct icons Admin Panel ============== - Add missing translations - Show "Simulate usergroup" only if usergroups are available - Remove "Total page count" in Info Tab as information is wrong (counting images + document is not the total page size) Frontend Editing ================= - Remove "edit_editNoPopup", "forceNoPopup", "editFormsOnPage" for direct inline editing - Remove setting "previewBorder" which is not needed and looks just ugly Releases: 6.2 Resolves: #49640 Change-Id: I35f88bc4e8c138fc21b74c0448b2f3892ab61918 Reviewed-on: https://review.typo3.org/21859 Reviewed-by: Markus Klein Tested-by: Markus Klein Reviewed-by: Wouter Wolters Tested-by: Wouter Wolters --- Classes/FrontendEditPanel.php | 319 +++++++++++----------------------- 1 file changed, 104 insertions(+), 215 deletions(-) diff --git a/Classes/FrontendEditPanel.php b/Classes/FrontendEditPanel.php index cb66e3c..e1fe338 100644 --- a/Classes/FrontendEditPanel.php +++ b/Classes/FrontendEditPanel.php @@ -3,50 +3,41 @@ namespace TYPO3\CMS\Feedit; /*************************************************************** * Copyright notice - * * (c) 2008-2013 Jeff Segars * (c) 2008-2013 David Slayback * All rights reserved - * * This script is part of the TYPO3 project. The TYPO3 project is * free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The GNU General Public License can be found at * http://www.gnu.org/copyleft/gpl.html. * A copy is found in the textfile GPL.txt and important notices to the license * from the author is found in LICENSE.txt distributed with these scripts. - * - * * This script is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use TYPO3\CMS\Backend\Sprite\SpriteManager; +use TYPO3\CMS\Backend\Utility\IconUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * View class for the edit panels in frontend editing. - * - * @author Jeff Segars - * @author David Slayback */ class FrontendEditPanel { /** - * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer Local instance of ContentObjectRenderer + * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */ protected $cObj; /** - * Constructor for the edit panel. Creates a new cObject instance to be used in wrapping, etc. - * - * @return void + * Constructor for the edit panel */ public function __construct() { $this->cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer'); @@ -69,103 +60,106 @@ class FrontendEditPanel { * @return string The input content string with the editPanel appended. This function returns only an edit panel appended to the content string if a backend user is logged in (and has the correct permissions). Otherwise the content string is directly returned. */ public function editPanel($content, array $conf, $currentRecord = '', array $dataArr = array(), $table = '', $allow = '', $newUID = 0, array $hiddenFields = array()) { + $hiddenFieldString = $command = ''; + // Special content is about to be shown, so the cache must be disabled. $GLOBALS['TSFE']->set_no_cache('Frontend edit panel is shown', TRUE); + $formName = 'TSFE_EDIT_FORM_' . substr($GLOBALS['TSFE']->uniqueHash(), 0, 4); - $formTag = '
'; + $formTag = ''; $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby']; $labelField = $GLOBALS['TCA'][$table]['ctrl']['label']; $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']; - $blackLine = $conf['line'] ? '

' : ''; - $theCmd = ''; + $TSFE_EDIT = $GLOBALS['BE_USER']->frontendEdit->TSFE_EDIT; if (is_array($TSFE_EDIT) && $TSFE_EDIT['record'] == $currentRecord && !$TSFE_EDIT['update_close']) { - $theCmd = $TSFE_EDIT['cmd']; + $command = $TSFE_EDIT['cmd']; } - switch ($theCmd) { - case 'edit': - case 'new': - $finalOut = $this->editContent($formTag, $formName, $theCmd, $newUID, $dataArr, $table, $currentRecord, $blackLine); - break; - default: - $panel = ''; - if (isset($allow['toolbar']) && $GLOBALS['BE_USER']->adminPanel instanceof \TYPO3\CMS\Frontend\View\AdminPanelView) { - $panel .= $GLOBALS['BE_USER']->adminPanel->ext_makeToolBar() . ''; - } - if (isset($allow['edit'])) { - $panel .= $this->editPanelLinkWrap('', $formName, 'edit', $dataArr['_LOCALIZED_UID'] ? $table . ':' . $dataArr['_LOCALIZED_UID'] : $currentRecord); - } - // Hiding in workspaces because implementation is incomplete - if (isset($allow['move']) && $sortField && $GLOBALS['BE_USER']->workspace === 0) { - $panel .= $this->editPanelLinkWrap('', $formName, 'up'); - $panel .= $this->editPanelLinkWrap('', $formName, 'down'); - } - // Hiding in workspaces because implementation is incomplete, Hiding for localizations because it is unknown what should be the function in that case - if (isset($allow['hide']) && $hideField && $GLOBALS['BE_USER']->workspace === 0 && !$dataArr['_LOCALIZED_UID']) { - if ($dataArr[$hideField]) { - $panel .= $this->editPanelLinkWrap('', $formName, 'unhide'); - } else { - $panel .= $this->editPanelLinkWrap('', $formName, 'hide', '', $GLOBALS['BE_USER']->extGetLL('p_hideConfirm')); - } - } - if (isset($allow['new'])) { - if ($table == 'pages') { - $panel .= $this->editPanelLinkWrap('', $formName, 'new', $currentRecord, ''); - } else { - $panel .= $this->editPanelLinkWrap('', $formName, 'new', $currentRecord, '', $newUID); - } - } - // Hiding in workspaces because implementation is incomplete, Hiding for localizations because it is unknown what should be the function in that case - if (isset($allow['delete']) && $GLOBALS['BE_USER']->workspace === 0 && !$dataArr['_LOCALIZED_UID']) { - $panel .= $this->editPanelLinkWrap('', $formName, 'delete', '', $GLOBALS['BE_USER']->extGetLL('p_deleteConfirm')); - } - // Final - $labelTxt = $this->cObj->stdWrap($conf['label'], $conf['label.']); - foreach ((array) $hiddenFields as $name => $value) { - $hiddenFieldString .= '' . LF; - } - $panel = ' + $panel = ''; + if (isset($allow['toolbar']) && $GLOBALS['BE_USER']->adminPanel instanceof \TYPO3\CMS\Frontend\View\AdminPanelView) { + $panel .= $GLOBALS['BE_USER']->adminPanel->ext_makeToolBar(); + } + if (isset($allow['edit'])) { + $icon = IconUtility::getSpriteIcon('actions-document-open', array('title' => $GLOBALS['BE_USER']->extGetLL('p_editRecord'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'edit', $dataArr['_LOCALIZED_UID'] ? $table . ':' . $dataArr['_LOCALIZED_UID'] : $currentRecord); + } + // Hiding in workspaces because implementation is incomplete + if (isset($allow['move']) && $sortField && $GLOBALS['BE_USER']->workspace === 0) { + $icon = IconUtility::getSpriteIcon('actions-move-up', array('title' => $GLOBALS['BE_USER']->extGetLL('p_moveUp'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'up'); + $icon = IconUtility::getSpriteIcon('actions-move-down', array('title' => $GLOBALS['BE_USER']->extGetLL('p_moveDown'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'down'); + } + // Hiding in workspaces because implementation is incomplete + // Hiding for localizations because it is unknown what should be the function in that case + if (isset($allow['hide']) && $hideField && $GLOBALS['BE_USER']->workspace === 0 && !$dataArr['_LOCALIZED_UID']) { + if ($dataArr[$hideField]) { + $icon = IconUtility::getSpriteIcon('actions-edit-unhide', array('title' => $GLOBALS['BE_USER']->extGetLL('p_unhide'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'unhide'); + } else { + $icon = IconUtility::getSpriteIcon('actions-edit-hide', array('title' => $GLOBALS['BE_USER']->extGetLL('p_hide'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'hide', '', $GLOBALS['BE_USER']->extGetLL('p_hideConfirm')); + } + } + if (isset($allow['new'])) { + if ($table === 'pages') { + $icon = IconUtility::getSpriteIcon('actions-page-new', array('title' => $GLOBALS['BE_USER']->extGetLL('p_newSubpage'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'new', $currentRecord, ''); + } else { + $icon = IconUtility::getSpriteIcon('actions-document-new', array('title' => $GLOBALS['BE_USER']->extGetLL('p_newRecordAfter'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'new', $currentRecord, '', $newUID); + } + } + // Hiding in workspaces because implementation is incomplete + // Hiding for localizations because it is unknown what should be the function in that case + if (isset($allow['delete']) && $GLOBALS['BE_USER']->workspace === 0 && !$dataArr['_LOCALIZED_UID']) { + $icon = IconUtility::getSpriteIcon('actions-edit-delete', array('title' => $GLOBALS['BE_USER']->extGetLL('p_delete'))); + $panel .= $this->editPanelLinkWrap($icon, $formName, 'delete', '', $GLOBALS['BE_USER']->extGetLL('p_deleteConfirm')); + } + // Final + $labelTxt = $this->cObj->stdWrap($conf['label'], $conf['label.']); + foreach ((array)$hiddenFields as $name => $value) { + $hiddenFieldString .= '' . LF; + } - + $panel = ' ' . $formTag . $hiddenFieldString . ' - - - ' . ($labelTxt ? '' : '') . ' - -
' . $panel . ' ' . sprintf($labelTxt, htmlspecialchars(GeneralUtility::fixed_lgd_cs($dataArr[$labelField], 50))) . ' 
+
' + . $panel . + ($labelTxt ? '
' . sprintf($labelTxt, htmlspecialchars(GeneralUtility::fixed_lgd_cs($dataArr[$labelField], 50))) . '
' : '') . ' +
'; - // Wrap the panel - if ($conf['innerWrap']) { - $panel = $this->cObj->wrap($panel, $conf['innerWrap']); - } - if ($conf['innerWrap.']) { - $panel = $this->cObj->stdWrap($panel, $conf['innerWrap.']); - } - // Add black line: - $panel .= $blackLine; - // Wrap the complete panel - if ($conf['outerWrap']) { - $panel = $this->cObj->wrap($panel, $conf['outerWrap']); - } - if ($conf['outerWrap.']) { - $panel = $this->cObj->stdWrap($panel, $conf['outerWrap.']); - } - if ($conf['printBeforeContent']) { - $finalOut = $panel . $content; - } else { - $finalOut = $content . $panel; - } - break; + + // Wrap the panel + if ($conf['innerWrap']) { + $panel = $this->cObj->wrap($panel, $conf['innerWrap']); } - if ($conf['previewBorder']) { - if (!is_array($conf['previewBorder.'])) { - $conf['previewBorder.'] = array(); - } - $finalOut = $this->editPanelPreviewBorder($table, $dataArr, $finalOut, $conf['previewBorder'], $conf['previewBorder.']); + if ($conf['innerWrap.']) { + $panel = $this->cObj->stdWrap($panel, $conf['innerWrap.']); } + + // Wrap the complete panel + if ($conf['outerWrap']) { + $panel = $this->cObj->wrap($panel, $conf['outerWrap']); + } + if ($conf['outerWrap.']) { + $panel = $this->cObj->stdWrap($panel, $conf['outerWrap.']); + } + if ($conf['printBeforeContent']) { + $finalOut = $panel . $content; + } else { + $finalOut = $content . $panel; + } + + $hidden = $this->isDisabled($table, $dataArr) ? ' typo3-feedit-element-hidden' : ''; + $outerWrapConfig = isset($conf['stdWrap.']) + ? $conf['stdWrap.'] + : array('wrap' => '
|
'); + $finalOut = $this->cObj->stdWrap($finalOut, $outerWrapConfig); + return $finalOut; } @@ -192,17 +186,17 @@ class FrontendEditPanel { $iconImg = $conf['iconImg'] ? $conf['iconImg'] : ''; $nV = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0; $adminURL = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir; - $icon = $this->editPanelLinkWrap_doWrap($iconImg, $adminURL . 'alt_doc.php?edit[' . $table . '][' . $editUid . ']=edit&columnsOnly=' . rawurlencode($fieldList) . '&noView=' . $nV . $addUrlParamStr, $currentRecord); + $icon = $this->editPanelLinkWrap_doWrap($iconImg, $adminURL . 'alt_doc.php?edit[' . $table . '][' . $editUid . ']=edit&columnsOnly=' . rawurlencode($fieldList) . '&noView=' . $nV . $addUrlParamStr); if ($conf['beforeLastTag'] < 0) { $content = $icon . $content; } elseif ($conf['beforeLastTag'] > 0) { $cBuf = rtrim($content); - $securCount = 30; - while ($securCount && substr($cBuf, -1) == '>' && substr($cBuf, -4) != '') { + $secureCount = 30; + while ($secureCount && substr($cBuf, -1) == '>' && substr($cBuf, -4) != '') { $cBuf = rtrim(preg_replace('/<[^<]*>$/', '', $cBuf)); - $securCount--; + $secureCount--; } - $content = strlen($cBuf) && $securCount ? substr($content, 0, strlen($cBuf)) . $icon . substr($content, strlen($cBuf)) : ($content = $icon . $content); + $content = strlen($cBuf) && $secureCount ? substr($content, 0, strlen($cBuf)) . $icon . substr($content, strlen($cBuf)) : ($content = $icon . $content); } else { $content .= $icon; } @@ -218,18 +212,16 @@ class FrontendEditPanel { * @param string $cmd The command of the link. There is a predefined list available: edit, new, up, down etc. * @param string $currentRecord The "table:uid" of the record being processed by the panel. * @param string $confirm Text string with confirmation message; If set a confirm box will be displayed before carrying out the action (if Yes is pressed) - * @param integer $nPid "New pid" - for new records + * @param int|string $nPid "New pid" - for new records * @return string A tag wrapped string. */ protected function editPanelLinkWrap($string, $formName, $cmd, $currentRecord = '', $confirm = '', $nPid = '') { - // Editing forms on page only supported in Live workspace (because of incomplete implementation) - $editFormsOnPage = $GLOBALS['BE_USER']->uc['TSFE_adminConfig']['edit_editFormsOnPage'] && $GLOBALS['BE_USER']->workspace === 0; $nV = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0; $adminURL = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir; - if ($cmd == 'edit' && !$editFormsOnPage) { + if ($cmd == 'edit') { $rParts = explode(':', $currentRecord); $out = $this->editPanelLinkWrap_doWrap($string, $adminURL . 'alt_doc.php?edit[' . $rParts[0] . '][' . $rParts[1] . ']=edit&noView=' . $nV, $currentRecord); - } elseif ($cmd == 'new' && !$editFormsOnPage) { + } elseif ($cmd == 'new') { $rParts = explode(':', $currentRecord); if ($rParts[0] == 'pages') { $out = $this->editPanelLinkWrap_doWrap($string, $adminURL . 'db_new.php?id=' . $rParts[1] . '&pagesOnly=1', $currentRecord); @@ -257,66 +249,23 @@ class FrontendEditPanel { * * @param string $string The string to wrap in a link, typ. and image used as button in the edit panel. * @param string $url The URL of the link. Should be absolute if supposed to work with path set. - * @param string $currentRecord The "table:uid" of the record being processed by the panel. * @return string A tag wrapped string. - * @see editPanelLinkWrap() + * @see editPanelLinkWrap() */ - protected function editPanelLinkWrap_doWrap($string, $url, $currentRecord) { - if ($GLOBALS['BE_USER']->uc['TSFE_adminConfig']['edit_editNoPopup'] || $GLOBALS['BE_USER']->extAdminConfig['module.']['edit.']['forceNoPopup']) { - $retUrl = GeneralUtility::getIndpEnv('REQUEST_URI'); - $rParts = explode(':', $currentRecord); - // This parentRecordNumber is used to make sure that only elements 3- of ordinary content elements makes a 'anchor' jump down the page. - if ($rParts[0] == 'tt_content' && $this->parentRecordNumber > 2) { - $retUrl .= '#' . $rParts[1]; - } - return '' . $string . ''; - } else { - return '' . $string . ''; - } + protected function editPanelLinkWrap_doWrap($string, $url) { + $onclick = 'vHWin=window.open(\'' . $url . '&returnUrl=close.html\',\'FEquickEditWindow\',\'' . ($GLOBALS['BE_USER']->uc['edit_wideDocument'] ? 'width=690,height=500' : 'width=540,height=400') . ',status=0,menubar=0,scrollbars=1,resizable=1\');vHWin.focus();return false;'; + return '' . $string . ''; } /** - * Wraps the input content string in a table with a gray border if the table/row combination evaluates to being disabled/hidden. - * Used for marking previewed records in the frontend. - * - * @param string $table The table name - * @param array $row The data record from $table - * @param string $content The content string to wrap - * @param integer $thick The thickness of the border - * @param array $conf The array with TypoScript properties for the content object - * @return string The input string wrapped in a table with a border color of #cccccc and thickness = $thick - * @see editPanel() - */ - protected function editPanelPreviewBorder($table, array $row, $content, $thick, array $conf = array()) { - if ($this->isDisabled($table, $row)) { - $thick = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($thick, 1, 100); - $color = $conf['color'] ? $conf['color'] : '#cccccc'; - if ($conf['innerWrap']) { - $content = $this->wrap($content, $conf['innerWrap']); - } - if ($conf['innerWrap.']) { - $content = $this->stdWrap($content, $conf['innerWrap.']); - } - $content = '
' . $content . '
'; - if ($conf['outerWrap']) { - $content = $this->wrap($content, $conf['outerWrap']); - } - if ($conf['outerWrap.']) { - $content = $this->stdWrap($panel, $conf['outerWrap.']); - } - } - return $content; - } - - /** - * Returns TRUE if the input table/row would be hidden in the frontend (according nto the current time and simulate user group) + * Returns TRUE if the input table/row would be hidden in the frontend, according to the current time and simulate user group * * @param string $table The table name * @param array $row The data record * @return boolean - * @see editPanelPreviewBorder() */ - protected function isDisabled($table, $row) { + protected function isDisabled($table, array $row) { + $status = FALSE; if ( $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'] && $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']] || @@ -329,70 +278,10 @@ class FrontendEditPanel { $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime']] && $row[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime']] < $GLOBALS['EXEC_TIME'] ) { - return TRUE; + $status = TRUE; } - } - /** - * Returns the editing form for a content element. - * - * @param string $formTag Form tag - * @param string $formName Form name - * @param string $theCmd The command - * @param integer $newUID newUID - * @param array $dataArray dataArray for element - * @param string $table Table name of element - * @param string $currentRecord Current record - * @param string $blackLine Blackline - * @return string - */ - protected function editContent($formTag, $formName, $theCmd, $newUID, array $dataArray, $table, $currentRecord, $blackLine) { - $tceforms = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\FrontendFormEngine'); - $tceforms->initDefaultBEMode(); - $tceforms->prependFormFieldNames = 'TSFE_EDIT[data]'; - $tceforms->prependFormFieldNames_file = 'TSFE_EDIT_file'; - $tceforms->doSaveFieldName = 'TSFE_EDIT[doSave]'; - $tceforms->formName = $formName; - $tceforms->backPath = TYPO3_mainDir; - $tceforms->setFancyDesign(); - $tceforms->defStyle = 'font-family:Verdana;font-size:10px;'; - $tceforms->edit_showFieldHelp = 0; - $tceforms->helpTextFontTag = ''; - $trData = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\DataPreprocessor'); - $trData->addRawData = TRUE; - $trData->lockRecords = 1; - // Added without testing - should provide ability to submit default values in frontend editing, in-page. - $trData->defVals = GeneralUtility::_GP('defVals'); - $trData->fetchRecord($table, $theCmd == 'new' ? $newUID : $dataArray['uid'], $theCmd == 'new' ? 'new' : ''); - reset($trData->regTableItems_data); - $processedDataArr = current($trData->regTableItems_data); - $processedDataArr['uid'] = $theCmd == 'new' ? 'NEW' : $dataArray['uid']; - $processedDataArr['pid'] = $theCmd == 'new' ? $newUID : $dataArray['pid']; - $panel = ''; - $buttons = ''; - $buttons .= ''; - $buttons .= ''; - // Buttons top - $panel .= $tceforms->intoTemplate(array('ITEM' => $buttons)); - $panel .= $tceforms->getMainFields($table, $processedDataArr); - $hiddenF = ''; - if ($theCmd == 'new') { - $hiddenF .= ''; - if ($table == 'pages') { - // If a new page is created in front-end, then show it by default! - $hiddenF .= ''; - } else { - $hiddenF .= ''; - $hiddenF .= ''; - } - } - $hiddenF .= ''; - // Buttons AND hidden fields bottom. - $panel .= $tceforms->intoTemplate(array('ITEM' => $buttons . $hiddenF)); - $panel = $formTag . $tceforms->wrapTotal($panel, $dataArray, $table) . '' . ($theCmd != 'new' ? $blackLine : ''); - $finalOut = $tceforms->printNeededJSFunctions_top() . ($conf['edit.']['displayRecord'] ? $content : '') . $panel . ($theCmd == 'new' ? $blackLine : '') . $tceforms->printNeededJSFunctions(); - $GLOBALS['SOBE']->doc->insertHeaderData(); - return $finalOut; + return $status; } }