Error News Recycler Undelete broken for nonAdmins and Fix
Case:
- Editors (nonAdmins) with all rights on all NewsRecord-Types and Global Categories
- Editors have Web Recycler Module (Core) to restore deleted Records.
- Editors have not yet added any Categories
- Editor adds News1 in Sysfolder (without any Category-Relation)
- Editor deletes News1 in Sysfolder
- Editor uses Recycler to check for deleted records and finds News1
- Editor selects News1, and Clicks Button Undelete
and confirms the Dialog: "Undelete records from tables: tx_news_domain_model_news Are you Sure?"
with OK and gets the following ERROR:
Uncaught TYPO3 Exception
#1: PHP Catchable Fatal Error: Argument 1 passed to GeorgRinger\News\Service\AccessControlService::userHasCategoryPermissionsForRecord() must be of the type array, null given, called in /srv/www/www/typo3conf/ext/news/Classes/Hooks/DataHandler.php on line 157 and defined in /srv/www/www/typo3conf/ext/news/Classes/Service/AccessControlService.php line 35 (More information)
- Stacktrace see below (the print_r is mine ;-)
- Reason seems to be that $newsRecord = BackendUtilityCore::getRecord($table, $id); wont return the right value.
- However it seems superflous to me that the
function processCmdmap_preProcess
which is supposed to:
- Prevent deleting/moving of a news record if the editor doesn't have access to all categories of the news record
also tries to take care of an Undelete-Action.
Thus my simple bugfix is to exclude the undelete-command from those checks in:
news/Classes/Hooks/DataHandler.php:153
public function processCmdmap_preProcess($command, &$table, $id, $value, $parentObject) {
// if ($table === 'tx_news_domain_model_news' && !$this->getBackendUser()->isAdmin() && is_integer($id)) {
if ($table === 'tx_news_domain_model_news' && $command != 'undelete' && !$this->getBackendUser()->isAdmin() && is_integer($id)) {
Please review and feedback;
Thanks Georg
Stacktrace
10 TYPO3\CMS\Core\Error\ErrorHandler::handleError(4096, "Argument 1 passed to GeorgRinger\News\Service\Acce…sses/Hooks/DataHandler.php on line 157 and defined", "/srv/www/www/typo3conf/ext/news/Classes/Service/AccessControlService.php", 35, array)
/srv/www/www/typo3conf/ext/news/Classes/Service/AccessControlService.php:
00033: * @return boolean
00034: */
00035: public static function userHasCategoryPermissionsForRecord(array $newsRecord) {
00036: if (!EmConfiguration::getSettings()->getCategoryBeGroupTceFormsRestriction()) {
00037: return TRUE;
9 GeorgRinger\News\Service\AccessControlService::userHasCategoryPermissionsForRecord(NULL)
/srv/www/www/typo3conf/ext/news/Classes/Hooks/DataHandler.php:
00155: $newsRecord = BackendUtilityCore::getRecord($table, $id);
00156: print_r($newsRecord);
00157: if (!AccessControlService::userHasCategoryPermissionsForRecord($newsRecord)) {
00158: $parentObject->log($table, $id, 2, 0, 1, "processCmdmap: Attempt to " . $command . " a record from table '%s' without permission. Reason: the record has one or more categories assigned that are not defined in the BE usergroup.", 1, array($table));
00159: // unset table to prevent saving
8 GeorgRinger\News\Hooks\DataHandler::processCmdmap_preProcess("undelete", "tx_news_domain_model_news", 14, 1, TYPO3\CMS\Core\DataHandling\DataHandler, boolean)
/srv/www/www/typo3_src/typo3/sysext/core/Classes/DataHandling/DataHandler.php:
02995: foreach ($hookObjectsArr as $hookObj) {
02996: if (method_exists($hookObj, 'processCmdmap_preProcess')) {
02997: $hookObj->processCmdmap_preProcess($command, $table, $id, $value, $this, $pasteUpdate);
02998: }
02999: }
7 TYPO3\CMS\Core\DataHandling\DataHandler::process_cmdmap()
/srv/www/www/typo3_src/typo3/sysext/recycler/Classes/Domain/Model/DeletedRecords.php:
00323: $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Core\DataHandling\DataHandler');
00324: $tce->start(array(), $cmd);
00325: $tce->process_cmdmap();
00326: $result = TRUE;
00327: }
6 TYPO3\CMS\Recycler\Domain\Model\DeletedRecords::undeleteData("[["tx_news_domain_model_news",14]]", "false")
/srv/www/www/typo3_src/typo3/sysext/recycler/Classes/Controller/RecyclerAjaxController.php:
00111: $recursive = GeneralUtility::_GP('recursive');
00112: $model = GeneralUtility::makeInstance('TYPO3\CMS\Recycler\Domain\Model\DeletedRecords');
00113: if ($model->undeleteData($this->data, $recursive)) {
00114: $str = TRUE;
00115: }
5 TYPO3\CMS\Recycler\Controller\RecyclerAjaxController::createContent()
/srv/www/www/typo3_src/typo3/sysext/recycler/Classes/Controller/RecyclerAjaxController.php:
00072: }
00073: // Create content
00074: $this->createContent();
00075: }
00076:
4 TYPO3\CMS\Recycler\Controller\RecyclerAjaxController::mapCommand()
/srv/www/www/typo3_src/typo3/sysext/recycler/Classes/Controller/RecyclerAjaxController.php:
00054: */
00055: public function init() {
00056: $this->mapCommand();
00057: $this->getContent();
00058: }
3 TYPO3\CMS\Recycler\Controller\RecyclerAjaxController::init(array, TYPO3\CMS\Core\Http\AjaxRequestHandler)
2 call_user_func_array(array, array)
/srv/www/www/typo3_src/typo3/sysext/core/Classes/Utility/GeneralUtility.php:
04296: }
04297: // Call method:
04298: $content = call_user_func_array(array(&$classObj, $parts[1]), array(&$params, &$ref));
04299: } else {
04300: $errorMsg = 'No method name '' . $parts[1] . '' in class ' . $parts[0];
1 TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction("TYPO3\CMS\Recycler\Controller\RecyclerAjaxController->init", array, TYPO3\CMS\Core\Http\AjaxRequestHandler, boolean, boolean)
/srv/www/www/typo3_src/typo3/ajax.php:
00078: // Cleanup global variable space
00079: unset($csrfTokenCheck, $ajaxRegistryEntry, $tokenIsValid, $success);
00080: $success = \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($ajaxScript, $ajaxParams, $ajaxObj, FALSE, TRUE);
00081: } else {
00082: $ajaxObj->setError('Invalid CSRF token detected for ajaxID "' . $ajaxID . '"!');