[TASK] Make show_rechis.php mod.php dispatched 05/28205/5
authorNicole Cordes <typo3@cordes.co>
Sun, 9 Mar 2014 22:33:42 +0000 (23:33 +0100)
committerMarkus Klein <klein.t3@mfc-linz.at>
Mon, 24 Mar 2014 15:45:24 +0000 (16:45 +0100)
The patch adds a new module for the record history view. All calls to
the show_rechis.php script are rewritten to use
BackendUtility::getModuleUrl() to ensure CSRF protection.

Resolves: #56632
Releases: 6.2
Change-Id: I2466c1b08afdd7d987ef38a29500f02641156c07
Reviewed-on: https://review.typo3.org/28205
Reviewed-by: Markus Klein
Tested-by: Markus Klein
17 files changed:
typo3/js/extjs/components/pagetree/javascript/actions.js
typo3/show_rechis.php
typo3/sysext/backend/Classes/ClickMenu/ClickMenu.php
typo3/sysext/backend/Classes/Controller/BackendController.php
typo3/sysext/backend/Classes/Controller/ContentElement/ElementInformationController.php
typo3/sysext/backend/Classes/Controller/EditDocumentController.php
typo3/sysext/backend/Classes/Controller/PageLayoutController.php
typo3/sysext/backend/Classes/Controller/Wizard/RteController.php
typo3/sysext/backend/Classes/History/RecordHistory.php
typo3/sysext/backend/Modules/RecordHistory/conf.php [new file with mode: 0644]
typo3/sysext/backend/Modules/RecordHistory/index.php [new file with mode: 0644]
typo3/sysext/backend/ext_tables.php
typo3/sysext/belog/Classes/ViewHelpers/HistoryEntryViewHelper.php
typo3/sysext/frontend/Classes/View/AdminPanelView.php
typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php
typo3/sysext/workspaces/Classes/Controller/PreviewController.php
typo3/sysext/workspaces/Classes/Controller/ReviewController.php

index 6e6b1cc..84c7e74 100644 (file)
@@ -372,7 +372,7 @@ TYPO3.Components.PageTree.Actions = {
        openHistoryPopUp: function(node) {
                node.select();
                TYPO3.Backend.ContentContainer.setUrl(
-                       'show_rechis.php?element=pages:' + node.attributes.nodeData.id
+                       TYPO3.settings.RecordHistory.moduleUrl + '&element=pages:' + node.attributes.nodeData.id
                );
        },
 
index 1f4796e..82233cb 100644 (file)
@@ -32,6 +32,8 @@
  */
 require __DIR__ . '/init.php';
 
+\TYPO3\CMS\Core\Utility\GeneralUtility::deprecationLog('The history of a record was moved to a separate module. Please use BackendUtility::getModuleUrl() to link to this script. This script will be removed two versions after 6.2.');
+
 $elementHistoryController = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Controller\\ContentElement\\ElementHistoryController');
 $elementHistoryController->main();
 $elementHistoryController->printContent();
index 2c7eb4d..3bab552 100644 (file)
@@ -458,7 +458,7 @@ class ClickMenu {
         * @todo Define visibility
         */
        public function DB_history($table, $uid) {
-               $url = 'show_rechis.php?element=' . rawurlencode(($table . ':' . $uid));
+               $url = BackendUtility::getModuleUrl('record_history', array('element' => $table . ':' . $uid));
                return $this->linkItem($GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_history')), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-history-open')), $this->urlRefForCM($url, 'returnUrl'), 0);
        }
 
index bcdc34c..4cdb238 100644 (file)
@@ -277,6 +277,7 @@ class BackendController {
                        foreach ($jsFiles as $jsFile) {
                                $this->pageRenderer->addJsFile($relativeComponentPath . 'javascript/' . $jsFile);
                        }
+                       $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', BackendUtility::getModuleUrl('record_history'));
                }
        }
 
index 49829fb..09507c0 100644 (file)
@@ -479,11 +479,19 @@ class ElementInformationController {
                $editOnClick = BackendUtility::editOnClick('&edit[' . $table . '][' . $uid . ']=edit', $GLOBALS['BACK_PATH']);
                $icon = IconUtility::getSpriteIcon('actions-document-open');
                $pageActionIcons = '<a href="#" onclick="' . htmlspecialchars($editOnClick) . '">' . $icon . '</a>';
-               $historyOnClick = 'window.location.href=\'show_rechis.php?element=' . $table . '%3A' .
-                               $uid . '&returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI')) . '\'; return false;';
+               $historyOnClick = 'window.location.href=' .
+                       GeneralUtility::quoteJSvalue(
+                               BackendUtility::getModuleUrl(
+                                       'record_history',
+                                       array(
+                                               'element' => $table . ':' . $uid,
+                                               'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
+                                       )
+                               )
+                       ) . '; return false;';
 
                $icon = IconUtility::getSpriteIcon('actions-document-history-open');
-               $pageActionIcons .= '<a href="#" onclick="' . $historyOnClick . '">' . $icon . '</a>';
+               $pageActionIcons .= '<a href="#" onclick="' . htmlspecialchars($historyOnClick) . '">' . $icon . '</a>';
                if ($table === 'pages') {
                        $pageActionIcons .= $this->doc->viewPageIcon($uid, '');
                }
index 4b2322b..4c3c216 100644 (file)
@@ -990,11 +990,31 @@ class EditDocumentController {
                                // Undo:
                                $undoRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->firstEl['table'], 'sys_history') . ' AND recuid=' . (int)$this->firstEl['uid'], '', 'tstamp DESC', '1');
                                if ($undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) {
-                                       $aOnClick = 'window.location.href=\'show_rechis.php?element=' . rawurlencode(($this->firstEl['table'] . ':' . $this->firstEl['uid'])) . '&revert=ALL_FIELDS&sumUp=-1&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;';
+                                       $aOnClick = 'window.location.href=' .
+                                               GeneralUtility::quoteJSvalue(
+                                                       BackendUtility::getModuleUrl(
+                                                               'record_history',
+                                                               array(
+                                                                       'element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'],
+                                                                       'revert' => 'ALL_FIELDS',
+                                                                       'sumUp' => -1,
+                                                                       'returnUrl' => $this->R_URI,
+                                                               )
+                                                       )
+                                               ) . '; return false;';
                                        $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"' . ' title="' . htmlspecialchars(sprintf($GLOBALS['LANG']->getLL('undoLastChange'), BackendUtility::calcAge(($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp']), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '">' . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>';
                                }
                                if ($this->getNewIconMode($this->firstEl['table'], 'showHistory')) {
-                                       $aOnClick = 'window.location.href=\'show_rechis.php?element=' . rawurlencode(($this->firstEl['table'] . ':' . $this->firstEl['uid'])) . '&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;';
+                                       $aOnClick = 'window.location.href=' .
+                                               GeneralUtility::quoteJSvalue(
+                                                       BackendUtility::getModuleUrl(
+                                                               'record_history',
+                                                               array(
+                                                                       'element' => $this->firstEl['table'] . ':' . $this->firstEl['uid'],
+                                                                       'returnUrl' => $this->R_URI,
+                                                               )
+                                                       )
+                                               ) . '; return false;';
                                        $buttons['history'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>';
                                }
                                // If only SOME fields are shown in the form, this will link the user to the FULL form:
index d8afa37..e8b185b 100644 (file)
@@ -1111,10 +1111,34 @@ class PageLayoutController {
                                if ($this->undoButton) {
                                        // Undo button
                                        $buttons['undo'] = '<a href="#"
-                                               onclick="' . htmlspecialchars(('window.location.href=\'' . $GLOBALS['BACK_PATH'] . 'show_rechis.php?element=' . rawurlencode(($this->eRParts[0] . ':' . $this->eRParts[1])) . '&revert=ALL_FIELDS&sumUp=-1&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;')) . '"
+                                               onclick="' . htmlspecialchars('window.location.href=' .
+                                                       GeneralUtility::quoteJSvalue(
+                                                               $GLOBALS['BACK_PATH'] .
+                                                               BackendUtility::getModuleUrl(
+                                                                       'record_history',
+                                                                       array(
+                                                                               'element' => $this->eRParts[0] . ':' . $this->eRParts[1],
+                                                                               'revert' => 'ALL_FIELDS',
+                                                                               'sumUp' => -1,
+                                                                               'returnUrl' => $this->R_URI,
+                                                                       )
+                                                               )
+                                                       ) . '; return false;') . '"
                                                title="' . htmlspecialchars(sprintf($GLOBALS['LANG']->getLL('undoLastChange'), BackendUtility::calcAge(($GLOBALS['EXEC_TIME'] - $this->undoButtonR['tstamp']), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '">' . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>';
                                        // History button
-                                       $buttons['history_record'] = '<a href="#" onclick="' . htmlspecialchars(('jumpToUrl(' . GeneralUtility::quoteJSvalue($GLOBALS['BACK_PATH'] . 'show_rechis.php?element=' . rawurlencode(($this->eRParts[0] . ':' . $this->eRParts[1])) . '&returnUrl=' . rawurlencode($this->R_URI) . '#latest') . ');return false;')) . '" title="' . $GLOBALS['LANG']->getLL('recordHistory', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>';
+                                       $buttons['history_record'] = '<a href="#"
+                                               onclick="' . htmlspecialchars('jumpToUrl(' .
+                                                       GeneralUtility::quoteJSvalue(
+                                                               $GLOBALS['BACK_PATH'] .
+                                                               BackendUtility::getModuleUrl(
+                                                                       'record_history',
+                                                                       array(
+                                                                               'element' => $this->eRParts[0] . ':' . $this->eRParts[1],
+                                                                               'returnUrl' => $this->R_URI,
+                                                                       )
+                                                               ) . '#latest'
+                                                       ) . ');return false;') . '"
+                                               title="' . $GLOBALS['LANG']->getLL('recordHistory', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>';
                                }
                        }
                }
index a98d1e1..e22805c 100644 (file)
@@ -245,7 +245,18 @@ class RteController {
                        $buttons['save_close'] = '<input type="image" class="c-inputButton" onclick="' . htmlspecialchars(('document.editform.redirect.value=\'' . $closeUrl . '\'; TBE_EDITOR.checkAndDoSubmit(1); return false;')) . '" name="_saveandclosedok"' . IconUtility::skinImg($this->doc->backPath, 'gfx/saveandclosedok.gif', '') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />';
                        // Undo/Revert:
                        if ($undoButton) {
-                               $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars(('window.location.href=\'show_rechis.php?element=' . rawurlencode(($this->P['table'] . ':' . $this->P['uid'])) . '&revert=' . rawurlencode(('field:' . $this->P['field'])) . '&sumUp=-1&returnUrl=' . rawurlencode($this->R_URI) . '\'; return false;')) . '">' . '<img' . IconUtility::skinImg($this->doc->backPath, 'gfx/undo.gif') . ' class="c-inputButton" title="' . htmlspecialchars(sprintf($GLOBALS['LANG']->getLL('rte_undoLastChange'), BackendUtility::calcAge(($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp']), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '" alt="" />' . '</a>';
+                               $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars('window.location.href=' .
+                                       GeneralUtility::quoteJSvalue(
+                                               BackendUtility::getModuleUrl(
+                                                       'record_history',
+                                                       array(
+                                                               'element' => $this->P['table'] . ':' . $this->P['uid'],
+                                                               'revert' => 'field:' . $this->P['field'],
+                                                               'sumUp' => -1,
+                                                               'returnUrl' => $this->R_URI,
+                                                       )
+                                               )
+                                       ) . '; return false;') . '">' . '<img' . IconUtility::skinImg($this->doc->backPath, 'gfx/undo.gif') . ' class="c-inputButton" title="' . htmlspecialchars(sprintf($GLOBALS['LANG']->getLL('rte_undoLastChange'), BackendUtility::calcAge(($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp']), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '" alt="" />' . '</a>';
                        }
                        // Shortcut
                        if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
index 2145ea5..99d11ba 100644 (file)
@@ -802,7 +802,7 @@ class RecordHistory {
                // Mergin overriding values:
                $params = array_merge($params, $inparams);
                // Make the link:
-               $link = 'show_rechis.php?' . GeneralUtility::implodeArrayForUrl('', $params) . ($anchor ? '#' . $anchor : '');
+               $link = BackendUtility::getModuleUrl('record_history', $params) . ($anchor ? '#' . $anchor : '');
                return '<a href="' . htmlspecialchars($link) . '"' . ($title ? ' title="' . $title . '"' : '') . '>' . $str . '</a>';
        }
 
diff --git a/typo3/sysext/backend/Modules/RecordHistory/conf.php b/typo3/sysext/backend/Modules/RecordHistory/conf.php
new file mode 100644 (file)
index 0000000..2c7845d
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+//required for mod.php
+$MCONF['name'] = 'record_history';
+$MCONF['script'] = '_DISPATCH';
+$MCONF['access'] = '';
+?>
diff --git a/typo3/sysext/backend/Modules/RecordHistory/index.php b/typo3/sysext/backend/Modules/RecordHistory/index.php
new file mode 100644 (file)
index 0000000..1a9ef42
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Nicole Cordes (typo3@cordes.co)
+ *  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 text file 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!
+ ***************************************************************/
+
+$elementHistoryController = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Controller\\ContentElement\\ElementHistoryController');
+$elementHistoryController->main();
+$elementHistoryController->printContent();
\ No newline at end of file
index c5fcbec..ab2df60 100644 (file)
@@ -4,6 +4,12 @@ if (!defined('TYPO3_MODE')) {
 }
 
 if (TYPO3_MODE === 'BE') {
+       // Register record history module
+       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModulePath(
+               'record_history',
+               \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Modules/RecordHistory/'
+       );
+
        // Register edit wizard
        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModulePath(
                'wizard_edit',
index b0ac9c1..6a63232 100644 (file)
@@ -60,7 +60,14 @@ class HistoryEntryViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractVi
                $historyIcon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-history-open', array(
                        'title' => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('showHistory', $this->controllerContext->getRequest()->getControllerExtensionName())
                ));
-               $historyHref = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3/show_rechis.php?sh_uid=' . $historyEntry->getUid() . '&returnUrl=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI'));
+               $historyHref = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3/' .
+                       \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl(
+                               'record_history',
+                               array(
+                                       'sh_uid' => $historyEntry->getUid(),
+                                       'returnUrl' => \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI'),
+                               )
+                       );
                $historyLink = '<a href="' . htmlspecialchars($historyHref) . '">' . $historyIcon . '</a>';
                return $historyLabel . '&nbsp;' . $historyLink;
        }
index 1e1d9c5..fdc6112 100644 (file)
@@ -596,7 +596,7 @@ class AdminPanelView {
                $returnUrl = '&returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'));
 
                $icon = IconUtility::getSpriteIcon('actions-document-history-open', array('title' => $this->extGetLL('edit_newContentElement')));
-               $toolBar = '<a href="' . htmlspecialchars((TYPO3_mainDir . 'show_rechis.php?element=' . rawurlencode(('pages:' . $id)) . $returnUrl)) . '#latest">' . $icon . '</a>';
+               $toolBar = '<a href="' . htmlspecialchars(TYPO3_mainDir . BackendUtility::getModuleUrl('record_history', array('element' => 'pages:' . $id)) . $returnUrl) . '#latest">' . $icon . '</a>';
                if ($perms & 16 && $langAllowed) {
                        $params = '';
                        if ($GLOBALS['TSFE']->sys_language_uid) {
index e8cef05..15faa3d 100644 (file)
@@ -1050,7 +1050,7 @@ class DatabaseRecordList extends \TYPO3\CMS\Recordlist\RecordList\AbstractDataba
                        // 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="' . $GLOBALS['LANG']->getLL('history', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-history-open') . '</a>';
+                               $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);
index 65b236a..206aed5 100644 (file)
@@ -82,6 +82,7 @@ class PreviewController extends \TYPO3\CMS\Workspaces\Controller\AbstractControl
                foreach ($jsFiles as $jsFile) {
                        $this->pageRenderer->addJsFile($resourcePathJavaScript . $jsFile);
                }
+               $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', BackendUtility::getModuleUrl('record_history'));
                // todo this part should be done with inlineLocallanglabels
                $this->pageRenderer->addJsInlineCode('workspace-inline-code', $this->generateJavascript());
        }
index 08e8fa7..f5e4c60 100644 (file)
@@ -192,6 +192,7 @@ class ReviewController extends \TYPO3\CMS\Workspaces\Controller\AbstractControll
                foreach ($javaScriptFiles as $javaScriptFile) {
                        $this->pageRenderer->addJsFile($javaScriptFile);
                }
+               $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('record_history'));
        }
 
 }