Commit fe02b742 authored by Frank Nägler's avatar Frank Nägler Committed by Wouter Wolters
Browse files

[!!!][TASK] Remove ExtDirect from Workspaces

This patch removes ExtDirect from EXT:workspaces and add a new AJAX disptacher.
The ExtDirect classes are renamend and moved into a new location.

Resolves: #78468
Releases: master
Change-Id: I7a60bfd1a790174d6013e16a0903b2ae2c244cc0
Reviewed-on: https://review.typo3.org/50294


Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: default avatarDaniel Lorenz <info@extco.de>
Tested-by: default avatarDaniel Lorenz <info@extco.de>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
parent 32d99247
......@@ -46,7 +46,7 @@ TYPO3.state.ExtDirectProvider = function(config) {
* @param {HttpProvider} this
*/
'savefailure'
);
);
// call parent
TYPO3.state.ExtDirectProvider.superclass.constructor.call(this);
......
.. include:: ../../Includes.txt
=======================================================
Breaking: #78468 - Remove ExtDirect from EXT:workspaces
=======================================================
See :issue:`78468`
Description
===========
To remove ExtJS the ExtDirect component are removed too.
A new class :php:`TYPO3\CMS\Workspaces\Controller\AjaxDispatcher` was added to implement the ExtDirect router functionality.
This class is callable by a new AJAX route with the name `workspace_dispatch`.
Impact
======
The following classes are moved:
* EXT:workspaces/Classes/ExtDirect/AbstractHandler.php
=> EXT:workspaces/Classes/Controller/Remote/AbstractHandler.php
* EXT:workspaces/Classes/ExtDirect/ActionHandler.php
=> EXT:workspaces/Classes/Controller/Remote/ActionHandler.php
* EXT:workspaces/Classes/ExtDirect/MassActionHandler.php
=> EXT:workspaces/Classes/Controller/Remote/MassActionHandler.php
* EXT:workspaces/Classes/ExtDirect/ExtDirectServer.php
=> EXT:workspaces/Classes/Controller/Remote/RemoteServer.php
Affected Installations
======================
Any TYPO3 installation using the previously classes.
Migration
=========
Use the new classes as mentioned above.
.. index:: Backend, JavaScript, ext:workspaces
<?php
namespace TYPO3\CMS\Workspaces\Controller;
/*
* 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 Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Workspaces\Controller\Remote\ActionHandler;
use TYPO3\CMS\Workspaces\Controller\Remote\MassActionHandler;
use TYPO3\CMS\Workspaces\Controller\Remote\RemoteServer;
/**
* Implements the AJAX functionality for the various asynchronous calls
*/
class AjaxDispatcher
{
/**
* @var array
*/
protected $classMap = [
'RemoteServer' => RemoteServer::class,
'MassActions' => MassActionHandler::class,
'Actions' => ActionHandler::class
];
/**
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface
*/
public function dispatch(ServerRequestInterface $request, ResponseInterface $response)
{
$callStack = \GuzzleHttp\json_decode($request->getBody()->getContents());
if (!is_array($callStack)) {
$callStack = [$callStack];
}
$results = [];
foreach ($callStack as $call) {
$className = $this->classMap[$call->action];
$method = $call->method;
$parameters = $call->data;
$instance = GeneralUtility::makeInstance($className);
$results[] = $this->buildResultFromResponse(call_user_func_array([$instance, $method], $parameters), $call);
}
$response->getBody()->write(json_encode($results));
return $response;
}
/**
* @param mixed $responseFromMethod
* @param \stdClass $call
*
* @return \stdClass
*/
protected function buildResultFromResponse($responseFromMethod, $call)
{
$tmp = new \stdClass();
$tmp->action = $call->action;
$tmp->debug = '';
$tmp->method = $call->method;
$tmp->result = $responseFromMethod;
$tmp->tid = $call->tid;
$tmp->type = $call->type;
return $tmp;
}
}
......@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Workspaces\Controller;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\BackendTemplateView;
use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
......@@ -66,13 +65,6 @@ class PreviewController extends AbstractController
parent::initializeAction();
$this->stageService = GeneralUtility::makeInstance(StagesService::class);
$this->workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
$this->pageRenderer->addJsFile('EXT:backend/Resources/Public/JavaScript/ExtDirect.StateProvider.js');
$this->pageRenderer->loadExtJS(false, false);
// Load JavaScript:
$this->pageRenderer->addExtDirectCode([
'TYPO3.Workspaces',
'TYPO3.ExtDirectStateProvider'
]);
$states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
$this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
$this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', BackendUtility::getModuleUrl('record_edit'));
......@@ -150,7 +142,6 @@ class PreviewController extends AbstractController
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Preview');
$this->pageRenderer->addInlineSetting('Workspaces', 'SplitPreviewModes', $splitPreviewModes);
$this->pageRenderer->addInlineSetting('Workspaces', 'token', FormProtectionFactory::get('backend')->generateToken('extDirect'));
$cssFile = 'EXT:workspaces/Resources/Public/Css/preview.css';
$cssFile = GeneralUtility::getFileAbsFileName($cssFile);
......
<?php
namespace TYPO3\CMS\Workspaces\ExtDirect;
namespace TYPO3\CMS\Workspaces\Controller\Remote;
/*
* This file is part of the TYPO3 CMS project.
......@@ -15,7 +15,7 @@ namespace TYPO3\CMS\Workspaces\ExtDirect;
*/
/**
* Abstract ExtDirect handler
* Class AbstractHandler
*/
abstract class AbstractHandler
{
......
<?php
namespace TYPO3\CMS\Workspaces\ExtDirect;
namespace TYPO3\CMS\Workspaces\Controller\Remote;
/*
* This file is part of the TYPO3 CMS project.
......@@ -24,7 +24,7 @@ use TYPO3\CMS\Workspaces\Service\StagesService;
use TYPO3\CMS\Workspaces\Service\WorkspaceService;
/**
* ExtDirect action handler
* Class ActionHandler
*/
class ActionHandler extends AbstractHandler
{
......
<?php
namespace TYPO3\CMS\Workspaces\ExtDirect;
namespace TYPO3\CMS\Workspaces\Controller\Remote;
/*
* This file is part of the TYPO3 CMS project.
......@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Workspaces\ExtDirect;
*/
/**
* Class MassActionHandler
* Class encapsulates all actions which are triggered for all elements within the current workspace.
*/
class MassActionHandler extends AbstractHandler
......
<?php
namespace TYPO3\CMS\Workspaces\ExtDirect;
namespace TYPO3\CMS\Workspaces\Controller\Remote;
/*
* This file is part of the TYPO3 CMS project.
......@@ -35,9 +35,9 @@ use TYPO3\CMS\Workspaces\Service\StagesService;
use TYPO3\CMS\Workspaces\Service\WorkspaceService;
/**
* ExtDirect server
* Class RemoteServer
*/
class ExtDirectServer extends AbstractHandler
class RemoteServer extends AbstractHandler
{
/**
* @var GridDataService
......
......@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Workspaces\Controller;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
......@@ -201,14 +200,8 @@ class ReviewController extends AbstractController
protected function initializeAction()
{
parent::initializeAction();
$this->pageRenderer->addJsFile('EXT:backend/Resources/Public/JavaScript/ExtDirect.StateProvider.js');
$this->pageRenderer->loadExtJS(false, false);
$states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
$this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
// Load JavaScript:
$this->pageRenderer->addExtDirectCode([
'TYPO3.Workspaces'
]);
foreach ($this->getAdditionalResourceService()->getLocalizationResources() as $localizationResource) {
$this->pageRenderer->addInlineLanguageLabelFile($localizationResource);
......@@ -216,7 +209,6 @@ class ReviewController extends AbstractController
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Backend');
$this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', BackendUtility::getModuleUrl('record_edit'));
$this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', BackendUtility::getModuleUrl('record_history'));
$this->pageRenderer->addInlineSetting('Workspaces', 'token', FormProtectionFactory::get('backend')->generateToken('extDirect'));
$this->pageRenderer->addInlineSetting('Workspaces', 'id', (int)GeneralUtility::_GP('id'));
}
......
<?php
namespace TYPO3\CMS\Workspaces\ExtDirect;
namespace TYPO3\CMS\Workspaces\Hooks;
/*
* This file is part of the TYPO3 CMS project.
......
......@@ -8,5 +8,9 @@ return [
'workspace_switch' => [
'path' => '/workspace/switch',
'target' => \TYPO3\CMS\Workspaces\Controller\AjaxController::class . '::switchWorkspaceAction'
],
'workspace_dispatch' => [
'path' => '/workspace/dispatch',
'target' => \TYPO3\CMS\Workspaces\Controller\AjaxDispatcher::class . '::dispatch'
]
];
......@@ -124,8 +124,8 @@ define([
);
Wizard.addFinalProcessingSlide(function() {
// We passed this slide, swap the record now
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectActionsPayload('swapSingleRecord', [
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteActionsPayload('swapSingleRecord', [
$tr.data('table'),
$tr.data('t3ver_oid'),
$tr.data('uid')
......@@ -224,9 +224,9 @@ define([
var $me = $(this);
Backend.settings.language = $me.val();
Workspaces.sendExtDirectRequest([
Workspaces.generateExtDirectActionsPayload('saveLanguageSelection', [$me.val()]),
Workspaces.generateExtDirectPayload('getWorkspaceInfos', Backend.settings)
Workspaces.sendRemoteRequest([
Workspaces.generateRemoteActionsPayload('saveLanguageSelection', [$me.val()]),
Workspaces.generateRemotePayload('getWorkspaceInfos', Backend.settings)
]).done(function(response) {
Backend.elements.$languageSelector.prev().html($me.find(':selected').data('icon'));
Backend.renderWorkspaceInfos(response[1].result);
......@@ -377,8 +377,8 @@ define([
throw 'Invalid direction given.';
}
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectActionsPayload(stageWindowAction, [
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteActionsPayload(stageWindowAction, [
$row.data('uid'), $row.data('table'), $row.data('t3ver_oid')
])
).done(function(response) {
......@@ -396,9 +396,9 @@ define([
elements: []
};
Workspaces.sendExtDirectRequest([
Workspaces.generateExtDirectActionsPayload(stageExecuteAction, [serializedForm]),
Workspaces.generateExtDirectPayload('getWorkspaceInfos', Backend.settings)
Workspaces.sendRemoteRequest([
Workspaces.generateRemoteActionsPayload(stageExecuteAction, [serializedForm]),
Workspaces.generateRemotePayload('getWorkspaceInfos', Backend.settings)
]).done(function(response) {
$modal.modal('hide');
Backend.renderWorkspaceInfos(response[1].result);
......@@ -413,11 +413,11 @@ define([
* Loads the workspace components, like available stage actions and items of the workspace
*/
Backend.loadWorkspaceComponents = function() {
Workspaces.sendExtDirectRequest([
Workspaces.generateExtDirectPayload('getWorkspaceInfos', Backend.settings),
Workspaces.generateExtDirectPayload('getStageActions', {}),
Workspaces.generateExtDirectMassActionsPayload('getMassStageActions', {}),
Workspaces.generateExtDirectPayload('getSystemLanguages', {})
Workspaces.sendRemoteRequest([
Workspaces.generateRemotePayload('getWorkspaceInfos', Backend.settings),
Workspaces.generateRemotePayload('getStageActions', {}),
Workspaces.generateRemoteMassActionsPayload('getMassStageActions', {}),
Workspaces.generateRemotePayload('getSystemLanguages', {})
]).done(function(response) {
Backend.elements.$depthSelector.prop('disabled', false);
......@@ -466,8 +466,8 @@ define([
* @protected
*/
Backend.getWorkspaceInfos = function() {
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectPayload('getWorkspaceInfos', Backend.settings)
Workspaces.sendRemoteRequest(
Workspaces.generateRemotePayload('getWorkspaceInfos', Backend.settings)
).done(function(response) {
Backend.renderWorkspaceInfos(response[0].result);
});
......@@ -627,8 +627,8 @@ define([
var $tr = $(e.target).closest('tr');
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectPayload('getRowDetails', {
Workspaces.sendRemoteRequest(
Workspaces.generateRemotePayload('getRowDetails', {
stage: $tr.data('stage'),
t3ver_oid: $tr.data('t3ver_oid'),
table: $tr.data('table'),
......@@ -756,8 +756,8 @@ define([
Backend.openPreview = function(e) {
var $tr = $(e.target).closest('tr');
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectActionsPayload('viewSingleRecord', [
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteActionsPayload('viewSingleRecord', [
$tr.data('table'), $tr.data('uid')
])
).done(function(response) {
......@@ -849,8 +849,8 @@ define([
);
$modal.on('button.clicked', function(e) {
if (e.target.name === 'ok') {
Workspaces.sendExtDirectRequest([
Workspaces.generateExtDirectActionsPayload('deleteSingleRecord', [
Workspaces.sendRemoteRequest([
Workspaces.generateRemoteActionsPayload('deleteSingleRecord', [
$tr.data('table'),
$tr.data('uid')
])
......@@ -930,8 +930,8 @@ define([
Severity.warning
);
Wizard.addFinalProcessingSlide(function() {
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectActionsPayload('executeSelectionAction', {
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteActionsPayload('executeSelectionAction', {
action: selectedAction,
selection: affectedRecords
})
......@@ -1014,8 +1014,8 @@ define([
Severity.warning
);
Wizard.addFinalProcessingSlide(function() {
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectMassActionsPayload(massAction, {
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteMassActionsPayload(massAction, {
init: true,
total: 0,
processed: 0,
......@@ -1024,8 +1024,8 @@ define([
})
).done(function(response) {
var payload = response[0].result;
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectMassActionsPayload(massAction, payload)
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteMassActionsPayload(massAction, payload)
).done(function() {
Backend.getWorkspaceInfos();
Wizard.dismiss();
......@@ -1056,8 +1056,8 @@ define([
t3ver_oid: affected[2]
});
}
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectActionsPayload('sendToSpecificStageWindow', [
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteActionsPayload('sendToSpecificStageWindow', [
stage, affectedRecords
])
).done(function(response) {
......@@ -1072,9 +1072,9 @@ define([
nextStage: stage
};
Workspaces.sendExtDirectRequest([
Workspaces.generateExtDirectActionsPayload('sendToSpecificStageExecute', [serializedForm]),
Workspaces.generateExtDirectPayload('getWorkspaceInfos', Backend.settings)
Workspaces.sendRemoteRequest([
Workspaces.generateRemoteActionsPayload('sendToSpecificStageExecute', [serializedForm]),
Workspaces.generateRemotePayload('getWorkspaceInfos', Backend.settings)
]).done(function(response) {
$modal.modal('hide');
Backend.renderWorkspaceInfos(response[1].result);
......@@ -1098,7 +1098,6 @@ define([
/**
* Renders the action button based on the user's permission.
* This method is intended to be dropped once we don't the ExtDirect stuff anymore.
*
* @returns {$}
* @private
......@@ -1114,8 +1113,8 @@ define([
* Fetches and renders available preview links
*/
Backend.generatePreviewLinks = function() {
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectActionsPayload('generateWorkspacePreviewLinksForAllLanguages', [
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteActionsPayload('generateWorkspacePreviewLinksForAllLanguages', [
Backend.settings.id
])
).done(function(response) {
......@@ -1189,4 +1188,4 @@ define([
};
$(Backend.initialize);
});
\ No newline at end of file
});
......@@ -170,9 +170,9 @@ define([
);
$modal.on('button.clicked', function(e) {
if (e.target.name === 'ok') {
Workspaces.sendExtDirectRequest([
Workspaces.generateExtDirectActionsPayload('discardStagesFromPage', [TYPO3.settings.Workspaces.id]),
Workspaces.generateExtDirectActionsPayload('updateStageChangeButtons', [TYPO3.settings.Workspaces.id])
Workspaces.sendRemoteRequest([
Workspaces.generateRemoteActionsPayload('discardStagesFromPage', [TYPO3.settings.Workspaces.id]),
Workspaces.generateRemoteActionsPayload('updateStageChangeButtons', [TYPO3.settings.Workspaces.id])
]).done(function(response) {
$modal.modal('hide');
Preview.renderStageButtons(response[1].result);
......@@ -220,8 +220,8 @@ define([
throw 'Invalid direction ' + direction + ' requested.';
}
Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectActionsPayload(actionName, [TYPO3.settings.Workspaces.id])
Workspaces.sendRemoteRequest(
Workspaces.generateRemoteActionsPayload(actionName, [TYPO3.settings.Workspaces.id])
).done(function(response) {
var $modal = Workspaces.renderSendToStageWindow(response);
$modal.on('button.clicked', function (e) {
......@@ -232,9 +232,9 @@ define([
serializedForm.affects = response[0].result.affects;
serializedForm.stageId = $me.data('stageId');
Workspaces.sendExtDirectRequest([
Workspaces.generateExtDirectActionsPayload('sentCollectionToStage', [serializedForm]),
Workspaces.generateExtDirectActionsPayload('updateStageChangeButtons', [TYPO3.settings.Workspaces.id])
Workspaces.sendRemoteRequest([
Workspaces.generateRemoteActionsPayload('sentCollectionToStage', [serializedForm]),
Workspaces.generateRemoteActionsPayload('updateStageChangeButtons', [TYPO3.settings.Workspaces.id])
]).done(function(response) {
$modal.modal('hide');
......@@ -302,4 +302,4 @@ define([
$(document).ready(function() {
Preview.initialize();
});
});
\ No newline at end of file
});
......@@ -108,7 +108,7 @@ define(['jquery'], function($) {
* @param {String} title the workspace title
*/
WorkspacesMenu.performWorkspaceSwitch = function(id, title) {
top.TYPO3.Workspaces.workspaceTitle = title;
top.TYPO3.Backend.workspaceTitle = title;
top.TYPO3.configuration.inWorkspace = id !== 0;
WorkspacesMenu.updateBackendContext(title);
......
......@@ -22,7 +22,9 @@ define([
], function($, Severity, Modal) {
'use strict';
var Workspaces = {};
var Workspaces = {
tid: 0
};
/**
* Renders the send to stage window
......@@ -99,21 +101,20 @@ define([
* @return {$}
*/
Workspaces.checkIntegrity = function(payload) {
return Workspaces.sendExtDirectRequest(
Workspaces.generateExtDirectPayload('checkIntegrity', payload)
return Workspaces.sendRemoteRequest(
Workspaces.generateRemotePayload('checkIntegrity', payload)
);
};
/**
* Sends an AJAX request compatible to ExtDirect
* This method is intended to be dropped once we don't the ExtDirect stuff anymore.
* Sends an AJAX request
*
* @param {Object} payload
* @return {$}
*/
Workspaces.sendExtDirectRequest = function(payload) {
Workspaces.sendRemoteRequest = function(payload) {
return $.ajax({
url: TYPO3.settings.ajaxUrls['ext_direct_route'] + '&namespace=TYPO3.Workspaces',
url: TYPO3.settings.ajaxUrls['workspace_dispatch'],
method: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
......@@ -122,45 +123,45 @@ define([
};
/**
* Generates the payload for ExtDirect
* Generates the payload for a remote call
*
* @param {String} method
* @param {Object} data
* @return {{action, data, method, type}}
*/
Workspaces.generateExtDirectPayload = function(method, data) {
Workspaces.generateRemotePayload = function(method, data) {
if (typeof data === 'undefined') {
data = {};
}
return Workspaces.generateExtDirectPayloadBody('ExtDirect', method, data);
return Workspaces.generateRemotePayloadBody('RemoteServer', method, data);
};
/**
* Generates the payload for ExtDirectMassActions
* Generates the payload for MassActions
*
* @param {String} method
* @param {Object} data