[BUGFIX] Apply restrictions for default language in context menu 15/62915/3
authorDaniel Goerz <daniel.goerz@posteo.de>
Wed, 15 Jan 2020 14:13:11 +0000 (15:13 +0100)
committerSusanne Moog <look@susi.dev>
Thu, 16 Jan 2020 09:25:07 +0000 (10:25 +0100)
Editors without access to the default language can no longer
see those options in the context menu for page records that
would lead to error messages due to missing language access.

Additionally the list menu doc header and edit button for
translated pages in the list menu are adapted to respect
missing access rights to the default language as well.

Resolves: #75130
Releases: master, 9.5
Change-Id: I686d29a90ed0ee428f9c2eeb68815f4122705de3
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/62915
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Henning Liebe <h.liebe@neusta.de>
Tested-by: Sascha Rademacher <sascha.rademacher+typo3@gmail.com>
Tested-by: Susanne Moog <look@susi.dev>
Reviewed-by: Henning Liebe <h.liebe@neusta.de>
Reviewed-by: Sascha Rademacher <sascha.rademacher+typo3@gmail.com>
Reviewed-by: Felix P. <f.pachowsky@neusta.de>
Reviewed-by: Susanne Moog <look@susi.dev>
typo3/sysext/backend/Classes/ContextMenu/ItemProviders/PageProvider.php
typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php

index 0ecb82b..d7eba58 100644 (file)
@@ -166,6 +166,11 @@ class PageProvider extends RecordProvider
     ];
 
     /**
+     * @var bool
+     */
+    protected $languageAccess = false;
+
+    /**
      * Checks if the provider can add items to the menu
      *
      * @return bool
@@ -270,6 +275,7 @@ class PageProvider extends RecordProvider
     protected function initPermissions()
     {
         $this->pagePermissions = $this->backendUser->calcPerms($this->record);
+        $this->languageAccess = $this->hasLanguageAccess();
     }
 
     /**
@@ -279,6 +285,9 @@ class PageProvider extends RecordProvider
      */
     protected function canBeCreated(): bool
     {
+        if (!$this->backendUser->checkLanguageAccess(0)) {
+            return false;
+        }
         return $this->hasPagePermission(Permission::PAGE_NEW);
     }
 
@@ -289,6 +298,9 @@ class PageProvider extends RecordProvider
      */
     protected function canBeEdited(): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
         if ($this->isRoot()) {
             return false;
         }
@@ -321,6 +333,14 @@ class PageProvider extends RecordProvider
      */
     protected function canBeCut(): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
+        if (isset($GLOBALS['TCA'][$this->table]['ctrl']['languageField'])
+            && !in_array($this->record[$GLOBALS['TCA'][$this->table]['ctrl']['languageField']], [0, -1])
+        ) {
+            return false;
+        }
         return !$this->isWebMount()
             && $this->canBeEdited()
             && !$this->isDeletePlaceholder();
@@ -333,6 +353,14 @@ class PageProvider extends RecordProvider
      */
     protected function canBeCopied(): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
+        if (isset($GLOBALS['TCA'][$this->table]['ctrl']['languageField'])
+            && !in_array($this->record[$GLOBALS['TCA'][$this->table]['ctrl']['languageField']], [0, -1])
+        ) {
+            return false;
+        }
         return !$this->isRoot()
             && !$this->isWebMount()
             && !$this->isRecordInClipboard('copy')
@@ -347,6 +375,9 @@ class PageProvider extends RecordProvider
      */
     protected function canBePastedInto(): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
         $clipboardElementCount = count($this->clipboard->elFromTable($this->table));
 
         return $clipboardElementCount
@@ -361,6 +392,9 @@ class PageProvider extends RecordProvider
      */
     protected function canBePastedAfter(): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
         $clipboardElementCount = count($this->clipboard->elFromTable($this->table));
         return $clipboardElementCount
             && $this->canBeCreated()
@@ -374,6 +408,9 @@ class PageProvider extends RecordProvider
      */
     protected function canBeSorted(): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
         return $this->backendUser->check('tables_modify', $this->table)
             && $this->hasPagePermission(Permission::CONTENT_EDIT)
             && !$this->isDeletePlaceholder()
@@ -387,6 +424,9 @@ class PageProvider extends RecordProvider
      */
     protected function canBeDeleted(): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
         return !$this->isDeletePlaceholder()
             && !$this->isRecordLocked()
             && !$this->isDeletionDisabledInTS()
@@ -536,6 +576,9 @@ class PageProvider extends RecordProvider
      */
     protected function canBeToggled(string $fieldName, int $value): bool
     {
+        if (!$this->languageAccess) {
+            return false;
+        }
         if (!empty($GLOBALS['TCA'][$this->table]['columns'][$fieldName]['exclude'])
             && $this->record['doktype'] <= PageRepository::DOKTYPE_SPACER
             && $this->backendUser->check('non_exclude_fields', $this->table . ':' . $fieldName)
@@ -544,4 +587,22 @@ class PageProvider extends RecordProvider
         }
         return false;
     }
+
+    /**
+     * Returns true if a current user has access to the language of the record
+     *
+     * @see BackendUserAuthentication::checkLanguageAccess()
+     * @return bool
+     */
+    protected function hasLanguageAccess(): bool
+    {
+        if ($this->backendUser->isAdmin()) {
+            return true;
+        }
+        $languageField = $GLOBALS['TCA'][$this->table]['ctrl']['languageField'] ?? '';
+        if ($languageField !== '' && isset($this->record[$languageField])) {
+            return $this->backendUser->checkLanguageAccess((int)$this->record[$languageField]);
+        }
+        return true;
+    }
 }
index 17f85cc..22709fe 100644 (file)
@@ -660,7 +660,7 @@ class DatabaseRecordList
             }
             // If edit permissions are set, see
             // \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
-            if ($localCalcPerms & Permission::PAGE_EDIT && !empty($this->id) && $this->editLockPermissions()) {
+            if ($localCalcPerms & Permission::PAGE_EDIT && !empty($this->id) && $this->editLockPermissions() && $backendUser->checkLanguageAccess(0)) {
                 // Edit
                 $params = '&edit[pages][' . $this->pageRow['uid'] . ']=edit';
                 $editLink = $this->uriBuilder->buildUriFromRoute('record_edit') . $params . $this->makeReturnUrl();
@@ -1817,7 +1817,7 @@ class DatabaseRecordList
             $localCalcPerms = $backendUser->calcPerms(BackendUtility::getRecord('pages', $row['pid']));
         }
         $permsEdit = $table === 'pages'
-                     && $backendUser->checkLanguageAccess(0)
+                     && $backendUser->checkLanguageAccess((int)$row[$GLOBALS['TCA']['pages']['ctrl']['languageField']])
                      && $localCalcPerms & Permission::PAGE_EDIT
                      || $table !== 'pages'
                         && $localCalcPerms & Permission::CONTENT_EDIT