[TASK] Refactor ext:beuser access module 46/36246/9
authorChristian Kuhn <lolli@schwarzbu.ch>
Thu, 22 Jan 2015 20:55:33 +0000 (21:55 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sun, 25 Jan 2015 20:49:04 +0000 (21:49 +0100)
* Move most rendering from PermissionController and
  PermissionAjaxController to fluid
* PermissionController no longer calls methods from
  PermissionAjaxController
* PermissionController no longer loops over the result
  set of getTree() in indexAction to prepare view data
* Fix a couple of minor edge cases and bugs, especially
  some missing labels
* Deprecate some now unused public methods in
  PermissionAjaxController

Even with additional fluid rendering, the module is about
20% quicker with applied patch rendering longish tree lists,
mostly by suppressing tons of calls to the sprite icon API.

Change-Id: Ib3104d147270bc0ccf65f73773baed2a31418953
Resolves: #64489
Releases: master
Reviewed-on: http://review.typo3.org/36246
Reviewed-by: Philipp Gampe <philipp.gampe@typo3.org>
Tested-by: Philipp Gampe <philipp.gampe@typo3.org>
Reviewed-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Tested-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
12 files changed:
typo3/sysext/beuser/Classes/Controller/PermissionAjaxController.php
typo3/sysext/beuser/Classes/Controller/PermissionController.php
typo3/sysext/beuser/Classes/Exception.php [new file with mode: 0644]
typo3/sysext/beuser/Classes/ViewHelpers/ArrayElementViewHelper.php [new file with mode: 0644]
typo3/sysext/beuser/Classes/ViewHelpers/PermissionsViewHelper.php [new file with mode: 0644]
typo3/sysext/beuser/Resources/Private/Language/locallang_mod_permission.xlf
typo3/sysext/beuser/Resources/Private/Partials/Permission/Groupname.html [new file with mode: 0644]
typo3/sysext/beuser/Resources/Private/Partials/Permission/Ownername.html [new file with mode: 0644]
typo3/sysext/beuser/Resources/Private/Templates/Permission/Index.html
typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangeGroup.html [new file with mode: 0644]
typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangeOwner.html [new file with mode: 0644]
typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangePermission.html [new file with mode: 0644]

index 9de8870..65a44a7 100644 (file)
@@ -16,8 +16,11 @@ namespace TYPO3\CMS\Beuser\Controller;
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Backend\Utility\IconUtility;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Http\AjaxRequestHandler;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Fluid\View\StandaloneView;
 
 /**
  * This class extends the permissions module in the TYPO3 Backend to provide
@@ -50,14 +53,8 @@ class PermissionAjaxController {
                $this->conf['groupUid'] = (int)GeneralUtility::_POST('groupUid');
                $this->conf['groupname'] = GeneralUtility::_POST('groupname');
                $this->conf['editLockState'] = (int)GeneralUtility::_POST('editLockState');
-               // User: Replace some parts of the posted values
                $this->conf['new_owner_uid'] = (int)GeneralUtility::_POST('newOwnerUid');
-               $temp_owner_data = BackendUtility::getUserNames('username, uid', ' AND uid = ' . $this->conf['new_owner_uid']);
-               $this->conf['new_owner_username'] = htmlspecialchars($temp_owner_data[$this->conf['new_owner_uid']]['username']);
-               // Group: Replace some parts of the posted values
                $this->conf['new_group_uid'] = (int)GeneralUtility::_POST('newGroupUid');
-               $temp_group_data = BackendUtility::getGroupNames('title,uid', ' AND uid = ' . $this->conf['new_group_uid']);
-               $this->conf['new_group_username'] = htmlspecialchars($temp_group_data[$this->conf['new_group_uid']]['title']);
        }
 
        /**
@@ -68,12 +65,18 @@ class PermissionAjaxController {
         * @return void
         */
        public function dispatch($params = array(), AjaxRequestHandler $ajaxObj = NULL) {
+               $extPath = ExtensionManagementUtility::extPath('beuser');
+
+               $view = GeneralUtility::makeInstance(StandaloneView::class);
+               $view->setPartialRootPaths(array('default' => ExtensionManagementUtility::extPath('beuser') . 'Resources/Private/Partials'));
+               $view->assign('pageId', $this->conf['page']);
+
                $content = '';
                // Basic test for required value
                if ($this->conf['page'] > 0) {
                        // Init TCE for execution of update
-                       /** @var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */
-                       $tce = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
+                       /** @var $tce DataHandler */
+                       $tce = GeneralUtility::makeInstance(DataHandler::class);
                        $tce->stripslashes_values = 1;
                        // Determine the scripts to execute
                        switch ($this->conf['action']) {
@@ -81,14 +84,20 @@ class PermissionAjaxController {
                                        $content = $this->renderUserSelector($this->conf['page'], $this->conf['ownerUid'], $this->conf['username']);
                                        break;
                                case 'change_owner':
-                                       if (is_int($this->conf['new_owner_uid'])) {
+                                       $userId = $this->conf['new_owner_uid'];
+                                       if (is_int($userId)) {
                                                // Prepare data to change
                                                $data = array();
-                                               $data['pages'][$this->conf['page']]['perms_userid'] = $this->conf['new_owner_uid'];
+                                               $data['pages'][$this->conf['page']]['perms_userid'] = $userId;
                                                // Execute TCE Update
                                                $tce->start($data, array());
                                                $tce->process_datamap();
-                                               $content = self::renderOwnername($this->conf['page'], $this->conf['new_owner_uid'], $this->conf['new_owner_username']);
+
+                                               $view->setTemplatePathAndFilename($extPath . 'Resources/Private/Templates/PermissionAjax/ChangeOwner.html');
+                                               $view->assign('userId', $userId);
+                                               $usernameArray = BackendUtility::getUserNames('username', ' AND uid = ' . $userId);
+                                               $view->assign('username', $usernameArray[$userId]['username']);
+                                               $content = $view->render();
                                        } else {
                                                $ajaxObj->setError('An error occurred: No page owner uid specified.');
                                        }
@@ -97,14 +106,20 @@ class PermissionAjaxController {
                                        $content = $this->renderGroupSelector($this->conf['page'], $this->conf['groupUid'], $this->conf['groupname']);
                                        break;
                                case 'change_group':
-                                       if (is_int($this->conf['new_group_uid'])) {
+                                       $groupId = $this->conf['new_group_uid'];
+                                       if (is_int($groupId)) {
                                                // Prepare data to change
                                                $data = array();
-                                               $data['pages'][$this->conf['page']]['perms_groupid'] = $this->conf['new_group_uid'];
+                                               $data['pages'][$this->conf['page']]['perms_groupid'] = $groupId;
                                                // Execute TCE Update
                                                $tce->start($data, array());
                                                $tce->process_datamap();
-                                               $content = self::renderGroupname($this->conf['page'], $this->conf['new_group_uid'], $this->conf['new_group_username']);
+
+                                               $view->setTemplatePathAndFilename($extPath . 'Resources/Private/Templates/PermissionAjax/ChangeGroup.html');
+                                               $view->assign('groupId', $groupId);
+                                               $groupnameArray = BackendUtility::getGroupNames('title', ' AND uid = ' . $groupId);
+                                               $view->assign('groupname', $groupnameArray[$groupId]['title']);
+                                               $content = $view->render();
                                        } else {
                                                $ajaxObj->setError('An error occurred: No page group uid specified.');
                                        }
@@ -130,7 +145,11 @@ class PermissionAjaxController {
                                        // Execute TCE Update
                                        $tce->start($data, array());
                                        $tce->process_datamap();
-                                       $content = self::renderPermissions($this->conf['permissions'], $this->conf['page'], $this->conf['who']);
+
+                                       $view->setTemplatePathAndFilename($extPath . 'Resources/Private/Templates/PermissionAjax/ChangePermission.html');
+                                       $view->assign('permission', $this->conf['permissions']);
+                                       $view->assign('scope', $this->conf['who']);
+                                       $content = $view->render();
                        }
                } else {
                        $ajaxObj->setError('This script cannot be called directly.');
@@ -149,11 +168,6 @@ class PermissionAjaxController {
        protected function renderUserSelector($page, $ownerUid, $username = '') {
                // Get usernames
                $beUsers = BackendUtility::getUserNames();
-               // Init groupArray
-               $groups = array();
-               if (!$GLOBALS['BE_USER']->isAdmin()) {
-                       $beUsers = BackendUtility::blindUserNames($beUsers, $groups, 1);
-               }
                // Owner selector:
                $options = '';
                // Loop through the users
@@ -174,17 +188,12 @@ class PermissionAjaxController {
         *
         * @param int $page The page id to change the user for
         * @param int $groupUid The page group uid
-        * @param string $username The username to display
+        * @param string $groupname The groupname to display
         * @return string The html select element
         */
        protected function renderGroupSelector($page, $groupUid, $groupname = '') {
                // Get usernames
-               $beGroups = BackendUtility::getListGroupNames('title,uid');
-               $beGroupKeys = array_keys($beGroups);
-               $beGroupsO = ($beGroups = BackendUtility::getGroupNames());
-               if (!$this->getBackendUser()->isAdmin()) {
-                       $beGroups = BackendUtility::blindGroupNames($beGroupsO, $beGroupKeys, 1);
-               }
+               $beGroupsO = $beGroups = BackendUtility::getGroupNames();
                // Group selector:
                $options = '';
                // flag: is set if the page-groupid equals one from the group-list
@@ -220,8 +229,10 @@ class PermissionAjaxController {
         * @param string $username The TYPO3 BE username (used to display in the element)
         * @param bool $validUser Must be set to FALSE, if the user has no name or is deleted
         * @return string The new group wrapped in HTML
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. This is now solved with fluid.
         */
        static public function renderOwnername($page, $ownerUid, $username, $validUser = TRUE) {
+               GeneralUtility::logDeprecatedFunction();
                $elementId = 'o_' . $page;
                return '<span id="' . $elementId . '"><a class="ug_selector changeowner" data-page="' . $page . '" data-owner="' . $ownerUid . '" data-username="' . htmlspecialchars($username) . '">' . ($validUser ? ($username == '' ? '<span class=not_set>[' . $GLOBALS['LANG']->getLL('notSet') . ']</span>' : htmlspecialchars(GeneralUtility::fixed_lgd_cs($username, 20))) : '<span class=not_set title="' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($username, 20)) . '">[' . $GLOBALS['LANG']->getLL('deleted') . ']</span>') . '</a></span>';
        }
@@ -234,8 +245,10 @@ class PermissionAjaxController {
         * @param string $groupname The TYPO3 BE groupname (used to display in the element)
         * @param bool $validGroup Must be set to FALSE, if the group has no name or is deleted
         * @return string The new group wrapped in HTML
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. This is now solved with fluid.
         */
        static public function renderGroupname($page, $groupUid, $groupname, $validGroup = TRUE) {
+               GeneralUtility::logDeprecatedFunction();
                $elementId = 'g_' . $page;
                return '<span id="' . $elementId . '"><a class="ug_selector changegroup" data-page="' . $page . '" data-group="' . $groupUid . '" data-groupname="' . htmlspecialchars($groupname) . '">' . ($validGroup ? ($groupname == '' ? '<span class=not_set>[' . $GLOBALS['LANG']->getLL('notSet') . ']</span>' : htmlspecialchars(GeneralUtility::fixed_lgd_cs($groupname, 20))) : '<span class=not_set title="' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($groupname, 20)) . '">[' . $GLOBALS['LANG']->getLL('deleted') . ']</span>') . '</a></span>';
        }
@@ -244,7 +257,7 @@ class PermissionAjaxController {
         * Print the string with the new edit lock state of a page record
         *
         * @param int $page The TYPO3 page id
-        * @param string $editlockstate The state of the TYPO3 page (locked, unlocked)
+        * @param string $editLockState The state of the TYPO3 page (locked, unlocked)
         * @return string The new edit lock string wrapped in HTML
         */
        protected function renderToggleEditLock($page, $editLockState) {
@@ -260,11 +273,13 @@ class PermissionAjaxController {
         * Print a set of permissions. Also used in index.php
         *
         * @param int $int Permission integer (bits)
-        * @param int $page The TYPO3 page id
+        * @param int $pageId The TYPO3 page id
         * @param string $who The scope (user, group or everybody)
         * @return string HTML marked up x/* indications.
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. This is now solved with fluid.
         */
        static public function renderPermissions($int, $pageId = 0, $who = 'user') {
+               GeneralUtility::logDeprecatedFunction();
                $str = '';
                $permissions = array(1, 16, 2, 4, 8);
                foreach ($permissions as $permission) {
index 17f8639..3d613fa 100644 (file)
@@ -14,23 +14,18 @@ namespace TYPO3\CMS\Beuser\Controller;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Backend\Template\DocumentTemplate;
 use TYPO3\CMS\Backend\Tree\View\PageTreeView;
 use TYPO3\CMS\Backend\Utility\IconUtility;
 use TYPO3\CMS\Core\Database\DatabaseConnection;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
-use TYPO3\CMS\Version\View\VersionView;
 
 /**
  * Backend module page permissions
- *
- * @author Frank Nägler <typo3@naegler.net>
  */
 class PermissionController extends ActionController {
 
@@ -122,7 +117,6 @@ class PermissionController extends ActionController {
                        $this->pageInfo = array('title' => '[root-level]', 'uid' => 0, 'pid' => 0);
                }
 
-               $this->view->assign('versionSelector', $this->getVersionSelector($this->id, TRUE));
                if ($this->getBackendUser()->workspace != 0) {
                        // Adding section with the permission setting matrix:
                        $this->addFlashMessage(
@@ -147,7 +141,9 @@ class PermissionController extends ActionController {
                $this->view->assign('depthOptions', $depthOptions);
 
                $beUserArray = BackendUtility::getUserNames();
+               $this->view->assign('beUsers', $beUserArray);
                $beGroupArray = BackendUtility::getGroupNames();
+               $this->view->assign('beGroups', $beGroupArray);
 
                /** @var PageTreeView */
                $tree = GeneralUtility::makeInstance(PageTreeView::class);
@@ -167,78 +163,9 @@ class PermissionController extends ActionController {
                $html = IconUtility::getSpriteIconForRecord('pages', $this->pageInfo);
                $tree->tree[] = array('row' => $this->pageInfo, 'HTML' => $html);
 
-               // Create the tree from $this->id:
+               // Create the tree from $this->id
                $tree->getTree($this->id, $this->depth, '');
-
-               // Traverse tree:
-               $treeData = array();
-               foreach ($tree->tree as $data) {
-                       $viewDataRow = array();
-                       $pageId = $data['row']['uid'];
-                       $viewData['pageId'] = $pageId;
-
-                       // User/Group names:
-                       if ($beUserArray[$data['row']['perms_userid']]) {
-                               $userName = $beUserArray[$data['row']['perms_userid']]['username'];
-                       } else {
-                               $userName = ($data['row']['perms_userid'] ? $data['row']['perms_userid'] : '');
-                       }
-
-                       if ($data['row']['perms_userid'] && !$beUserArray[$data['row']['perms_userid']]) {
-                               $userName = PermissionAjaxController::renderOwnername(
-                                       $pageId,
-                                       $data['row']['perms_userid'],
-                                       htmlspecialchars(GeneralUtility::fixed_lgd_cs($userName, 20)),
-                                       FALSE
-                               );
-                       } else {
-                               $userName = PermissionAjaxController::renderOwnername(
-                                       $pageId,
-                                       $data['row']['perms_userid'],
-                                       htmlspecialchars(GeneralUtility::fixed_lgd_cs($userName, 20))
-                               );
-                       }
-                       $viewDataRow['userName'] = $userName;
-
-                       if ($beGroupArray[$data['row']['perms_groupid']]) {
-                               $groupName = $beGroupArray[$data['row']['perms_groupid']]['title'];
-                       } else {
-                               $groupName = $data['row']['perms_groupid'] ? $data['row']['perms_groupid'] : '';
-                       }
-
-                       if ($data['row']['perms_groupid'] && !$beGroupArray[$data['row']['perms_groupid']]) {
-                               $groupName = PermissionAjaxController::renderGroupname(
-                                       $pageId,
-                                       $data['row']['perms_groupid'],
-                                       htmlspecialchars(GeneralUtility::fixed_lgd_cs($groupName, 20)),
-                                       FALSE
-                               );
-                       } else {
-                               $groupName = PermissionAjaxController::renderGroupname(
-                                       $pageId, $data['row']['perms_groupid'],
-                                       htmlspecialchars(GeneralUtility::fixed_lgd_cs($groupName, 20))
-                               );
-                       }
-                       $viewDataRow['groupName'] = $groupName;
-
-                       $viewData['html'] = $this->getControllerDocumentTemplate()->wrapClickMenuOnIcon($data['HTML'], 'pages', $data['row']['uid'])
-                               . htmlspecialchars(GeneralUtility::fixed_lgd_cs($data['row']['title'], 20));
-                       $viewData['id'] = $data['row']['_ORIG_uid'] ? $data['row']['_ORIG_uid'] : $pageId;
-
-                       $viewData['userPermissions'] = ($pageId ?
-                               PermissionAjaxController::renderPermissions($data['row']['perms_user'], $pageId, 'user') .
-                               ' ' . $userName : '');
-                       $viewData['groupPermissions'] = ($pageId ?
-                               PermissionAjaxController::renderPermissions($data['row']['perms_group'], $pageId, 'group') .
-                               ' ' . $groupName : '');
-                       $viewData['otherPermissions'] = ($pageId ? ' ' .
-                               PermissionAjaxController::renderPermissions($data['row']['perms_everybody'], $pageId, 'everybody') : '');
-
-                       $viewData['editLock'] = ($data['row']['editlock']) ? TRUE : FALSE;
-
-                       $treeData[] = $viewData;
-               }
-               $this->view->assign('viewTree', $treeData);
+               $this->view->assign('viewTree', $tree->tree);
 
                // CSH for permissions setting
                $this->view->assign('cshItem', BackendUtility::cshItem('xMOD_csh_corebe', 'perm_module', $GLOBALS['BACK_PATH']));
@@ -342,13 +269,6 @@ class PermissionController extends ActionController {
        }
 
        /**
-        * @return DocumentTemplate
-        */
-       protected function getControllerDocumentTemplate() {
-               return $GLOBALS['TBE_TEMPLATE'];
-       }
-
-       /**
         * Finding tree and offer setting of values recursively.
         *
         * @return array
@@ -387,23 +307,4 @@ class PermissionController extends ActionController {
                return $options;
        }
 
-       /**
-        * Creates the version selector for the page id inputted.
-        * Requires the core version management extension, "version" to be loaded.
-        *
-        * @param int $id Page id to create selector for.
-        * @param bool $noAction If set, there will be no button for swapping page.
-        * @return string
-        */
-       protected function getVersionSelector($id, $noAction = FALSE) {
-               if (
-                       ExtensionManagementUtility::isLoaded('version') &&
-                       !ExtensionManagementUtility::isLoaded('workspaces')
-               ) {
-                       $versionView = GeneralUtility::makeInstance(VersionView::class);
-                       return $versionView->getVersionSelector($id, $noAction);
-               }
-               return '';
-       }
-
 }
diff --git a/typo3/sysext/beuser/Classes/Exception.php b/typo3/sysext/beuser/Classes/Exception.php
new file mode 100644 (file)
index 0000000..c1b45a0
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace TYPO3\CMS\Beuser;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Generic Beuser exception
+ */
+class Exception extends \Exception {
+
+}
\ No newline at end of file
diff --git a/typo3/sysext/beuser/Classes/ViewHelpers/ArrayElementViewHelper.php b/typo3/sysext/beuser/Classes/ViewHelpers/ArrayElementViewHelper.php
new file mode 100644 (file)
index 0000000..abf89be
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+namespace TYPO3\CMS\Beuser\ViewHelpers;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Get a value from an array by given key.
+ */
+class ArrayElementViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
+
+       /**
+        * Return array element by key. Acessed values must be scalar (string, int, float or double)
+        *
+        * @param array $array Array to search in
+        * @param string $key Key to return its value
+        * @param string $subKey If result of key access is an array, subkey can be used to fetch an element from this again
+        * @throws \TYPO3\CMS\Beuser\Exception
+        * @return string
+        */
+       public function render(array $array, $key, $subKey = '') {
+               $result = '';
+               if (is_array($array) && isset($array[$key])) {
+                       $result = $array[$key];
+                       if (is_array($result) && $subKey && isset($result[$subKey])) {
+                               $result = $result[$subKey];
+                       }
+               }
+               if (!is_scalar($result)) {
+                       throw new \TYPO3\CMS\Beuser\Exception(
+                               'Only scalar return values (string, int, float or double) are supported.',
+                               1382284105
+                       );
+               }
+               return $result;
+       }
+
+}
diff --git a/typo3/sysext/beuser/Classes/ViewHelpers/PermissionsViewHelper.php b/typo3/sysext/beuser/Classes/ViewHelpers/PermissionsViewHelper.php
new file mode 100644 (file)
index 0000000..35e918f
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+namespace TYPO3\CMS\Beuser\ViewHelpers;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Utility\IconUtility;
+use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
+use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
+use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
+use TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface;
+
+/**
+ * Render permission icon group (user / group / others) of the "Access" module.
+ *
+ * Most of that could be done in fluid directly, but this view helper
+ * is much better performance wise.
+ */
+class PermissionsViewHelper extends AbstractViewHelper implements CompilableInterface {
+
+       /**
+        * @var string Cached Css classes for a "granted" icon
+        */
+       static protected $grantedCssClasses = '';
+
+       /**
+        * @var string Cached Css classes for a "denied" icon
+        */
+       static protected $deniedCssClasses = '';
+
+       /**
+        * @var array Cached labels for a single permission mask like "Delete page"
+        */
+       static protected $permissionLabels = array();
+
+       /**
+        * Return permissions.
+        *
+        * @param integer $permission Current permission
+        * @param string $scope "user" / "group" / "everybody"
+        * @param integer $pageId
+        * @return string
+        */
+       public function render($permission, $scope, $pageId) {
+               return static::renderStatic($this->arguments, $this->buildRenderChildrenClosure(), $this->renderingContext);
+       }
+
+       /**
+        * Implementing CompilableInterface suppresses object instantiation of this view helper
+        *
+        * @param array $arguments
+        * @param \Closure $renderChildrenClosure
+        * @param RenderingContextInterface $renderingContext
+        * @return string
+        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
+        */
+       static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
+               // The two main icon classes are static during one call. They trigger relatively expensive
+               // calculation with a signal and object creation and thus make sense to have them cached.
+               if (!static::$grantedCssClasses) {
+                       static::$grantedCssClasses = IconUtility::getSpriteIconClasses('status-status-permission-granted');
+               }
+               if (!static::$deniedCssClasses) {
+                       static::$deniedCssClasses = IconUtility::getSpriteIconClasses('status-status-permission-denied');
+               }
+
+               $masks = array(1, 16, 2, 4, 8);
+
+               if (empty(static::$permissionLabels)) {
+                       foreach ($masks as $mask) {
+                               static::$permissionLabels[$mask] = LocalizationUtility::translate(
+                                       'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:' . $mask,
+                                       'be_user'
+                               );
+                       }
+               }
+
+               $icon = '';
+               foreach ($masks as $mask) {
+                       if ($arguments['permission'] & $mask) {
+                               $icon .= '<span' .
+                                       ' title="' . static::$permissionLabels[$mask] . '"' .
+                                       ' class="' . static::$grantedCssClasses . ' change-permission text-success"' .
+                                       ' data-page="' . $arguments['pageId'] . '"' .
+                                       ' data-permissions="' . $arguments['permission'] . '"' .
+                                       ' data-mode="delete"' .
+                                       ' data-who="' . $arguments['scope'] . '"' .
+                                       ' data-bits="' . $mask . '"' .
+                                       ' style="cursor:pointer"' .
+                               '></span>';
+                       } else {
+                               $icon .= '<span' .
+                                       ' title="' . static::$permissionLabels[$mask] . '"' .
+                                       ' class="' . static::$deniedCssClasses . ' change-permission text-danger"' .
+                                       ' data-page="' . $arguments['pageId'] . '"' .
+                                       ' data-permissions="' . $arguments['permission'] . '"' .
+                                       ' data-mode="add"' .
+                                       ' data-who="' . $arguments['scope'] . '"' .
+                                       ' data-bits="' . $mask . '"' .
+                                       ' style="cursor:pointer"' .
+                               '></span>';
+                       }
+               }
+
+               return '<span id="' . $arguments['pageId'] . '_' . $arguments['scope'] . '">' . $icon . '</span>';
+       }
+
+}
index 262e970..19a9c76 100644 (file)
@@ -27,6 +27,9 @@
                        <trans-unit id="EditLock_descr" xml:space="preserve">
                                <source>The page and all content is locked for editing by all non-Admin users.</source>
                        </trans-unit>
+                       <trans-unit id="EditLock_descr2" xml:space="preserve">
+                               <source>Enable the »Admin-only« edit lock for this page</source>
+                       </trans-unit>
                        <trans-unit id="Save" xml:space="preserve">
                                <source>Save</source>
                        </trans-unit>
diff --git a/typo3/sysext/beuser/Resources/Private/Partials/Permission/Groupname.html b/typo3/sysext/beuser/Resources/Private/Partials/Permission/Groupname.html
new file mode 100644 (file)
index 0000000..9842cbd
--- /dev/null
@@ -0,0 +1,37 @@
+<span id="g_{pageId}">
+       <a
+               class="ug_selector changegroup"
+               data-page="{pageId}"
+               data-owner="{groupId}"
+               data-username="{groupname}"
+       >
+               <f:if condition="{groupId} == 0">
+                       <f:then>
+                               <f:comment>
+                                       No group set -> [not set]
+                               </f:comment>
+                               <span class="not_set">
+                                       [<f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:notSet" />]
+                               </span>
+                       </f:then>
+                       <f:else>
+                               <f:if condition="{groupname}">
+                                       <f:then>
+                                               <f:comment>
+                                                       A group name can be resolved
+                                               </f:comment>
+                                               {groupname -> f:format.crop(maxCharacters:20)}
+                                       </f:then>
+                                       <f:else>
+                                               <f:comment>
+                                                       Group was deleted -> [deleted]
+                                               </f:comment>
+                                               <span class="not_set" title="{groupId}">
+                                                       [<f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:deleted" />]
+                                               </span>
+                                       </f:else>
+                               </f:if>
+                       </f:else>
+               </f:if>
+       </a>
+</span>
diff --git a/typo3/sysext/beuser/Resources/Private/Partials/Permission/Ownername.html b/typo3/sysext/beuser/Resources/Private/Partials/Permission/Ownername.html
new file mode 100644 (file)
index 0000000..576002b
--- /dev/null
@@ -0,0 +1,37 @@
+<span id="o_{pageId}">
+       <a
+               class="ug_selector changeowner"
+               data-page="{pageId}"
+               data-owner="{userId}"
+               data-username="{username}"
+       >
+               <f:if condition="{userId} == 0">
+                       <f:then>
+                               <f:comment>
+                                       No owner set -> [not set]
+                               </f:comment>
+                               <span class="not_set">
+                                       [<f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:notSet" />]
+                               </span>
+                       </f:then>
+                       <f:else>
+                               <f:if condition="{username}">
+                                       <f:then>
+                                               <f:comment>
+                                                       A user name can be resolved
+                                               </f:comment>
+                                               {username -> f:format.crop(maxCharacters:20)}
+                                       </f:then>
+                                       <f:else>
+                                               <f:comment>
+                                                       User was deleted -> [deleted]
+                                               </f:comment>
+                                               <span class="not_set" title="{userId}">
+                                                       [<f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:deleted" />]
+                                               </span>
+                                       </f:else>
+                               </f:if>
+                       </f:else>
+               </f:if>
+       </a>
+</span>
index 52d0db0..00fa5c1 100644 (file)
                                </thead>
                                <f:for each="{viewTree}" as="data">
                                        <tr>
-                                               <f:if condition="{data.cellAttrib}">
+                                               <f:if condition="{data.row.uid}">
                                                        <f:then>
-                                                               <td align="left" nowrap="nowrap" {data.cellAttrib}>
-                                                                       <f:format.raw>{data.html}</f:format.raw>
+                                                               <f:comment>
+                                                                       A "normal" page row is rendered, not the root page
+                                                               </f:comment>
+
+                                                               <td align="left" nowrap="nowrap">
+                                                                       <a
+                                                                               href="#"
+                                                                               class="t3-js-clickmenutrigger"
+                                                                               data-table="pages"
+                                                                               data-uid="{data.row.uid}"
+                                                                               data-listfr="1"
+                                                                       >
+                                                                               <f:format.raw>{data.HTML}</f:format.raw>
+                                                                               {data.row.title -> f:format.crop(maxCharacters:20)}
+                                                                       </a>
+                                                               </td>
+
+                                                               <td>
+                                                                       <f:comment>
+                                                                               Edit link is workspace aware: If in ws, link to edit the ws overlay record is rendered
+                                                                       </f:comment>
+                                                                       <f:if condition="{data.row._ORIG_uid}">
+                                                                               <f:then>
+                                                                                       <f:link.action
+                                                                                               action="edit"
+                                                                                               arguments="{id: data.row._ORIG_uid, depth: depth}"
+                                                                                               title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:ch_permissions')}"
+                                                                                       >
+                                                                                               <bu:spriteManagerIcon iconName="actions-document-open" />
+                                                                                       </f:link.action>
+                                                                               </f:then>
+                                                                               <f:else>
+                                                                                       <f:link.action
+                                                                                               action="edit"
+                                                                                               arguments="{id: data.row.uid, depth: depth}"
+                                                                                               title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:ch_permissions')}"
+                                                                                       >
+                                                                                               <bu:spriteManagerIcon iconName="actions-document-open" />
+                                                                                       </f:link.action>
+                                                                               </f:else>
+                                                                       </f:if>
+                                                               </td>
+
+                                                               <td nowrap="nowrap">
+                                                                       <bu:permissions permission="{data.row.perms_user}" scope="user" pageId="{data.row.uid}" />
+                                                                       <f:render
+                                                                               partial="Permission/Ownername"
+                                                                               arguments="{
+                                                                                       pageId: '{data.row.uid}',
+                                                                                       userId: '{data.row.perms_userid}',
+                                                                                       username: '{bu:arrayElement(array:beUsers, key:data.row.perms_userid, subKey:\'username\')}'
+                                                                               }"
+                                                                       />
+                                                               </td>
+
+                                                               <td nowrap="nowrap">
+                                                                       <bu:permissions permission="{data.row.perms_group}" scope="group" pageId="{data.row.uid}" />
+                                                                       <f:render
+                                                                               partial="Permission/Groupname"
+                                                                               arguments="{
+                                                                                       pageId: '{data.row.uid}',
+                                                                                       groupId: '{data.row.perms_groupid}',
+                                                                                       groupname: '{bu:arrayElement(array:beGroups, key:data.row.perms_groupid, subKey:\'title\')}'
+                                                                               }"
+                                                                       />
+                                                               </td>
+
+                                                               <td nowrap="nowrap">
+                                                                       <bu:permissions permission="{data.row.perms_everybody}" scope="everybody" pageId="{data.row.uid}" />
+                                                               </td>
+
+                                                               <td nowrap="nowrap">
+                                                                       <span id="el_{data.row.uid}">
+                                                                               <f:if condition="{data.row.editlock}">
+                                                                                       <f:then>
+                                                                                               <a
+                                                                                                       class="editlock"
+                                                                                                       data-page="{data.row.uid}"
+                                                                                                       data-lockstate="1"
+                                                                                                       title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:EditLock_descr')}"
+                                                                                               >
+                                                                                                       <bu:spriteManagerIcon iconName="status-warning-lock" />
+                                                                                               </a>
+                                                                                       </f:then>
+                                                                                       <f:else>
+                                                                                               <a
+                                                                                                       class="editlock"
+                                                                                                       data-page="{data.row.uid}"
+                                                                                                       data-lockstate="0"
+                                                                                                       title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:EditLock_descr2')}"
+                                                                                               >
+                                                                                                       [+]
+                                                                                               </a>
+                                                                                       </f:else>
+                                                                               </f:if>
+                                                                       </span>
                                                                </td>
                                                        </f:then>
+
                                                        <f:else>
-                                                               <td align="left" nowrap="nowrap" {data.groupName}>
-                                                                       <f:format.raw>{data.html}</f:format.raw>
+                                                               <f:comment>
+                                                                       Root page row is rendered
+                                                               </f:comment>
+                                                               <td align="left" nowrap="nowrap">
+                                                                       <f:format.raw>{data.HTML}</f:format.raw>
+                                                                       {data.row.title -> f:format.crop(maxCharacters:20)}
                                                                </td>
+                                                               <td></td>
+                                                               <td nowrap="nowrap"></td>
+                                                               <td nowrap="nowrap"></td>
+                                                               <td nowrap="nowrap"></td>
+                                                               <td nowrap="nowrap"></td>
                                                        </f:else>
                                                </f:if>
-                                               <td>
-                                                       <f:if condition="{data.id} > 0">
-                                                               <f:link.action action="edit" arguments="{id: data.id, depth: depth}" title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:ch_permissions')}">
-                                                                       <bu:spriteManagerIcon iconName="actions-document-open" />
-                                                               </f:link.action>
-                                                       </f:if>
-                                               </td>
-                                               <td nowrap="nowrap"><f:format.raw>{data.userPermissions}</f:format.raw></td>
-                                               <td nowrap="nowrap"><f:format.raw>{data.groupPermissions}</f:format.raw></td>
-                                               <td nowrap="nowrap"><f:format.raw>{data.otherPermissions}</f:format.raw></td>
-                                               <td nowrap="nowrap">
-                                               <f:if condition="{data.id} > 0">
-                                                       <span id="el_{data.id}">
-                                                               <f:if condition="{data.editLock}">
-                                                                       <f:then>
-                                                                               <a class="editlock" data-page="{data.pageId}" data-lockstate="1" title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:EditLock_descr')}">
-                                                                                       <bu:spriteManagerIcon iconName="status-warning-lock" />
-                                                                               </a>
-                                                                       </f:then>
-                                                                       <f:else>
-                                                                               <a class="editlock" data-page="{data.pageId}" data-lockstate="0" title="Enable the &raquo;Admin-only&laquo; edit lock for this page">
-                                                                                       [+]
-                                                                               </a>
-                                                                       </f:else>
-                                                               </f:if>
-                                                       </span>
-                                               </f:if>
                                        </tr>
                                </f:for>
                        </table>
diff --git a/typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangeGroup.html b/typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangeGroup.html
new file mode 100644 (file)
index 0000000..6165036
--- /dev/null
@@ -0,0 +1,8 @@
+<f:render
+       partial="Permission/Groupname"
+       arguments="{
+               pageId: '{pageId}',
+               groupId: '{groupId}',
+               groupname: '{groupname}'
+       }"
+/>
diff --git a/typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangeOwner.html b/typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangeOwner.html
new file mode 100644 (file)
index 0000000..1a3b6b1
--- /dev/null
@@ -0,0 +1,8 @@
+<f:render
+       partial="Permission/Ownername"
+       arguments="{
+               pageId: '{pageId}',
+               userId: '{userId}',
+               username: '{username}'
+       }"
+/>
diff --git a/typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangePermission.html b/typo3/sysext/beuser/Resources/Private/Templates/PermissionAjax/ChangePermission.html
new file mode 100644 (file)
index 0000000..bbc70e0
--- /dev/null
@@ -0,0 +1,2 @@
+{namespace bu = TYPO3\CMS\Beuser\ViewHelpers}
+<bu:permissions permission="{permission}" scope="{scope}" pageId="{pageId}" />
\ No newline at end of file