[BUGFIX] Respect editlock in the UI of list & page module 64/41564/4
authorGeorg Ringer <georg.ringer@gmail.com>
Fri, 17 Jul 2015 12:18:04 +0000 (14:18 +0200)
committerAndreas Wolf <andreas.wolf@typo3.org>
Sat, 18 Jul 2015 13:12:17 +0000 (15:12 +0200)
If editlock is set in the page record, the icons to modify the records
need to be hidden.

Not touched with this patch are JS parts like the drag'n'drop and
inline editing of the page title.

Change-Id: Ie4434ee3a74b1d5427eef7fbd121738d4ccfd6df
Resolves: #68279
Releases: master
Reviewed-on: http://review.typo3.org/41564
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Markus Sommer <markussom@posteo.de>
Tested-by: Markus Sommer <markussom@posteo.de>
Reviewed-by: Andreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf <andreas.wolf@typo3.org>
typo3/sysext/backend/Classes/Controller/PageLayoutController.php
typo3/sysext/backend/Classes/View/PageLayoutView.php
typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php

index cb74ce0..bcd9474 100755 (executable)
@@ -500,7 +500,8 @@ class PageLayoutController {
                if ($this->id && $access) {
                        // Initialize permission settings:
                        $this->CALC_PERMS = $this->getBackendUser()->calcPerms($this->pageinfo);
-                       $this->EDIT_CONTENT = $this->CALC_PERMS & Permission::CONTENT_EDIT ? 1 : 0;
+                       $this->EDIT_CONTENT = $this->pageIsNotLockedForEditors();
+
                        // Start document template object:
                        $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
                        $this->doc->backPath = $GLOBALS['BACK_PATH'];
@@ -1143,7 +1144,7 @@ class PageLayoutController {
                        }
 
                        // Edit page properties and page language overlay icons
-                       if ($this->CALC_PERMS & Permission::PAGE_EDIT) {
+                       if ($this->pageIsNotLockedForEditors()) {
 
                                // Edit localized page_language_overlay only when one specific language is selected
                                if ($this->MOD_SETTINGS['function'] == 1 && $this->current_sys_language > 0) {
@@ -1296,6 +1297,15 @@ class PageLayoutController {
        }
 
        /**
+        * Check the editlock access
+        *
+        * @return bool
+        */
+       public function pageIsNotLockedForEditors() {
+               return !($this->pageinfo['editlock'] && ($this->CALC_PERMS & Permission::PAGE_EDIT));
+       }
+
+       /**
         * Returns LanguageService
         *
         * @return \TYPO3\CMS\Lang\LanguageService
index 0a7cc42..bbeec54 100644 (file)
@@ -440,15 +440,19 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                                }
                                $content[$key] .= '">';
                                // Add new content at the top most position
+                               $link = '';
+                               if ($this->getPageLayoutController()->pageIsNotLockedForEditors()) {
+                                       $link = '<a href="#" onclick="' . htmlspecialchars($this->newContentElementOnClick($id, $key, $lP))
+                                               . '" title="' . $this->getLanguageService()->getLL('newContentElement', TRUE) . '" class="btn btn-default btn-sm">'
+                                               . IconUtility::getSpriteIcon('actions-document-new')
+                                               . ' '
+                                               . $this->getLanguageService()->getLL('content', TRUE) . '</a>';
+                               }
                                $content[$key] .= '
                                <div class="t3-page-ce t3js-page-ce" data-page="' . (int)$id . '" id="' . str_replace('.', '', uniqid('', TRUE)) . '">
-                                       <div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-' . $key . '-' . 'page-' . $id . '-' . uniqid('', TRUE) . '">
-                                               <a href="#" onclick="' . htmlspecialchars($this->newContentElementOnClick($id, $key, $lP))
-                                                       . '" title="' . $this->getLanguageService()->getLL('newContentElement', TRUE) . '" class="btn btn-default btn-sm">'
-                                                       . IconUtility::getSpriteIcon('actions-document-new')
-                                                       . ' '
-                                                       . $this->getLanguageService()->getLL('content', TRUE) . '</a>
-                                       </div>
+                                       <div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-' . $key . '-' . 'page-' . $id . '-' . uniqid('', TRUE) . '">'
+                                               . $link
+                                       . '</div>
                                        <div class="t3-page-ce-dropzone-available t3js-page-ce-dropzone-available"></div>
                                </div>
                                ';
@@ -498,7 +502,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                                                $singleElementHTML .= '<div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-' . $key . '-' . 'page-' . $id .
                                                        '-' . str_replace('.', '', uniqid('', TRUE)) . '">';
                                                // Add icon "new content element below"
-                                               if (!$disableMoveAndNewButtons) {
+                                               if (!$disableMoveAndNewButtons && $this->getPageLayoutController()->pageIsNotLockedForEditors()) {
                                                        // New content element:
                                                        if ($this->option_newWizard) {
                                                                $onClick = 'window.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('new_content_element') . '&id=' . $row['pid']
index f283c0d..c48247a 100644 (file)
@@ -404,11 +404,10 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
                        $selectFields = array_merge($selectFields, $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']);
                }
-               if ($GLOBALS['TCA'][$table]['ctrl']['type']) {
-                       $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['type'];
-               }
-               if ($GLOBALS['TCA'][$table]['ctrl']['typeicon_column']) {
-                       $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
+               foreach(array('type', 'typeicon_column', 'editlock') as $field) {
+                       if ($GLOBALS['TCA'][$table]['ctrl'][$field]) {
+                               $selectFields[] = $GLOBALS['TCA'][$table]['ctrl'][$field];
+                       }
                }
                if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
                        $selectFields[] = 't3ver_id';
@@ -1197,8 +1196,8 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                if ($table == 'pages') {
                        $localCalcPerms = $this->getBackendUserAuthentication()->calcPerms(BackendUtility::getRecord('pages', $row['uid']));
                }
-               // This expresses the edit permissions for this particular element:
                $permsEdit = $table === 'pages' && $localCalcPerms & Permission::PAGE_EDIT || $table !== 'pages' && $this->calcPerms & Permission::CONTENT_EDIT;
+               $permsEdit = $this->overlayEditLockPermissions($table, $row, $permsEdit);
                // "Show" link (only pages and tt_content elements)
                if ($table == 'pages' || $table == 'tt_content') {
                        $viewAction = '<a class="btn btn-default" href="#" onclick="'
@@ -1219,15 +1218,17 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                        $spriteIcon = (!$this->isEditable($table) ? 'actions-document-open-read-only' : 'actions-document-open');
                        $editAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick($params, '', -1))
                                . '" title="' . $this->getLanguageService()->getLL('edit', TRUE) . '">' . IconUtility::getSpriteIcon($spriteIcon) . '</a>';
-                       $this->addActionToCellGroup($cells, $editAction, 'edit');
+               } else {
+                       $editAction = $this->spaceIcon;
                }
+               $this->addActionToCellGroup($cells, $editAction, 'edit');
                // "Info": (All records)
                $onClick = 'top.launchView(\'' . $table . '\', \'' . $row['uid'] . '\'); return false;';
                $viewBigAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $this->getLanguageService()->getLL('showInfo', TRUE) . '">'
                        . IconUtility::getSpriteIcon('actions-document-info') . '</a>';
                $this->addActionToCellGroup($cells, $viewBigAction, 'viewBig');
                // "Move" wizard link for pages/tt_content elements:
-               if ($table === 'tt_content' && $permsEdit || $table === 'pages') {
+               if ($permsEdit && ($table === 'tt_content' || $table === 'pages')) {
                        $onClick = 'return jumpExt(\'' . $this->backPath . BackendUtility::getModuleUrl('move_element') . '&table=' . $table . '&uid=' . $row['uid'] . '\');';
                        $linkTitleLL = $this->getLanguageService()->getLL('move_' . ($table === 'tt_content' ? 'record' : 'page'), TRUE);
                        $spriteIcon = $table === 'tt_content' ? 'actions-document-move' : 'actions-page-move';
@@ -1310,13 +1311,14 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                        }
                        // "Hide/Unhide" links:
                        $hiddenField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
+
                        if (
                                $permsEdit && $hiddenField && $GLOBALS['TCA'][$table]['columns'][$hiddenField]
                                && (!$GLOBALS['TCA'][$table]['columns'][$hiddenField]['exclude']
                                        || $this->getBackendUserAuthentication()->check('non_exclude_fields', $table . ':' . $hiddenField))
                        ) {
                                if ($this->isRecordCurrentBackendUser($table, $row)) {
-                                       $hideAction = '<span class="btn btn-default disabled">' . IconUtility::getSpriteIcon('empty-empty') . '</span>';
+                                       $hideAction = $this->spaceIcon;
                                } else {
                                        if ($row[$hiddenField]) {
                                                $params = 'data[' . $table . '][' . $rowUid . '][' . $hiddenField . ']=0';
@@ -1335,7 +1337,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                $this->addActionToCellGroup($cells, $hideAction, 'hide');
                        }
                        // "Delete" link:
-                       if ($table === 'pages' && $localCalcPerms & Permission::PAGE_DELETE || $table !== 'pages' && $this->calcPerms & Permission::CONTENT_EDIT) {
+                       if ($permsEdit && ($table === 'pages' && $localCalcPerms & Permission::PAGE_DELETE || $table !== 'pages' && $this->calcPerms & Permission::CONTENT_EDIT)) {
                                // Check if the record version is in "deleted" state, because that will switch the action to "restore"
                                if ($this->getBackendUserAuthentication()->workspace > 0 && isset($row['t3ver_state']) && (int)$row['t3ver_state'] === 2) {
                                        $actionName = 'restore';
@@ -1352,7 +1354,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                }
 
                                if ($this->isRecordCurrentBackendUser($table, $row)) {
-                                       $deleteAction = '<span class="btn btn-default disabled">' . IconUtility::getSpriteIcon('empty-empty') . '</span>';
+                                       $deleteAction = $this->spaceIcon;
                                } else {
                                        $titleOrig = BackendUtility::getRecordTitle($table, $row, FALSE, TRUE);
                                        $title = GeneralUtility::slashJS(GeneralUtility::fixed_lgd_cs($titleOrig, $this->fixedL), TRUE);
@@ -1367,8 +1369,10 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                                                        . ' data-message="' . htmlspecialchars($warningText) . '" title="' . $linkTitle . '"'
                                                                        . '>' . $icon . '</a>';
                                }
-                               $this->addActionToCellGroup($cells, $deleteAction, 'delete');
+                       } else {
+                               $deleteAction = $this->spaceIcon;
                        }
+                       $this->addActionToCellGroup($cells, $deleteAction, 'delete');
                        // "Levels" links: Moving pages into new levels...
                        if ($permsEdit && $table == 'pages' && !$this->searchLevels) {
                                // Up (Paste as the page right after the current parent page)
@@ -1483,7 +1487,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                if ($this->clipObj->current == 'normal') {
                        // Show copy/cut icons:
                        $isSel = (string)$this->clipObj->isSelected($table, $row['uid']);
-                       if ($isL10nOverlay) {
+                       if ($isL10nOverlay || !$this->overlayEditLockPermissions($table, $row)) {
                                $cells['copy'] = $this->spaceIcon;
                                $cells['cut'] = $this->spaceIcon;
                        } else {
@@ -1491,10 +1495,14 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                        . htmlspecialchars('return jumpSelf(\'' . $this->clipObj->selUrlDB($table, $row['uid'], 1, ($isSel == 'copy'), array('returnUrl' => '')) . '\');')
                                        . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.copy', TRUE) . '">'
                                        . (!$isSel == 'copy' ? IconUtility::getSpriteIcon('actions-edit-copy') : IconUtility::getSpriteIcon('actions-edit-copy-release')) . '</a>';
-                               $cells['cut'] = '<a class="btn btn-default" href="#" onclick="'
-                                       . htmlspecialchars('return jumpSelf(\'' . $this->clipObj->selUrlDB($table, $row['uid'], 0, ($isSel == 'cut'), array('returnUrl' => '')) . '\');')
-                                       . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.cut', TRUE) . '">'
-                                       . (!$isSel == 'cut' ? IconUtility::getSpriteIcon('actions-edit-cut') : IconUtility::getSpriteIcon('actions-edit-cut-release')) . '</a>';
+                               if (TRUE) {
+                                       $cells['cut'] = '<a class="btn btn-default" href="#" onclick="'
+                                               . htmlspecialchars('return jumpSelf(\'' . $this->clipObj->selUrlDB($table, $row['uid'], 0, ($isSel == 'cut'), array('returnUrl' => '')) . '\');')
+                                               . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.cut', TRUE) . '">'
+                                               . (!$isSel == 'cut' ? IconUtility::getSpriteIcon('actions-edit-cut') : IconUtility::getSpriteIcon('actions-edit-cut-release')) . '</a>';
+                               } else {
+                                       $cells['cut'] = $this->spaceIcon;
+                               }
                        }
                } else {
                        // For the numeric clipboard pads (showing checkboxes where one can select elements on/off)
@@ -1925,6 +1933,25 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
        }
 
        /**
+        * Check if the current record is locked by editlock
+        *
+        * @param string $table
+        * @param array $row
+        * @param bool $editPermission
+        * @return bool
+        */
+       protected function overlayEditLockPermissions($table, $row, $editPermission = TRUE) {
+               if ($editPermission) {
+                       if (($table === 'pages' && $row['editlock']) || ($table !== 'pages' && $this->pageRow['editlock'])) {
+                               $editPermission = FALSE;
+                       } elseif (isset($GLOBALS['TCA'][$table]['ctrl']['editlock']) && $row[$GLOBALS['TCA'][$table]['ctrl']['editlock']]) {
+                               $editPermission = FALSE;
+                       }
+               }
+               return $editPermission;
+       }
+
+       /**
         * @return DatabaseConnection
         */
        protected function getDatabaseConnection() {
@@ -1945,4 +1972,4 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                return $GLOBALS['TBE_TEMPLATE'];
        }
 
-}
+}
\ No newline at end of file