diff --git a/Classes/Cache/PermissionCache.php b/Classes/Cache/PermissionCache.php index f7d734e..cae378e 100644 --- a/Classes/Cache/PermissionCache.php +++ b/Classes/Cache/PermissionCache.php @@ -212,7 +212,9 @@ protected function getCacheIdentifier($requestedPermissions = '') throw new \JBartels\BeAcl\Exception\RuntimeException('The Backend user needs to be initializes before the cache identifier can be generated.'); } - $identifier = $this->backendUser->user['uid'] . ';' . $this->backendUser->user['usergroup_cached_list'] . ';' . $this->backendUser->user['workspace_id']; + $identifier = ($this->backendUser->user['uid'] ?? '') . ';' . + ($this->backendUser->user['usergroup_cached_list'] ?? '') . ';' . + ($this->backendUser->user['workspace_id'] ?? ''); $requestedPermissions = trim($requestedPermissions); if ($requestedPermissions !== '') { diff --git a/Classes/Controller/PermissionAjaxController.php b/Classes/Controller/PermissionAjaxController.php deleted file mode 100644 index ddba50c..0000000 --- a/Classes/Controller/PermissionAjaxController.php +++ /dev/null @@ -1,172 +0,0 @@ -extPath = empty($extPath) ? ExtensionManagementUtility::extPath('be_acl') : $extPath; - } - - /** - * Initialize the viewz - */ - protected function initializeView() - { - $this->view = GeneralUtility::makeInstance(StandaloneView::class); - $this->view->setPartialRootPaths(array('default' => $this->extPath . 'Resources/Private/Partials')); - $this->view->assign('pageId', $this->conf['page']); - } - - /** - * The main dispatcher function. Collect data and prepare HTML output. - * - * @param ServerRequestInterface $request - * - * @return ResponseInterface - */ - public function dispatch(ServerRequestInterface $request): ResponseInterface - { - // Actions handled by this class - $handledActions = ['delete_acl']; - $response = new HtmlResponse(''); - - $requestBody = $request->getParsedBody(); - $action = $requestBody['action'] ?? null; - $page = $requestBody['page'] ?? null; - - if ($page > 0 && in_array($action, $handledActions)) { - return $this->handleAction($request, $response, $action); - } - - return parent::dispatch($request); - } - - protected function handleAction(ServerRequestInterface $request, ResponseInterface $response, $action) - { - $methodName = GeneralUtility::underscoredToLowerCamelCase($action); - - if (method_exists($this, $methodName)) { - return call_user_func_array(array($this, $methodName), [$request, $response]); - } - - $response->getBody()->write('Action method not found'); - - return $response->withStatus(400); - } - - protected function deleteAcl(ServerRequestInterface $request, ResponseInterface $response) - { - $GLOBALS['LANG']->includeLLFile('EXT:be_acl/Resources/Private/Languages/locallang_perm.xlf'); - $GLOBALS['LANG']->getLL('aclUsers'); - - $postData = $request->getParsedBody(); - $aclUid = !empty($postData['acl']) ? $postData['acl'] : null; - - if (!MathUtility::canBeInterpretedAsInteger($aclUid)) { - return $this->errorResponse($response, $GLOBALS['LANG']->getLL('noAclId'), 400); - } - $aclUid = (int)$aclUid; - // Prepare command map - $cmdMap = [ - $this->table => [ - $aclUid => ['delete' => 1] - ] - ]; - - try { - // Process command map - $tce = GeneralUtility::makeInstance(DataHandler::class); - $tce->stripslashes_values = 0; - $tce->start(array(), $cmdMap); - $this->checkModifyAccess($this->table, $aclUid, $tce); - $tce->process_cmdmap(); - } catch (\Exception $ex) { - return $this->errorResponse($response, $ex->getMessage(), 403); - } - - $body = [ - 'title' => $GLOBALS['LANG']->getLL('aclSuccess'), - 'message' => $GLOBALS['LANG']->getLL('aclDeleted') - ]; - // Return result - $response->getBody()->write(json_encode($body)); - return $response; - } - - protected function checkModifyAccess($table, $id, DataHandler $tcemainObj) - { - // Check modify access - $modifyAccessList = $tcemainObj->checkModifyAccessList($table); - // Check basic permissions and circumstances: - if (!isset($GLOBALS['TCA'][$table]) || $tcemainObj->tableReadOnly($table) || !is_array($tcemainObj->cmdmap[$table]) || !$modifyAccessList) { - throw new \JBartels\BeAcl\Exception\RuntimeException($GLOBALS['LANG']->getLL('noPermissionToModifyAcl')); - } - - // Check table / id - if (!$GLOBALS['TCA'][$table] || !$id) { - throw new \JBartels\BeAcl\Exception\RuntimeException(sprintf($GLOBALS['LANG']->getLL('noEditAccessToAclRecord'), $id, $table)); - } - - // Check edit access - $hasEditAccess = $tcemainObj->BE_USER->recordEditAccessInternals($table, $id, false, false, true); - if (!$hasEditAccess) { - throw new \JBartels\BeAcl\Exception\RuntimeException(sprintf($GLOBALS['LANG']->getLL('noEditAccessToAclRecord'), $id, $table)); - } - } - - protected function errorResponse(ResponseInterface $response, $reason, $status = 500) - { - return $response->withStatus($status, $reason); - } -} diff --git a/Classes/Controller/PermissionController.php b/Classes/Controller/PermissionController.php index 2c6f3fa..1b45033 100644 --- a/Classes/Controller/PermissionController.php +++ b/Classes/Controller/PermissionController.php @@ -24,18 +24,22 @@ * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use JBartels\BeAcl\Exception\RuntimeException; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Backend\Utility\IconUtility; +use TYPO3\CMS\Beuser\Controller\PermissionController as BasePermissionController; use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; +use TYPO3\CMS\Core\DataHandling\DataHandler; +use TYPO3\CMS\Core\Http\ApplicationType; +use TYPO3\CMS\Core\Http\HtmlResponse; +use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\ArrayUtility; -use TYPO3\CMS\Backend\Tree\View\PageTreeView; -use TYPO3\CMS\Core\Messaging\FlashMessage; +use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; -use TYPO3\CMS\Extbase\Mvc\View\ViewInterface; -use JBartels\BeAcl\View\BackendTemplateView; use TYPO3\CMS\Core\Database\ConnectionPool; -use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder; +use TYPO3\CMS\Fluid\View\StandaloneView; /** * Backend ACL - Replacement for "web->Access" @@ -45,16 +49,11 @@ * Bugfixes applied: * #25942, #25835, #13019, #13176, #13175 Jan Bartels */ -class PermissionController extends \TYPO3\CMS\Beuser\Controller\PermissionController +class PermissionController extends BasePermissionController { - - protected $defaultViewObjectName = BackendTemplateView::class; - - protected $aclList = []; - - protected $currentAction; - - protected $aclTypes = [0, 1]; + protected string $table = 'tx_beacl_acl'; + protected array $aclList = []; + protected array $aclTypes = [0, 1]; /***************************** * @@ -63,55 +62,80 @@ class PermissionController extends \TYPO3\CMS\Beuser\Controller\PermissionContro *****************************/ /** - * Initialize action - * - * @return void + * @param string $template */ - protected function initializeAction() + protected function initializeView(string $template = ''): void { - parent::initializeAction(); + $this->view = GeneralUtility::makeInstance(StandaloneView::class); + $this->view->setTemplateRootPaths( + ['EXT:beuser/Resources/Private/Templates/Permission', 'EXT:be_acl/Resources/Private/Templates/Permission'] + ); + $this->view->setPartialRootPaths( + ['EXT:beuser/Resources/Private/Partials', 'EXT:be_acl/Resources/Private/Partials'] + ); + $this->view->setLayoutRootPaths( + ['EXT:beuser/Resources/Private/Layouts', 'EXT:be_acl/Resources/Private/Layouts'] + ); + + if ($template !== '') { + $this->view->setTemplatePathAndFilename( + GeneralUtility::getFileAbsFileName('EXT:be_acl/Resources/Private/Templates/Permission/' . $template . '.html') + ); + $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Beuser/Permissions'); + $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip'); + } if(empty($this->returnUrl)) { - $this->returnUrl = $this->uriBuilder->reset()->setArguments([ + $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); + // @extensionScannerIgnoreLine + $this->returnUrl = $uriBuilder->reset()->setArguments([ 'action' => 'index', 'id' => $this->id - ])->buildBackendUri(); + ])->buildBackendUri(); + } + + // Add custom JS for Acl permissions + if ($this->isBackendMode()) { + $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); + $pageRenderer->loadRequireJsModule('TYPO3/CMS/BeAcl/AclPermissions'); } } /** - * Initializes view - * - * @param ViewInterface $view The view to be initialized - * @return void + * @return bool */ - protected function initializeView(ViewInterface $view) + protected function isBackendMode(): bool { - parent::initializeView($view); - // Add custom JS for Acl permissions - if ($view instanceof BackendTemplateView) { - $view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/BeAcl/AclPermissions'); + return ($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface + && ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend(); + } + + public function handleAjaxRequest(ServerRequestInterface $request): ResponseInterface + { + $response = new HtmlResponse(''); + $parsedBody = $request->getParsedBody(); + $action = $parsedBody['action'] ?? null; + + if ($action === 'delete_acl') { + return $this->deleteAcl($request, $response); } + + return parent::handleAjaxRequest($request); + } /** - * Index action + * @param ServerRequestInterface $request * - * @return void + * @return ResponseInterface */ - public function indexAction() + public function indexAction(ServerRequestInterface $request): ResponseInterface { - parent::indexAction(); - // Get ACL configuration $beAclConfig = $this->getExtConf(); $disableOldPermissionSystem = $beAclConfig['disableOldPermissionSystem'] ? 1 : 0; $enableFilterSelector = $beAclConfig['enableFilterSelector'] ? 1 : 0; - - $this->view->assign('disableOldPermissionSystem', $disableOldPermissionSystem); - $this->view->assign('enableFilterSelector', $enableFilterSelector); - $GLOBALS['LANG']->includeLLFile('EXT:be_acl/Resources/Private/Languages/locallang_perm.xlf'); /* @@ -128,14 +152,6 @@ public function indexAction() else { $usersSelected = $userAcls; } - $this->view->assign('userSelectedAcls', $usersSelected); - - // Options for user filter - $this->view->assign('userFilterOptions', [ - 'options' => $userAcls, - 'title' => $GLOBALS['LANG']->getLL('aclUsers'), - 'id' => 'userAclFilter' - ]); /* * Group ACLs @@ -151,31 +167,40 @@ public function indexAction() else { $groupsSelected = $groupAcls; } - $this->view->assign('groupSelectedAcls', $groupsSelected); - - // Options for group filter - $this->view->assign('groupFilterOptions', [ - 'options' => $groupAcls, - 'title' => $GLOBALS['LANG']->getLL('aclGroups'), - 'id' => 'groupAclFilter' - ]); /* * ACL Tree */ $this->buildACLtree(array_keys($userAcls), array_keys($groupAcls)); - $this->view->assign('aclList', $this->aclList); + + $this->view->assignMultiple([ + 'disableOldPermissionSystem' => $disableOldPermissionSystem, + 'enableFilterSelector' => $enableFilterSelector, + 'userSelectedAcls' => $usersSelected, + 'userFilterOptions' => [ + 'options' => $userAcls, + 'title' => $GLOBALS['LANG']->getLL('aclUsers'), + 'id' => 'userAclFilter' + ], + 'groupSelectedAcls' => $groupsSelected, + 'groupFilterOptions' => [ + 'options' => $groupAcls, + 'title' => $GLOBALS['LANG']->getLL('aclGroups'), + 'id' => 'groupAclFilter' + ], + 'aclList' => $this->aclList + ]); + + return parent::indexAction($request); } /** - * Edit action + * @param ServerRequestInterface $request * - * @return void + * @return ResponseInterface */ - public function editAction() + public function editAction(ServerRequestInterface $request): ResponseInterface { - parent::editAction(); - // Get ACL configuration $beAclConfig = $this->getExtConf(); @@ -187,6 +212,7 @@ public function editAction() // ACL CODE $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_beacl_acl'); + // @extensionScannerIgnoreLine $statement = $queryBuilder ->select('*') ->from('tx_beacl_acl') @@ -194,12 +220,14 @@ public function editAction() $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter( $this->id, \PDO::PARAM_INT ) ) ) ->execute(); - $pageAcls = array(); + $pageAcls = []; + while ($result = $statement->fetch()) { $pageAcls[] = $result; } - $userGroupSelectorOptions = array(); + $userGroupSelectorOptions = []; + foreach (array(1 => 'Group', 0 => 'User') as $type => $label) { $option = new \stdClass(); $option->key = $type; @@ -207,26 +235,29 @@ public function editAction() 'be_acl'); $userGroupSelectorOptions[] = $option; } + $this->view->assign('userGroupSelectorOptions', $userGroupSelectorOptions); $this->view->assign('pageAcls', $pageAcls); + + return parent::editAction($request); } /** - * Update action + * @param ServerRequestInterface $request * - * @param array $data - * @param array $mirror - * @return void + * @return ResponseInterface */ - protected function updateAction(array $data, array $mirror) + protected function updateAction(ServerRequestInterface $request): ResponseInterface { + $data = (array)($request->getParsedBody()['data'] ?? []); + // Process data map $tce = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler'); $tce->stripslashes_values = 0; $tce->start($data, array()); $tce->process_datamap(); - parent::updateAction($data, $mirror); + return parent::updateAction($request); } /***************************** @@ -235,22 +266,13 @@ protected function updateAction(array $data, array $mirror) * *****************************/ - protected function getCurrentAction() - { - if (is_null($this->currentAction)) { - $this->currentAction = $this->request->getControllerActionName(); - } - return $this->currentAction; - } - /** - * * @global array $BE_USER * @param int $type * @param array $conf * @return array */ - protected function aclObjects($type, $conf) + protected function aclObjects(int $type, array $conf) { global $BE_USER; $aclObjects = []; @@ -281,7 +303,7 @@ protected function aclObjects($type, $conf) $currentSelectionOverride_raw = GeneralUtility::_GP('tx_beacl_objsel'); $currentSelectionOverride = array(); - if (is_array($currentSelectionOverride_raw[$type])) { + if (isset($currentSelectionOverride_raw[$type])) { foreach ($currentSelectionOverride_raw[$type] as $tmp) { $currentSelectionOverride[$tmp] = $tmp; } @@ -291,7 +313,7 @@ protected function aclObjects($type, $conf) } $BE_USER->uc['moduleData']['txbeacl_aclSelector'][$type] = $currentSelection; - $BE_USER->writeUC($BE_USER->uc); + $BE_USER->writeUC(); } // create option data @@ -314,7 +336,7 @@ protected function aclObjects($type, $conf) * @param array $users - user ID list * @param array $groups - group ID list */ - protected function buildACLtree($users, $groups) + protected function buildACLtree(array $users, array $groups) { $startPerms = [ 0 => [], @@ -322,6 +344,7 @@ protected function buildACLtree($users, $groups) ]; // get permissions in the starting point for users and groups + // @extensionScannerIgnoreLine $rootLine = BackendUtility::BEgetRootLine($this->id); $currentPage = array_shift($rootLine); // needed as a starting point @@ -367,7 +390,10 @@ protected function buildACLtree($users, $groups) $this->traversePageTree_acl($startPerms, $currentPage['uid']); } - protected function getDefaultAclMetaData() + /** + * @return array + */ + protected function getDefaultAclMetaData(): array { return array_fill_keys($this->aclTypes, [ 'acls' => 0, @@ -379,7 +405,7 @@ protected function getDefaultAclMetaData() * Adds count meta data to the page ACL list * @param array $pageData */ - protected function addAclMetaData(&$pageData) + protected function addAclMetaData(array &$pageData) { if (!array_key_exists('meta', $pageData)) { $pageData['meta'] = $this->getDefaultAclMetaData(); @@ -396,7 +422,7 @@ protected function addAclMetaData(&$pageData) * @param array $parentACLs * @param int $pageId */ - protected function traversePageTree_acl($parentACLs, $pageId) + protected function traversePageTree_acl(array $parentACLs, int $pageId) { // Fetch ACLs aasigned to given page $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_beacl_acl'); @@ -432,7 +458,7 @@ protected function traversePageTree_acl($parentACLs, $pageId) $parentACLs[$result['type']][$result['object_id']] = $aclData; // If there also is a non-recursive ACL for this object_id, that takes precedence // for this page. Otherwise, add it to the ACL list. - if (is_array($hasNoRecursive[$pageId][$result['type']][$result['object_id']])) { + if (isset($hasNoRecursive[$pageId][$result['type']][$result['object_id']])) { $this->aclList[$pageId][$result['type']][$result['object_id']] = $hasNoRecursive[$pageId][$result['type']][$result['object_id']]; } else { $this->aclList[$pageId][$result['type']][$result['object_id']] = $aclData; @@ -461,5 +487,80 @@ protected function getExtConf() { return GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('be_acl'); } -} + /** + * @param ServerRequestInterface $request + * @param ResponseInterface $response + * + * @return ResponseInterface + */ + protected function deleteAcl(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface + { + $GLOBALS['LANG']->includeLLFile('EXT:be_acl/Resources/Private/Languages/locallang_perm.xlf'); + $GLOBALS['LANG']->getLL('aclUsers'); + + $postData = $request->getParsedBody(); + $aclUid = !empty($postData['acl']) ? $postData['acl'] : null; + + if (!MathUtility::canBeInterpretedAsInteger($aclUid)) { + return $response->withStatus(400, $GLOBALS['LANG']->getLL('noAclId')); + } + + $aclUid = (int)$aclUid; + + // Prepare command map + $cmdMap = [ + $this->table => [ + $aclUid => ['delete' => 1] + ] + ]; + + try { + // Process command map + $tce = GeneralUtility::makeInstance(DataHandler::class); + $tce->stripslashes_values = 0; + $tce->start(array(), $cmdMap); + $this->checkModifyAccess($this->table, $aclUid, $tce); + $tce->process_cmdmap(); + } catch (\Exception $ex) { + return $response->withStatus(403, $ex->getMessage()); + } + + $body = [ + 'title' => $GLOBALS['LANG']->getLL('aclSuccess'), + 'message' => $GLOBALS['LANG']->getLL('aclDeleted') + ]; + + // Return result + $response->getBody()->write(json_encode($body)); + + return $response; + } + + /** + * @param string $table + * @param $id + * @param DataHandler $tcemainObj + */ + protected function checkModifyAccess(string $table, $id, DataHandler $tcemainObj) + { + // Check modify access + $modifyAccessList = $tcemainObj->checkModifyAccessList($table); + + // Check basic permissions and circumstances: + if (!isset($GLOBALS['TCA'][$table]) || $tcemainObj->tableReadOnly($table) || !is_array($tcemainObj->cmdmap[$table]) || !$modifyAccessList) { + throw new RuntimeException($GLOBALS['LANG']->getLL('noPermissionToModifyAcl')); + } + + // Check table / id + if (!$GLOBALS['TCA'][$table] || !$id) { + throw new RuntimeException(sprintf($GLOBALS['LANG']->getLL('noEditAccessToAclRecord'), $id, $table)); + } + + // Check edit access + $hasEditAccess = $tcemainObj->BE_USER->recordEditAccessInternals($table, $id, false, false, true); + if (!$hasEditAccess) { + throw new RuntimeException(sprintf($GLOBALS['LANG']->getLL('noEditAccessToAclRecord'), $id, $table)); + } + } +} diff --git a/Classes/Hook/DataHandlerHook.php b/Classes/Hook/DataHandlerHook.php index be006a7..1756dd0 100644 --- a/Classes/Hook/DataHandlerHook.php +++ b/Classes/Hook/DataHandlerHook.php @@ -138,7 +138,7 @@ public function checkRecordUpdateAccess($table, $id, $data, &$res, DataHandler $ /** * Case #2 - We are editing the page in default language, so translation gets updated too */ - $currentRecordUid = (integer)$dataHandler->checkValue_currentRecord['uid']; + $currentRecordUid = (int) ($dataHandler->checkValue_currentRecord['uid'] ?? 0); if ($currentRecordUid != 0 && $currentRecordUid != $id) { return true; } diff --git a/Classes/Utility/ObjectSelection.php b/Classes/Utility/ObjectSelection.php index a50a68f..cdb0bec 100644 --- a/Classes/Utility/ObjectSelection.php +++ b/Classes/Utility/ObjectSelection.php @@ -25,6 +25,7 @@ ***************************************************************/ use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Extbase\Utility\LocalizationUtility; /** * Class for building the item array for the Backend forms. @@ -51,13 +52,15 @@ function select($PA, $fobj) return; } - // Resetting the SELECT field items - $PA['items'] = array( - 0 => array( - 0 => '', - 1 => '', - ), - ); + $PA['items'] = [ + 0 =>[ + 0 => LocalizationUtility::translate( + 'LLL:EXT:be_acl/Resources/Private/Languages/locallang_db.xlf:tx_beacl_acl.object_id.select', + 'be_acl' + ), + 1 => 0, + ], + ]; $type = isset($PA['row']['type'][0]) ? $PA['row']['type'][0] : null; // Get users or groups - The function copies functionality of the method acl_objectSelector() // of ux_SC_mod_web_perm_index class as for non-admins it returns only: diff --git a/Classes/Utility/UserAuthGroup.php b/Classes/Utility/UserAuthGroup.php index 47329bb..1c65535 100644 --- a/Classes/Utility/UserAuthGroup.php +++ b/Classes/Utility/UserAuthGroup.php @@ -137,7 +137,6 @@ public function calcPerms($params, $that) */ public function getPagePermsClause($params, $that) { - /** @var \JBartels\BeAcl\Cache\PermissionCache $permissionCache */ $permissionCache = GeneralUtility::makeInstance('JBartels\\BeAcl\\Cache\\PermissionCache'); $permissionCache->setBackendUser($that); @@ -162,14 +161,13 @@ public function getPagePermsClause($params, $that) $this->getPagePermsClause_single(0, $that->user['uid'], $perms); // get allowed IDs for every single group - if ($that->groupList) { - $groupList = explode(',', $that->groupList); - foreach ($groupList as $singleGroup) { + if ($that->userGroupsUID) { + foreach ($that->userGroupsUID as $singleGroup) { $this->getPagePermsClause_single(1, $singleGroup, $perms); } } - if (!empty($this->aclPageList)) { + if (!empty($this->aclPageList)) { // put all page IDs together to the final SQL string $str = '( ' . $str . ' ) OR ( `pages`.`uid` IN (' . implode(',', $this->aclPageList) . ') )'; @@ -221,7 +219,9 @@ protected function getPagePermsClause_single($type, $object_id, $perms) ) ) ->execute(); -// $aclAllowed[] = $statement->fetchAll(); + + $aclAllowed = []; + while ($result = $statement->fetch()) { $aclAllowed[] = $result; } diff --git a/Classes/View/BackendTemplateView.php b/Classes/View/BackendTemplateView.php deleted file mode 100644 index 450fe79..0000000 --- a/Classes/View/BackendTemplateView.php +++ /dev/null @@ -1,79 +0,0 @@ -templateView->getTemplateRootPaths(); - } - - /** - * Set the root path(s) to the templates. - * If set, overrides the one determined from $this->templateRootPathPattern - * @see \TYPO3\CMS\Fluid\View\TemplateView::setTemplateRootPaths() - * - * @return void - */ - public function setTemplateRootPaths(array $templateRootPaths) - { - $this->templateView->setTemplateRootPaths($templateRootPaths); - } - - /** - * Resolves the partial root to be used inside other paths. - * @see \TYPO3\CMS\Fluid\View\TemplateView::getPartialRootPaths() - * - * @return array Path(s) to partial root directory - */ - protected function getPartialRootPaths() - { - return $this->templateView->getPartialRootPaths(); - } - - /** - * Set the root path(s) to the partials. - * If set, overrides the one determined from $this->partialRootPathPattern - * @see \TYPO3\CMS\Fluid\View\TemplateView::setPartialRootPaths() - * - * @return void - */ - public function setPartialRootPaths(array $partialRootPaths) - { - $this->templateView->setPartialRootPaths($partialRootPaths); - } - -} diff --git a/Configuration/Backend/AjaxRoutes.php b/Configuration/Backend/AjaxRoutes.php deleted file mode 100644 index 571a6f6..0000000 --- a/Configuration/Backend/AjaxRoutes.php +++ /dev/null @@ -1,12 +0,0 @@ - [ - 'path' => '/users/access/permissions', - 'target' => \JBartels\BeAcl\Controller\PermissionAjaxController::class . '::dispatch' - ] -]; diff --git a/Configuration/Service.yaml b/Configuration/Service.yaml new file mode 100644 index 0000000..aca962d --- /dev/null +++ b/Configuration/Service.yaml @@ -0,0 +1,12 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + JBartels\BeAcl\: + resource: '../Classes/*' + + TYPO3\CMS\Beuser\Controller\PermissionController: + class: JBartels\BeAcl\Controller\PermissionController + tags: ['backend.controller'] diff --git a/Resources/Private/Languages/locallang_db.xlf b/Resources/Private/Languages/locallang_db.xlf index d3a8c03..63e7c8d 100644 --- a/Resources/Private/Languages/locallang_db.xlf +++ b/Resources/Private/Languages/locallang_db.xlf @@ -18,6 +18,9 @@ ID of User/Group + + Select ID of User/Group + Show page diff --git a/Resources/Private/Partials/Permission/EditAclRow.html b/Resources/Private/Partials/Permission/EditAclRow.html index b3d424a..4aacdfc 100644 --- a/Resources/Private/Partials/Permission/EditAclRow.html +++ b/Resources/Private/Partials/Permission/EditAclRow.html @@ -1,6 +1,6 @@ {namespace core = TYPO3\CMS\Core\ViewHelpers} - +
@@ -37,17 +37,24 @@
- - - - - - - - + + + + + - - + + - - \ No newline at end of file + + + + + + + diff --git a/Resources/Private/Partials/Permission/EditTypeSelector.html b/Resources/Private/Partials/Permission/EditTypeSelector.html index 71ea241..4f0d6c9 100644 --- a/Resources/Private/Partials/Permission/EditTypeSelector.html +++ b/Resources/Private/Partials/Permission/EditTypeSelector.html @@ -1,7 +1,7 @@ - + - - \ No newline at end of file + diff --git a/Resources/Private/Partials/Permission/EditUserGroupSelectors.html b/Resources/Private/Partials/Permission/EditUserGroupSelectors.html index 3e9adb9..65c4dbc 100644 --- a/Resources/Private/Partials/Permission/EditUserGroupSelectors.html +++ b/Resources/Private/Partials/Permission/EditUserGroupSelectors.html @@ -1,9 +1,7 @@ - - - diff --git a/Resources/Private/Partials/Permission/GroupAclName.html b/Resources/Private/Partials/Permission/GroupAclName.html index 9c1248b..5c29973 100644 --- a/Resources/Private/Partials/Permission/GroupAclName.html +++ b/Resources/Private/Partials/Permission/GroupAclName.html @@ -17,4 +17,3 @@ - diff --git a/Resources/Private/Templates/Permission/Edit.html b/Resources/Private/Templates/Permission/Edit.html index 4ed9c1d..c15c16f 100644 --- a/Resources/Private/Templates/Permission/Edit.html +++ b/Resources/Private/Templates/Permission/Edit.html @@ -1,167 +1,161 @@ -{namespace be = TYPO3\CMS\Backend\ViewHelpers} -{namespace core = TYPO3\CMS\Core\ViewHelpers} +{namespace be=TYPO3\CMS\Backend\ViewHelpers} -

- : - -

+

+ : + +

- + + +
-
-
- - - - - - - - -
-
- - - - - - - - -
- -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
- - - - -
-
+
+
+ + +
+
+ + + + + + +
+
+
+
+
+ + +
+
-
- -
- - -
-
- - - - - +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
- +
+ + + + +
-
-

-

- :
- :
- :
- :
- : -

-

+ + + + + + + + + + + + + - +

+

+ :
+ :
+ :
+ :
+ : +

+

- - + /> +
diff --git a/Resources/Private/Templates/Permission/Index.html b/Resources/Private/Templates/Permission/Index.html index f1347f9..8ac356c 100644 --- a/Resources/Private/Templates/Permission/Index.html +++ b/Resources/Private/Templates/Permission/Index.html @@ -2,272 +2,271 @@ {namespace bu = TYPO3\CMS\Beuser\ViewHelpers} {namespace core = TYPO3\CMS\Core\ViewHelpers} {namespace ba = JBartels\BeAcl\ViewHelpers} - -

+

-
- - -
- -
-
- - -
-
-
- - -
-
-
-
-
-
+
+ + +
+ +
+
+ + +
+
+
+ + +
+
+
+
+
+
-
-
- - - - - - - - - - - - - + + + + + + + + + + + +
  - +
+ + + + + + + + + + + + + - - - - + + - - - - - - - - - A "normal" page row is rendered, not the root page - + /> + + + + + + + + + + + + + A "normal" page row is rendered, not the root page + - + - - - + + + /> + - + /> + - - - + + + - - - - - - + + + + + + - - - - - - + + + + + + - + - - - Root page row is rendered - - - - - - - - - - - - - -
  + - - + -
- - {data.depthData}{data.HTML} - {data.row.title -> f:format.crop(maxCharacters:20)} - - + + {data.depthData}{data.HTML} + {data.row.title -> f:format.crop(maxCharacters:20)} + + - - Edit link is workspace aware: If in ws, link to edit the ws overlay record is rendered - - - - - - - + + + + + - - - + + - - - + + + + class="editlock btn btn-default" + data-page="{data.row.uid}" + data-lockstate="1" + title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:EditLock_descr')}" + > + class="editlock btn btn-default" + data-page="{data.row.uid}" + data-lockstate="0" + title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:EditLock_descr2')}" + > -
-
-
- - - - -
+
+
+ + + + +
-
-
- - - - -
+
+
+ + + + + - {data.HTML} - {data.row.title -> f:format.crop(maxCharacters:20)} -
-
- + + + Root page row is rendered + +
+ {data.HTML} + {data.row.title -> f:format.crop(maxCharacters:20)} +
+
+
- {cshItem} + {cshItem} -

:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1:
2:
3:
4:
5:
-
-

-

-
- -

+

:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1:
2:
3:
4:
5:
+
+

+

+
+ +

diff --git a/Resources/Private/Templates/Permission/IndexA.html b/Resources/Private/Templates/Permission/IndexA.html new file mode 100644 index 0000000..b7d157d --- /dev/null +++ b/Resources/Private/Templates/Permission/IndexA.html @@ -0,0 +1,272 @@ +{namespace be = TYPO3\CMS\Backend\ViewHelpers} +{namespace bu = TYPO3\CMS\Beuser\ViewHelpers} +{namespace core = TYPO3\CMS\Core\ViewHelpers} +{namespace ba = JBartels\BeAcl\ViewHelpers} + + + +

+
+ + +
+ + +
+ +
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + A "normal" page row is rendered, not the root page + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Root page row is rendered + + + + + + + + + + + + + +
  + + + +
+ + {data.depthData}{data.HTML} + {data.row.title -> f:format.crop(maxCharacters:20)} + + + + Edit link is workspace aware: If in ws, link to edit the ws overlay record is rendered + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + +
+
+
+ + + + + + {data.HTML} + {data.row.title -> f:format.crop(maxCharacters:20)} +
+
+
+ + {cshItem} + +

:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1:
2:
3:
4:
5:
+
+

+

+
+ +

+
diff --git a/Resources/Public/JavaScript/AclPermissions.js b/Resources/Public/JavaScript/AclPermissions.js index 8e8a96c..2b38fcb 100644 --- a/Resources/Public/JavaScript/AclPermissions.js +++ b/Resources/Public/JavaScript/AclPermissions.js @@ -18,17 +18,17 @@ define(['jquery','TYPO3/CMS/Beuser/Permissions','TYPO3/CMS/Backend/Notification'], function($,Permissions,Notification) { var ajaxUrl = TYPO3.settings.ajaxUrls['user_access_permissions']; - + var AclPermissions = { options: { containerSelector: '#PermissionControllerEdit' } }; - + var newACLs = new Array(); var currentACLs = new Array(); var editAclRowTpl; - + AclPermissions.getEditAclRowTpl = function() { if(!editAclRowTpl) { editAclRowTpl = $('#tx_beacl-edit-acl-row-template').html(); @@ -49,14 +49,14 @@ define(['jquery','TYPO3/CMS/Beuser/Permissions','TYPO3/CMS/Backend/Notification' hiddenStore.setAttribute('name', name); hiddenFields.appendChild(hiddenStore); } - + /** * create new ACL ID */ AclPermissions.getNewId = function() { return 'NEW' + Math.round(Math.random()*10000000); } - + /** * add ACL */ @@ -66,16 +66,26 @@ define(['jquery','TYPO3/CMS/Beuser/Permissions','TYPO3/CMS/Backend/Notification' var ACLid = AclPermissions.getNewId(); // save ACL ID in the new ACLs array newACLs.push(ACLid); - // Create table row + // Create table row var tableRow = AclPermissions.getEditAclRowTpl().replace(/###uid###/g,ACLid); // append line to table $('#typo3-permissionMatrix tbody').append(tableRow); + $('#PermissionControllerEdit').append(AclPermissions.addHiddenInput(ACLid)); }; - + + AclPermissions.addHiddenInput = function (ACLid) { + return ''; + }; + + AclPermissions.removeHiddenInput = function (ACLid) { + let $hiddenInput = $('#PermissionControllerEdit').find('input[data-acluid="'+ ACLid +'"]'); + if($hiddenInput.length) $hiddenInput.remove(); + }; + AclPermissions.removeACL = function(id) { var $tableRow = $('#typo3-permissionMatrix tbody').find('tr[data-acluid="'+ id +'"]'); if($tableRow.length) $tableRow.remove(); - } + } /** * Group-related: Set the new group by executing an ajax call * @@ -85,12 +95,13 @@ define(['jquery','TYPO3/CMS/Beuser/Permissions','TYPO3/CMS/Backend/Notification' var $container = $(AclPermissions.options.containerSelector), pageID = $container.data('pageid'), id = $element.data('acluid'); - + // New ACL - simply remove ACL from table if(isNaN(id)) { AclPermissions.removeACL(id); + AclPermissions.removeHiddenInput(id); return; - } + } // Existing ACL - send delete request $.ajax({ url: ajaxUrl, @@ -105,6 +116,7 @@ define(['jquery','TYPO3/CMS/Beuser/Permissions','TYPO3/CMS/Backend/Notification' }).done(function(data) { // Remove from table AclPermissions.removeACL(id); + AclPermissions.removeHiddenInput(id); // Show notification var title = data.title || 'Success'; var msg = data.message || 'ACL deleted'; @@ -113,7 +125,7 @@ define(['jquery','TYPO3/CMS/Beuser/Permissions','TYPO3/CMS/Backend/Notification' Notification.error(null,error); }); }; - + /** * update user and group information * @@ -125,7 +137,7 @@ define(['jquery','TYPO3/CMS/Beuser/Permissions','TYPO3/CMS/Backend/Notification' var $container = $(AclPermissions.options.containerSelector), pageID = $container.data('pageid'), type = (typeVal == 1) ? 'group' : 'user'; - + // get child nodes of user/group selector var $selector = $('select[name=tx_beuser_system_beusertxpermission\\[data\\]\\[pages\\]\\['+pageID+'\\]\\[perms_'+type+'id\\]]'); diff --git a/composer.json b/composer.json index 9ea866a..92773d7 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "docs": "https://docs.typo3.org/typo3cms/extensions/be_acl/" }, "require": { - "typo3/cms-core": "^10.4" + "typo3/cms-core": "^11.5" }, "autoload": { "psr-4": { diff --git a/ext_emconf.php b/ext_emconf.php index b1c4e16..571b915 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -12,7 +12,7 @@ 'author_company' => '', 'constraints' => [ 'depends' => [ - 'typo3' => '10.4.0-10.4.99', + 'typo3' => '11.5.0-11.99.99', ], 'conflicts' => [ ], diff --git a/ext_localconf.php b/ext_localconf.php index 7be7deb..d07cfbb 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,72 +1,72 @@ get('be_acl'); + $extensionConfiguration = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( + \TYPO3\CMS\Core\Configuration\ExtensionConfiguration::class + )->get('be_acl'); - $isRedisEnabled = extension_loaded('redis') && $extensionConfiguration['enableRedis']; + $isRedisEnabled = extension_loaded('redis') && $extensionConfiguration['enableRedis']; - \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addUserTSConfig(' + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addUserTSConfig(' options.saveDocNew.tx_beacl_acl=1 '); - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['calcPerms'][] = - \JBartels\BeAcl\Utility\UserAuthGroup::class .'->calcPerms' - ; - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getPagePermsClause'][] = - \JBartels\BeAcl\Utility\UserAuthGroup::class .'->getPagePermsClause' - ; + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['calcPerms'][] = + \JBartels\BeAcl\Utility\UserAuthGroup::class .'->calcPerms' + ; + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getPagePermsClause'][] = + \JBartels\BeAcl\Utility\UserAuthGroup::class .'->getPagePermsClause' + ; - $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Beuser\Controller\PermissionController::class] = [ - 'className' => \JBartels\BeAcl\Controller\PermissionController::class, - ]; + $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Beuser\Controller\PermissionController::class] = [ + 'className' => \JBartels\BeAcl\Controller\PermissionController::class, + ]; - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = - \JBartels\BeAcl\Hook\DataHandlerHook::class - ; - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'][] = - \JBartels\BeAcl\Hook\DataHandlerHook::class - ; + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = + \JBartels\BeAcl\Hook\DataHandlerHook::class + ; + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'][] = + \JBartels\BeAcl\Hook\DataHandlerHook::class + ; - // set tx_be_acl_timestamp-cache - if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['frontend'])) { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['frontend'] = - 'TYPO3\\CMS\\Core\\Cache\\Frontend\\VariableFrontend' - ; - } - if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['backend'])) { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['backend'] = $isRedisEnabled - ? \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class - : \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend::class - ; - } + // set tx_be_acl_timestamp-cache + if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['frontend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['frontend'] = + 'TYPO3\\CMS\\Core\\Cache\\Frontend\\VariableFrontend' + ; + } + if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['backend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_timestamp']['backend'] = $isRedisEnabled + ? \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class + : \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend::class + ; + } - // set tx_be_acl_permissions-cache - if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['frontend'])) { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['frontend'] = - 'TYPO3\\CMS\\Core\\Cache\\Frontend\\VariableFrontend' - ; - } - if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['backend'])) { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['backend'] = $isRedisEnabled - ? \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class - : \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend::class - ; - } + // set tx_be_acl_permissions-cache + if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['frontend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['frontend'] = + 'TYPO3\\CMS\\Core\\Cache\\Frontend\\VariableFrontend' + ; + } + if (! isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['backend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_be_acl_permissions']['backend'] = $isRedisEnabled + ? \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class + : \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend::class + ; + } - $iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class); - $iconRegistry->registerIcon( - 'tx_beacl-object-info', - \TYPO3\CMS\Core\Imaging\IconProvider\FontawesomeIconProvider::class, - [ - 'name' => 'info' - ] - ); + $iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class); + $iconRegistry->registerIcon( + 'tx_beacl-object-info', + \TYPO3\CMS\Core\Imaging\IconProvider\FontawesomeIconProvider::class, + [ + 'name' => 'info' + ] + ); });