[TASK] Cleanup workspaces backend AJAX calls 72/56872/2
authorBenni Mack <benni@typo3.org>
Sun, 6 May 2018 14:24:07 +0000 (16:24 +0200)
committerBenni Mack <benni@typo3.org>
Sun, 6 May 2018 14:59:32 +0000 (16:59 +0200)
The AJAX endpoints for the workspaces backend module
on the PHP side still are 1:1 like the good old ExtJS times.

In order to abstract and separate concerns in this area,
and make the AJAX-based endpoints true PSR-7 compliant
requests and responses, some cleanups are necessary.

In this first step, the AbstractHandler is removed,
as some methods can be removed or simplified in the
child classes.

Resolves: #84937
Releases: master
Change-Id: If390d4b51d19059b18f579691371669c27a337d4
Reviewed-on: https://review.typo3.org/56872
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
typo3/sysext/workspaces/Classes/Controller/AjaxDispatcher.php
typo3/sysext/workspaces/Classes/Controller/Remote/AbstractHandler.php [deleted file]
typo3/sysext/workspaces/Classes/Controller/Remote/ActionHandler.php
typo3/sysext/workspaces/Classes/Controller/Remote/MassActionHandler.php
typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php
typo3/sysext/workspaces/Classes/Service/StagesService.php

index 53697fa..41eb963 100644 (file)
@@ -67,7 +67,6 @@ class AjaxDispatcher
     {
         $tmp = new \stdClass();
         $tmp->action = $call->action;
-        $tmp->debug = '';
         $tmp->method = $call->method;
         $tmp->result = $responseFromMethod;
         $tmp->tid = $call->tid;
diff --git a/typo3/sysext/workspaces/Classes/Controller/Remote/AbstractHandler.php b/typo3/sysext/workspaces/Classes/Controller/Remote/AbstractHandler.php
deleted file mode 100644 (file)
index 0284c29..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-<?php
-namespace TYPO3\CMS\Workspaces\Controller\Remote;
-
-/*
- * 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\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\MathUtility;
-use TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord;
-use TYPO3\CMS\Workspaces\Service\IntegrityService;
-use TYPO3\CMS\Workspaces\Service\WorkspaceService;
-
-/**
- * Class AbstractHandler
- */
-abstract class AbstractHandler
-{
-    /**
-     * Gets the current workspace ID.
-     *
-     * @return int The current workspace ID
-     */
-    protected function getCurrentWorkspace()
-    {
-        return $this->getWorkspaceService()->getCurrentWorkspace();
-    }
-
-    /**
-     * Gets an error response to be shown in the grid component.
-     *
-     * @param string $errorLabel Name of the label in the locallang.xlf file
-     * @param int $errorCode The error code to be used
-     * @param bool $successFlagValue Value of the success flag to be delivered back (might be FALSE in most cases)
-     * @return array
-     */
-    protected function getErrorResponse($errorLabel, $errorCode = 0, $successFlagValue = false)
-    {
-        $localLangFile = 'LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf';
-        $response = [
-            'error' => [
-                'code' => $errorCode,
-                'message' => $GLOBALS['LANG']->sL($localLangFile . ':' . $errorLabel)
-            ],
-            'success' => $successFlagValue
-        ];
-        return $response;
-    }
-
-    /**
-     * Gets an instance of the workspaces service.
-     *
-     * @return WorkspaceService
-     */
-    protected function getWorkspaceService()
-    {
-        return GeneralUtility::makeInstance(WorkspaceService::class);
-    }
-
-    /**
-     * Validates whether the submitted language parameter can be
-     * interpreted as integer value.
-     *
-     * @param stdClass $parameters
-     * @return int|null
-     */
-    protected function validateLanguageParameter(\stdClass $parameters)
-    {
-        $language = null;
-        if (isset($parameters->language) && MathUtility::canBeInterpretedAsInteger($parameters->language)) {
-            $language = $parameters->language;
-        }
-        return $language;
-    }
-
-    /**
-     * Gets affected elements on publishing/swapping actions.
-     * Affected elements have a dependency, e.g. translation overlay
-     * and the default origin record - thus, the default record would be
-     * affected if the translation overlay shall be published.
-     *
-     * @param stdClass $parameters
-     * @return array
-     */
-    protected function getAffectedElements(\stdClass $parameters)
-    {
-        $affectedElements = [];
-        if ($parameters->type === 'selection') {
-            foreach ((array)$parameters->selection as $element) {
-                $affectedElements[] = CombinedRecord::create($element->table, $element->liveId, $element->versionId);
-            }
-        } elseif ($parameters->type === 'all') {
-            $versions = $this->getWorkspaceService()->selectVersionsInWorkspace($this->getCurrentWorkspace(), 0, -99, -1, 0, 'tables_select', $this->validateLanguageParameter($parameters));
-            foreach ($versions as $table => $tableElements) {
-                foreach ($tableElements as $element) {
-                    $affectedElement = CombinedRecord::create($table, $element['t3ver_oid'], $element['uid']);
-                    $affectedElement->getVersionRecord()->setRow($element);
-                    $affectedElements[] = $affectedElement;
-                }
-            }
-        }
-        return $affectedElements;
-    }
-
-    /**
-     * Creates a new instance of the integrity service for the
-     * given set of affected elements.
-     *
-     * @param CombinedRecord[] $affectedElements
-     * @return IntegrityService
-     * @see getAffectedElements
-     */
-    protected function createIntegrityService(array $affectedElements)
-    {
-        $integrityService = GeneralUtility::makeInstance(IntegrityService::class);
-        $integrityService->setAffectedElements($affectedElements);
-        return $integrityService;
-    }
-}
index cec3676..f701abb 100644 (file)
@@ -18,6 +18,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Exception;
+use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
@@ -30,7 +31,7 @@ use TYPO3\CMS\Workspaces\Service\WorkspaceService;
 /**
  * Class ActionHandler
  */
-class ActionHandler extends AbstractHandler
+class ActionHandler
 {
     /**
      * @var StagesService
@@ -38,11 +39,17 @@ class ActionHandler extends AbstractHandler
     protected $stageService;
 
     /**
+     * @var WorkspaceService
+     */
+    protected $workspaceService;
+
+    /**
      * Creates this object.
      */
     public function __construct()
     {
         $this->stageService = GeneralUtility::makeInstance(StagesService::class);
+        $this->workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
     }
 
     /**
@@ -53,7 +60,7 @@ class ActionHandler extends AbstractHandler
      */
     public function generateWorkspacePreviewLink($uid)
     {
-        return $this->getWorkspaceService()->generateWorkspacePreviewLink($uid);
+        return $this->workspaceService->generateWorkspacePreviewLink($uid);
     }
 
     /**
@@ -64,7 +71,7 @@ class ActionHandler extends AbstractHandler
      */
     public function generateWorkspacePreviewLinksForAllLanguages($uid)
     {
-        return $this->getWorkspaceService()->generateWorkspacePreviewLinksForAllLanguages($uid);
+        return $this->workspaceService->generateWorkspacePreviewLinksForAllLanguages($uid);
     }
 
     /**
@@ -201,14 +208,14 @@ class ActionHandler extends AbstractHandler
                 'hidden' => $column->hidden
             ];
         }
-        $GLOBALS['BE_USER']->uc['moduleData']['Workspaces'][$GLOBALS['BE_USER']->workspace]['columns'] = $data;
-        $GLOBALS['BE_USER']->writeUC();
+        $this->getBackendUser()->uc['moduleData']['Workspaces'][$this->getBackendUser()->workspace]['columns'] = $data;
+        $this->getBackendUser()->writeUC();
     }
 
     public function loadColumnModel()
     {
-        if (is_array($GLOBALS['BE_USER']->uc['moduleData']['Workspaces'][$GLOBALS['BE_USER']->workspace]['columns'])) {
-            return $GLOBALS['BE_USER']->uc['moduleData']['Workspaces'][$GLOBALS['BE_USER']->workspace]['columns'];
+        if (is_array($this->getBackendUser()->uc['moduleData']['Workspaces'][$this->getBackendUser()->workspace]['columns'])) {
+            return $this->getBackendUser()->uc['moduleData']['Workspaces'][$this->getBackendUser()->workspace]['columns'];
         }
         return [];
     }
@@ -223,8 +230,8 @@ class ActionHandler extends AbstractHandler
         if (MathUtility::canBeInterpretedAsInteger($language) === false && $language !== 'all') {
             $language = 'all';
         }
-        $GLOBALS['BE_USER']->uc['moduleData']['Workspaces'][$GLOBALS['BE_USER']->workspace]['language'] = $language;
-        $GLOBALS['BE_USER']->writeUC();
+        $this->getBackendUser()->uc['moduleData']['Workspaces'][$this->getBackendUser()->workspace]['language'] = $language;
+        $this->getBackendUser()->writeUC();
     }
 
     /**
@@ -342,7 +349,7 @@ class ActionHandler extends AbstractHandler
 
         if ($stageRecord === null) {
             throw new \InvalidArgumentException(
-                $GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:error.stageId.integer'),
+                $this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:error.stageId.integer'),
                 1476044776
             );
         }
@@ -872,4 +879,43 @@ class ActionHandler extends AbstractHandler
     {
         return $GLOBALS['BE_USER'];
     }
+
+    /**
+     * @return LanguageService
+     */
+    protected function getLanguageService()
+    {
+        return $GLOBALS['LANG'];
+    }
+
+    /**
+     * Gets an error response to be shown in the grid component.
+     *
+     * @param string $errorLabel Name of the label in the locallang.xlf file
+     * @param int $errorCode The error code to be used
+     * @param bool $successFlagValue Value of the success flag to be delivered back (might be FALSE in most cases)
+     * @return array
+     */
+    protected function getErrorResponse($errorLabel, $errorCode = 0, $successFlagValue = false)
+    {
+        $localLangFile = 'LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf';
+        $response = [
+            'error' => [
+                'code' => $errorCode,
+                'message' => $this->getLanguageService()->sL($localLangFile . ':' . $errorLabel)
+            ],
+            'success' => $successFlagValue
+        ];
+        return $response;
+    }
+
+    /**
+     * Gets the current workspace ID.
+     *
+     * @return int The current workspace ID
+     */
+    protected function getCurrentWorkspace()
+    {
+        return $this->workspaceService->getCurrentWorkspace();
+    }
 }
index 8cc3fb6..c767c53 100644 (file)
@@ -14,13 +14,17 @@ namespace TYPO3\CMS\Workspaces\Controller\Remote;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Workspaces\Service\WorkspaceService;
 
 /**
- * Class MassActionHandler
  * Class encapsulates all actions which are triggered for all elements within the current workspace.
  */
-class MassActionHandler extends AbstractHandler
+class MassActionHandler
 {
     const MAX_RECORDS_TO_PROCESS = 30;
 
@@ -32,27 +36,36 @@ class MassActionHandler extends AbstractHandler
     private $pathToLocallang = 'LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf';
 
     /**
+     * @var WorkspaceService
+     */
+    protected $workspaceService;
+
+    public function __construct()
+    {
+        $this->workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
+    }
+
+    /**
      * Get list of available mass workspace actions.
      *
-     * @param \stdClass $parameter
      * @return array $data
      */
-    public function getMassStageActions($parameter)
+    public function getMassStageActions()
     {
         $actions = [];
         $currentWorkspace = $this->getCurrentWorkspace();
-        $massActionsEnabled = $GLOBALS['BE_USER']->getTSConfigVal('options.workspaces.enableMassActions') !== '0';
+        $massActionsEnabled = $this->getBackendUser()->getTSConfigVal('options.workspaces.enableMassActions') !== '0';
         // in case we're working within "All Workspaces" we can't provide Mass Actions
         if ($currentWorkspace != WorkspaceService::SELECT_ALL_WORKSPACES && $massActionsEnabled) {
-            $publishAccess = $GLOBALS['BE_USER']->workspacePublishAccess($currentWorkspace);
-            if ($publishAccess && !($GLOBALS['BE_USER']->workspaceRec['publish_access'] & 1)) {
-                $actions[] = ['action' => 'publish', 'title' => $GLOBALS['LANG']->sL($this->pathToLocallang . ':label_doaction_publish')];
-                if ($GLOBALS['BE_USER']->workspaceSwapAccess()) {
-                    $actions[] = ['action' => 'swap', 'title' => $GLOBALS['LANG']->sL($this->pathToLocallang . ':label_doaction_swap')];
+            $publishAccess = $this->getBackendUser()->workspacePublishAccess($currentWorkspace);
+            if ($publishAccess && !($this->getBackendUser()->workspaceRec['publish_access'] & 1)) {
+                $actions[] = ['action' => 'publish', 'title' => $this->getLanguageService()->sL($this->pathToLocallang . ':label_doaction_publish')];
+                if ($this->getBackendUser()->workspaceSwapAccess()) {
+                    $actions[] = ['action' => 'swap', 'title' => $this->getLanguageService()->sL($this->pathToLocallang . ':label_doaction_swap')];
                 }
             }
             if ($currentWorkspace !== WorkspaceService::LIVE_WORKSPACE_ID) {
-                $actions[] = ['action' => 'discard', 'title' => $GLOBALS['LANG']->sL($this->pathToLocallang . ':label_doaction_discard')];
+                $actions[] = ['action' => 'discard', 'title' => $this->getLanguageService()->sL($this->pathToLocallang . ':label_doaction_discard')];
             }
         }
         $result = [
@@ -82,8 +95,8 @@ class MassActionHandler extends AbstractHandler
                 $cnt = $this->initPublishData($this->getCurrentWorkspace(), $parameters->swap, $language);
                 $result['total'] = $cnt;
             } else {
-                $result['processed'] = $this->processData($this->getCurrentWorkspace());
-                $result['total'] = $GLOBALS['BE_USER']->getSessionData('workspaceMassAction_total');
+                $result['processed'] = $this->processData();
+                $result['total'] = $this->getBackendUser()->getSessionData('workspaceMassAction_total');
             }
         } catch (\Exception $e) {
             $result['error'] = $e->getMessage();
@@ -108,11 +121,10 @@ class MassActionHandler extends AbstractHandler
         try {
             if ($parameters->init) {
                 $language = $this->validateLanguageParameter($parameters);
-                $cnt = $this->initFlushData($this->getCurrentWorkspace(), $language);
-                $result['total'] = $cnt;
+                $result['total'] = $this->initFlushData($this->getCurrentWorkspace(), $language);
             } else {
-                $result['processed'] = $this->processData($this->getCurrentWorkspace());
-                $result['total'] = $GLOBALS['BE_USER']->getSessionData('workspaceMassAction_total');
+                $result['processed'] = $this->processData();
+                $result['total'] = $this->getBackendUser()->getSessionData('workspaceMassAction_total');
             }
         } catch (\Exception $e) {
             $result['error'] = $e->getMessage();
@@ -131,15 +143,15 @@ class MassActionHandler extends AbstractHandler
     protected function initPublishData($workspace, $swap, $language = null)
     {
         // workspace might be -98 a.k.a "All Workspaces but that's save here
-        $publishData = $this->getWorkspaceService()->getCmdArrayForPublishWS($workspace, $swap, 0, $language);
+        $publishData = $this->workspaceService->getCmdArrayForPublishWS($workspace, $swap, 0, $language);
         $recordCount = 0;
         foreach ($publishData as $table => $recs) {
             $recordCount += count($recs);
         }
         if ($recordCount > 0) {
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction', $publishData);
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction_total', $recordCount);
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction_processed', 0);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction', $publishData);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction_total', $recordCount);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction_processed', 0);
         }
         return $recordCount;
     }
@@ -154,15 +166,15 @@ class MassActionHandler extends AbstractHandler
     protected function initFlushData($workspace, $language = null)
     {
         // workspace might be -98 a.k.a "All Workspaces but that's save here
-        $flushData = $this->getWorkspaceService()->getCmdArrayForFlushWS($workspace, true, 0, $language);
+        $flushData = $this->workspaceService->getCmdArrayForFlushWS($workspace, true, 0, $language);
         $recordCount = 0;
         foreach ($flushData as $table => $recs) {
             $recordCount += count($recs);
         }
         if ($recordCount > 0) {
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction', $flushData);
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction_total', $recordCount);
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction_processed', 0);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction', $flushData);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction_total', $recordCount);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction_processed', 0);
         }
         return $recordCount;
     }
@@ -170,13 +182,12 @@ class MassActionHandler extends AbstractHandler
     /**
      * Processes the data.
      *
-     * @param int $workspace
      * @return int
      */
-    protected function processData($workspace)
+    protected function processData()
     {
-        $processData = $GLOBALS['BE_USER']->getSessionData('workspaceMassAction');
-        $recordsProcessed = $GLOBALS['BE_USER']->getSessionData('workspaceMassAction_processed');
+        $processData = $this->getBackendUser()->getSessionData('workspaceMassAction');
+        $recordsProcessed = $this->getBackendUser()->getSessionData('workspaceMassAction_processed');
         $limitedCmd = [];
         $numRecs = 0;
         foreach ($processData as $table => $recs) {
@@ -193,15 +204,14 @@ class MassActionHandler extends AbstractHandler
         }
         if ($numRecs == 0) {
             // All done
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction', null);
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction_total', 0);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction', null);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction_total', 0);
         } else {
-            /** @var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */
-            $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
+            $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
             // Execute the commands:
-            $tce->start([], $limitedCmd);
-            $tce->process_cmdmap();
-            $errors = $tce->errorLog;
+            $dataHandler->start([], $limitedCmd);
+            $dataHandler->process_cmdmap();
+            $errors = $dataHandler->errorLog;
             if (!empty($errors)) {
                 throw new \Exception(implode(', ', $errors), 1476048278);
             }
@@ -212,9 +222,51 @@ class MassActionHandler extends AbstractHandler
                     unset($processData[$table][$key]);
                 }
             }
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction', $processData);
-            $GLOBALS['BE_USER']->setAndSaveSessionData('workspaceMassAction_processed', $recordsProcessed);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction', $processData);
+            $this->getBackendUser()->setAndSaveSessionData('workspaceMassAction_processed', $recordsProcessed);
         }
         return $recordsProcessed;
     }
+
+    /**
+     * Validates whether the submitted language parameter can be
+     * interpreted as integer value.
+     *
+     * @param \stdClass $parameters
+     * @return int|null
+     */
+    protected function validateLanguageParameter(\stdClass $parameters)
+    {
+        $language = null;
+        if (isset($parameters->language) && MathUtility::canBeInterpretedAsInteger($parameters->language)) {
+            $language = $parameters->language;
+        }
+        return $language;
+    }
+
+    /**
+     * Gets the current workspace ID.
+     *
+     * @return int The current workspace ID
+     */
+    protected function getCurrentWorkspace()
+    {
+        return $this->workspaceService->getCurrentWorkspace();
+    }
+
+    /**
+     * @return BackendUserAuthentication
+     */
+    protected function getBackendUser()
+    {
+        return $GLOBALS['BE_USER'];
+    }
+
+    /**
+     * @return LanguageService
+     */
+    protected function getLanguageService()
+    {
+        return $GLOBALS['LANG'];
+    }
 }
index 90f1a5c..10aaf89 100644 (file)
@@ -28,15 +28,17 @@ use TYPO3\CMS\Core\Utility\DiffUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
+use TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord;
 use TYPO3\CMS\Workspaces\Service\GridDataService;
 use TYPO3\CMS\Workspaces\Service\HistoryService;
+use TYPO3\CMS\Workspaces\Service\IntegrityService;
 use TYPO3\CMS\Workspaces\Service\StagesService;
 use TYPO3\CMS\Workspaces\Service\WorkspaceService;
 
 /**
  * Class RemoteServer
  */
-class RemoteServer extends AbstractHandler
+class RemoteServer
 {
     /**
      * @var GridDataService
@@ -49,10 +51,22 @@ class RemoteServer extends AbstractHandler
     protected $stagesService;
 
     /**
+     * @var WorkspaceService
+     */
+    protected $workspaceService;
+
+    /**
      * @var DiffUtility
      */
     protected $differenceHandler;
 
+    public function __construct()
+    {
+        $this->workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
+        $this->gridDataService = GeneralUtility::makeInstance(GridDataService::class);
+        $this->stagesService = GeneralUtility::makeInstance(StagesService::class);
+    }
+
     /**
      * Checks integrity of elements before peforming actions on them.
      *
@@ -82,23 +96,22 @@ class RemoteServer extends AbstractHandler
         if (!isset($parameter->language) || !MathUtility::canBeInterpretedAsInteger($parameter->language)) {
             $parameter->language = null;
         }
-        $versions = $this->getWorkspaceService()->selectVersionsInWorkspace($this->getCurrentWorkspace(), 0, -99, $pageId, $parameter->depth, 'tables_select', $parameter->language);
-        $data = $this->getGridDataService()->generateGridListFromVersions($versions, $parameter, $this->getCurrentWorkspace());
+        $versions = $this->workspaceService->selectVersionsInWorkspace($this->getCurrentWorkspace(), 0, -99, $pageId, $parameter->depth, 'tables_select', $parameter->language);
+        $data = $this->gridDataService->generateGridListFromVersions($versions, $parameter, $this->getCurrentWorkspace());
         return $data;
     }
 
     /**
      * Get List of available workspace actions
      *
-     * @param \stdClass $parameter
      * @return array $data
      */
-    public function getStageActions(\stdClass $parameter)
+    public function getStageActions()
     {
         $currentWorkspace = $this->getCurrentWorkspace();
         $stages = [];
         if ($currentWorkspace != WorkspaceService::SELECT_ALL_WORKSPACES) {
-            $stages = $this->getStagesService()->getStagesForWSUser();
+            $stages = $this->stagesService->getStagesForWSUser();
         }
         $data = [
             'total' => count($stages),
@@ -124,8 +137,7 @@ class RemoteServer extends AbstractHandler
         $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
         $icon_Live = $iconFactory->getIconForRecord($parameter->table, $liveRecord, Icon::SIZE_SMALL)->render();
         $icon_Workspace = $iconFactory->getIconForRecord($parameter->table, $versionRecord, Icon::SIZE_SMALL)->render();
-        $stagesService = $this->getStagesService();
-        $stagePosition = $stagesService->getPositionOfCurrentStage($parameter->stage);
+        $stagePosition = $this->stagesService->getPositionOfCurrentStage($parameter->stage);
         $fieldsOfRecords = array_keys($liveRecord);
         if ($GLOBALS['TCA'][$parameter->table]) {
             if ($GLOBALS['TCA'][$parameter->table]['interface']['showRecordFieldList']) {
@@ -247,12 +259,11 @@ class RemoteServer extends AbstractHandler
         }
         $commentsForRecord = $this->getCommentsForRecord($parameter->uid, $parameter->table);
 
-        /** @var $historyService HistoryService */
         $historyService = GeneralUtility::makeInstance(HistoryService::class);
         $history = $historyService->getHistory($parameter->table, $parameter->t3ver_oid);
 
-        $prevStage = $stagesService->getPrevStage($parameter->stage);
-        $nextStage = $stagesService->getNextStage($parameter->stage);
+        $prevStage = $this->stagesService->getPrevStage($parameter->stage);
+        $nextStage = $this->stagesService->getNextStage($parameter->stage);
 
         if (isset($prevStage[0])) {
             $prevStage = current($prevStage);
@@ -275,7 +286,7 @@ class RemoteServer extends AbstractHandler
                     'comments' => $commentsForRecord,
                     // escape/sanitize the others
                     'path_Live' => htmlspecialchars(BackendUtility::getRecordPath($liveRecord['pid'], '', 999)),
-                    'label_Stage' => htmlspecialchars($stagesService->getStageTitle($parameter->stage)),
+                    'label_Stage' => htmlspecialchars($this->stagesService->getStageTitle($parameter->stage)),
                     'label_PrevStage' => $prevStage,
                     'label_NextStage' => $nextStage,
                     'stage_position' => (int)$stagePosition['position'],
@@ -404,7 +415,7 @@ class RemoteServer extends AbstractHandler
             $sysLogEntry = [];
             $data = unserialize($sysLogRow['log_data']);
             $beUserRecord = BackendUtility::getRecord('be_users', $sysLogRow['userid']);
-            $sysLogEntry['stage_title'] = htmlspecialchars($this->getStagesService()->getStageTitle($data['stage']));
+            $sysLogEntry['stage_title'] = htmlspecialchars($this->stagesService->getStageTitle($data['stage']));
             $sysLogEntry['user_uid'] = (int)$sysLogRow['userid'];
             $sysLogEntry['user_username'] = is_array($beUserRecord) ? htmlspecialchars($beUserRecord['username']) : '';
             $sysLogEntry['tstamp'] = htmlspecialchars(BackendUtility::datetime($sysLogRow['tstamp']));
@@ -430,7 +441,7 @@ class RemoteServer extends AbstractHandler
                 'icon' => $iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render()
             ]
         ];
-        foreach ($this->getGridDataService()->getSystemLanguages() as $id => $systemLanguage) {
+        foreach ($this->gridDataService->getSystemLanguages() as $id => $systemLanguage) {
             if ($id < 0) {
                 continue;
             }
@@ -448,7 +459,7 @@ class RemoteServer extends AbstractHandler
     }
 
     /**
-     * @return BackendUserAuthentication;
+     * @return BackendUserAuthentication
      */
     protected function getBackendUser()
     {
@@ -456,7 +467,7 @@ class RemoteServer extends AbstractHandler
     }
 
     /**
-     * @return LanguageService;
+     * @return LanguageService
      */
     protected function getLanguageService()
     {
@@ -464,42 +475,86 @@ class RemoteServer extends AbstractHandler
     }
 
     /**
-     * Gets the Grid Data Service.
+     * Gets the difference handler, parsing differences based on sentences.
      *
-     * @return GridDataService
+     * @return DiffUtility
      */
-    protected function getGridDataService()
+    protected function getDifferenceHandler()
     {
-        if (!isset($this->gridDataService)) {
-            $this->gridDataService = GeneralUtility::makeInstance(GridDataService::class);
+        if (!isset($this->differenceHandler)) {
+            $this->differenceHandler = GeneralUtility::makeInstance(DiffUtility::class);
+            $this->differenceHandler->stripTags = false;
         }
-        return $this->gridDataService;
+        return $this->differenceHandler;
     }
 
     /**
-     * Gets the Stages Service.
+     * Creates a new instance of the integrity service for the
+     * given set of affected elements.
      *
-     * @return StagesService
+     * @param CombinedRecord[] $affectedElements
+     * @return IntegrityService
+     * @see getAffectedElements
      */
-    protected function getStagesService()
+    protected function createIntegrityService(array $affectedElements)
     {
-        if (!isset($this->stagesService)) {
-            $this->stagesService = GeneralUtility::makeInstance(StagesService::class);
+        $integrityService = GeneralUtility::makeInstance(IntegrityService::class);
+        $integrityService->setAffectedElements($affectedElements);
+        return $integrityService;
+    }
+
+    /**
+     * Gets affected elements on publishing/swapping actions.
+     * Affected elements have a dependency, e.g. translation overlay
+     * and the default origin record - thus, the default record would be
+     * affected if the translation overlay shall be published.
+     *
+     * @param \stdClass $parameters
+     * @return array
+     */
+    protected function getAffectedElements(\stdClass $parameters)
+    {
+        $affectedElements = [];
+        if ($parameters->type === 'selection') {
+            foreach ((array)$parameters->selection as $element) {
+                $affectedElements[] = CombinedRecord::create($element->table, $element->liveId, $element->versionId);
+            }
+        } elseif ($parameters->type === 'all') {
+            $versions = $this->workspaceService->selectVersionsInWorkspace($this->getCurrentWorkspace(), 0, -99, -1, 0, 'tables_select', $this->validateLanguageParameter($parameters));
+            foreach ($versions as $table => $tableElements) {
+                foreach ($tableElements as $element) {
+                    $affectedElement = CombinedRecord::create($table, $element['t3ver_oid'], $element['uid']);
+                    $affectedElement->getVersionRecord()->setRow($element);
+                    $affectedElements[] = $affectedElement;
+                }
+            }
         }
-        return $this->stagesService;
+        return $affectedElements;
     }
 
     /**
-     * Gets the difference handler, parsing differences based on sentences.
+     * Validates whether the submitted language parameter can be
+     * interpreted as integer value.
      *
-     * @return DiffUtility
+     * @param \stdClass $parameters
+     * @return int|null
      */
-    protected function getDifferenceHandler()
+    protected function validateLanguageParameter(\stdClass $parameters)
     {
-        if (!isset($this->differenceHandler)) {
-            $this->differenceHandler = GeneralUtility::makeInstance(DiffUtility::class);
-            $this->differenceHandler->stripTags = false;
+        $language = null;
+        if (isset($parameters->language) && MathUtility::canBeInterpretedAsInteger($parameters->language)) {
+            $language = $parameters->language;
         }
-        return $this->differenceHandler;
+        return $language;
+    }
+
+    /**
+     * Gets the current workspace ID.
+     *
+     * @return int The current workspace ID
+     */
+    protected function getCurrentWorkspace()
+    {
+        return $this->workspaceService->getCurrentWorkspace();
     }
 }
index 923ba46..f0b7eef 100644 (file)
@@ -204,7 +204,7 @@ class StagesService implements SingletonInterface
      */
     public function getStagesForWSUser()
     {
-        if ($GLOBALS['BE_USER']->isAdmin()) {
+        if ($this->getBackendUser()->isAdmin()) {
             return $this->getStagesForWS();
         }
 
@@ -303,7 +303,7 @@ class StagesService implements SingletonInterface
      * Gets next stage in process for given stage id
      *
      * @param int $stageId Id of the stage to fetch the next one for
-     * @return int The next stage Id
+     * @return array The next stage (id + details)
      * @throws \InvalidArgumentException
      */
     public function getNextStage($stageId)
@@ -370,7 +370,7 @@ class StagesService implements SingletonInterface
      * Get next stage in process for given stage id
      *
      * @param int $stageId Id of the stage to fetch the previous one for
-     * @return int The previous stage Id
+     * @return bool|array The previous stage or false
      * @throws \InvalidArgumentException
      */
     public function getPrevStage($stageId)
@@ -746,7 +746,7 @@ class StagesService implements SingletonInterface
         if (isset($this->workspaceStageAllowedCache[$cacheKey])) {
             return $this->workspaceStageAllowedCache[$cacheKey];
         }
-        $isAllowed = $GLOBALS['BE_USER']->workspaceCheckStageForCurrent($stageId);
+        $isAllowed = $this->getBackendUser()->workspaceCheckStageForCurrent($stageId);
         $this->workspaceStageAllowedCache[$cacheKey] = $isAllowed;
         return $isAllowed;
     }