+++ /dev/null
-<?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 TYPO3\CMS\Backend\View\BackendTemplateView;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Imaging\IconFactory;
-use TYPO3\CMS\Core\Page\PageRenderer;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
-use TYPO3\CMS\Workspaces\Service\AdditionalColumnService;
-use TYPO3\CMS\Workspaces\Service\AdditionalResourceService;
-
-/**
- * Abstract action controller.
- */
-class AbstractController extends ActionController
-{
- /**
- * @var string
- */
- protected $defaultViewObjectName = BackendTemplateView::class;
-
- /**
- * @var BackendTemplateView
- */
- protected $view;
-
- /**
- * @var string Key of the extension this controller belongs to
- */
- protected $extensionName = 'Workspaces';
-
- /**
- * @var PageRenderer
- */
- protected $pageRenderer;
-
- /**
- * @var int
- */
- protected $pageId;
-
- /**
- * Initializes the controller before invoking an action method.
- */
- protected function initializeAction()
- {
- $this->pageRenderer = $this->getPageRenderer();
- // @todo Evaluate how the (int) typecast can be used with Extbase validators/filters
- $this->pageId = (int)GeneralUtility::_GP('id');
- $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
- $lang = $this->getLanguageService();
- $icons = [
- 'language' => $iconFactory->getIcon('flags-multiple', Icon::SIZE_SMALL)->render(),
- 'integrity' => $iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
- 'success' => $iconFactory->getIcon('status-dialog-ok', Icon::SIZE_SMALL)->render(),
- 'info' => $iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
- 'warning' => $iconFactory->getIcon('status-dialog-warning', Icon::SIZE_SMALL)->render(),
- 'error' => $iconFactory->getIcon('status-dialog-error', Icon::SIZE_SMALL)->render()
- ];
- $this->pageRenderer->addInlineSetting('Workspaces', 'icons', $icons);
- $this->pageRenderer->addInlineSetting('Workspaces', 'id', $this->pageId);
- $this->pageRenderer->addInlineSetting('Workspaces', 'depth', $this->pageId === 0 ? 999 : 1);
- $this->pageRenderer->addInlineSetting('Workspaces', 'language', $this->getLanguageSelection());
- $this->pageRenderer->addInlineLanguageLabelArray([
- 'title' => $lang->getLL('title'),
- 'path' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.path'),
- 'table' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.table'),
- 'depth' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_perm.xlf:Depth'),
- 'depth_0' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
- 'depth_1' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
- 'depth_2' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
- 'depth_3' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
- 'depth_4' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
- 'depth_infi' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
- ]);
- $this->pageRenderer->addInlineLanguageLabelFile('EXT:workspaces/Resources/Private/Language/locallang.xlf');
- $this->assignExtensionSettings();
- }
-
- /**
- * Assigns additional Workspace settings to TYPO3.settings.Workspaces.extension
- */
- protected function assignExtensionSettings()
- {
- $extension = [
- 'AdditionalColumn' => [
- 'Definition' => [],
- 'Handler' => [],
- ],
- ];
-
- $extension['AdditionalColumn']['Definition'] = $this->getAdditionalColumnService()->getDefinition();
- $extension['AdditionalColumn']['Handler'] = $this->getAdditionalColumnService()->getHandler();
- $this->pageRenderer->addInlineSetting('Workspaces', 'extension', $extension);
- }
-
- /**
- * Gets the selected language.
- *
- * @return string
- */
- protected function getLanguageSelection()
- {
- $language = 'all';
- $backendUser = $this->getBackendUser();
- if (isset($backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'])) {
- $language = $backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'];
- }
- return $language;
- }
-
- /**
- * @return AdditionalColumnService
- */
- protected function getAdditionalColumnService()
- {
- return $this->objectManager->get(AdditionalColumnService::class);
- }
-
- /**
- * @return AdditionalResourceService
- */
- protected function getAdditionalResourceService()
- {
- return $this->objectManager->get(AdditionalResourceService::class);
- }
-
- /**
- * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
- */
- protected function getBackendUser()
- {
- return $GLOBALS['BE_USER'];
- }
-
- /**
- * @return \TYPO3\CMS\Core\Localization\LanguageService
- */
- protected function getLanguageService()
- {
- return $GLOBALS['LANG'];
- }
-
- /**
- * @return PageRenderer
- */
- protected function getPageRenderer()
- {
- return GeneralUtility::makeInstance(PageRenderer::class);
- }
-}
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Http\JsonResponse;
+use TYPO3\CMS\Core\Type\Bitmask\Permission;
/**
* Implements the AJAX functionality for the various asynchronous calls
' AND pages.t3ver_wsid IN (0, ' . $workspaceId . ')'
);
if ($page) {
- if ($this->getBackendUser()->doesUserHaveAccess($page, 1)) {
+ if ($this->getBackendUser()->doesUserHaveAccess($page, Permission::PAGE_SHOW)) {
break;
}
} else {
<?php
+declare(strict_types = 1);
namespace TYPO3\CMS\Workspaces\Controller;
/*
* The TYPO3 project - inspiring people to share!
*/
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Backend\View\BackendTemplateView;
-use TYPO3\CMS\Core\Messaging\FlashMessage;
-use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\PathUtility;
-use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
-use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
+use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Workspaces\Service\StagesService;
use TYPO3\CMS\Workspaces\Service\WorkspaceService;
/**
* Implements the preview controller of the workspace module.
*/
-class PreviewController extends AbstractController
+class PreviewController
{
/**
* @var StagesService
protected $workspaceService;
/**
- * Set up the doc header properly here
+ * @var int
+ */
+ protected $pageId;
+
+ /**
+ * ModuleTemplate object
*
- * @param ViewInterface $view
+ * @var ModuleTemplate
*/
- protected function initializeView(ViewInterface $view)
- {
- if ($view instanceof BackendTemplateView) {
- /** @var BackendTemplateView $view */
- parent::initializeView($view);
- $view->getModuleTemplate()->getDocHeaderComponent()->disable();
- $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
- }
- }
+ protected $moduleTemplate;
+
+ /**
+ * @var \TYPO3Fluid\Fluid\View\ViewInterface
+ */
+ protected $view;
/**
- * Initializes the controller before invoking an action method.
+ * Set up the module template
*/
- protected function initializeAction()
+ public function __construct()
{
- parent::initializeAction();
- /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
- $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
$this->stageService = GeneralUtility::makeInstance(StagesService::class);
$this->workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
+ $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+ $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Workspaces/Preview');
+ $this->moduleTemplate->getDocHeaderComponent()->disable();
+ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
- $this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
- $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
- $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_history'));
- // @todo this part should be done with inlineLocallanglabels
- $this->pageRenderer->addJsInlineCode('workspace-inline-code', $this->generateJavascript());
+ $this->moduleTemplate->getPageRenderer()->addInlineSetting('Workspaces', 'States', $states);
+ $this->moduleTemplate->getPageRenderer()->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
+ $this->moduleTemplate->getPageRenderer()->addInlineSetting('RecordHistory', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_history'));
+ $this->moduleTemplate->getPageRenderer()->addJsInlineCode('workspace-inline-code', $this->generateJavascript());
+ $this->moduleTemplate->getPageRenderer()->addCssFile('EXT:workspaces/Resources/Public/Css/preview.css');
+ $this->moduleTemplate->getPageRenderer()->addInlineLanguageLabelFile('EXT:workspaces/Resources/Private/Language/locallang.xlf');
+ }
+
+ /**
+ * Sets up the view
+ *
+ * @param string $templateName
+ */
+ protected function initializeView(string $templateName)
+ {
+ $this->view = GeneralUtility::makeInstance(StandaloneView::class);
+ $this->view->setTemplate($templateName);
+ $this->view->setTemplateRootPaths(['EXT:workspaces/Resources/Private/Templates/Preview']);
+ $this->view->setPartialRootPaths(['EXT:workspaces/Resources/Private/Partials']);
+ $this->view->setLayoutRootPaths(['EXT:workspaces/Resources/Private/Layouts']);
}
/**
* Basically makes sure that the workspace preview is rendered.
* The preview itself consists of three frames, so there are
- * only the frames-urls we've to generate here
+ * only the frames-urls we have to generate here
*
- * @param int $previewWS
+ * @param ServerRequestInterface $request
+ * @return ResponseInterface
*/
- public function indexAction($previewWS = null)
+ public function handleRequest(ServerRequestInterface $request): ResponseInterface
{
- $backendUser = $this->getBackendUser();
+ $this->initializeView('Index');
// Get all the GET parameters to pass them on to the frames
- $queryParameters = GeneralUtility::_GET();
+ $queryParameters = $request->getQueryParams();
+
+ $previewWS = $queryParameters['previewWS'] ?? null;
+ $this->pageId = (int)$queryParameters['id'];
- // Remove the GET parameters related to the workspaces module and the page id
- unset($queryParameters['tx_workspaces_web_workspacesworkspaces']);
- unset($queryParameters['route']);
- unset($queryParameters['id']);
+ // Remove the GET parameters related to the workspaces module
+ unset($queryParameters['route'], $queryParameters['token'], $queryParameters['previewWS']);
// Assemble a query string from the retrieved parameters
$queryString = GeneralUtility::implodeArrayForUrl('', $queryParameters);
// fetch the next and previous stage
- $workspaceItemsArray = $this->workspaceService->selectVersionsInWorkspace($this->stageService->getWorkspaceId(), ($filter = 1), ($stage = -99), $this->pageId, ($recursionLevel = 0), ($selectionType = 'tables_modify'));
+ $workspaceItemsArray = $this->workspaceService->selectVersionsInWorkspace($this->stageService->getWorkspaceId(), 1, -99, $this->pageId, 0, 'tables_modify');
list(, $nextStage) = $this->stageService->getNextStageForElementCollection($workspaceItemsArray);
list(, $previousStage) = $this->stageService->getPreviousStageForElementCollection($workspaceItemsArray);
- /** @var $wsService WorkspaceService */
- $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
- $wsList = $wsService->getAvailableWorkspaces();
- $activeWorkspace = $backendUser->workspace;
- if (!is_null($previewWS)) {
- if (in_array($previewWS, array_keys($wsList)) && $activeWorkspace != $previewWS) {
- $activeWorkspace = $previewWS;
- $backendUser->setWorkspace($activeWorkspace);
- BackendUtility::setUpdateSignal('updatePageTree');
- }
+ $availableWorkspaces = $this->workspaceService->getAvailableWorkspaces();
+ $activeWorkspace = $this->getBackendUser()->workspace;
+ if ($previewWS !== null && in_array($previewWS, array_keys($availableWorkspaces)) && $activeWorkspace != $previewWS) {
+ $activeWorkspace = $previewWS;
+ $this->getBackendUser()->setWorkspace($activeWorkspace);
+ BackendUtility::setUpdateSignal('updatePageTree');
}
- /** @var $uriBuilder UriBuilder */
- $uriBuilder = $this->objectManager->get(UriBuilder::class);
- $wsSettingsPath = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
- $wsSettingsUri = $uriBuilder->uriFor('singleIndex', [], ReviewController::class, 'workspaces', 'web_workspacesworkspaces');
- $wsSettingsParams = '&tx_workspaces_web_workspacesworkspaces[controller]=Review';
- $wsSettingsUrl = $wsSettingsPath . $wsSettingsUri . $wsSettingsParams;
- $viewDomain = BackendUtility::getViewDomain($this->pageId);
- $wsBaseUrl = $viewDomain . '/index.php?id=' . $this->pageId . $queryString;
- // @todo - handle new pages here
- // branchpoints are not handled anymore because this feature is not supposed anymore
- if (WorkspaceService::isNewPage($this->pageId)) {
- $wsNewPageUri = $uriBuilder->uriFor('newPage', [], self::class, 'workspaces', 'web_workspacesworkspaces');
- $wsNewPageParams = '&tx_workspaces_web_workspacesworkspaces[controller]=Preview';
- $liveUrl = $wsSettingsPath . $wsNewPageUri . $wsNewPageParams . '&ADMCMD_prev=IGNORE';
- } else {
- $liveUrl = $wsBaseUrl . '&ADMCMD_noBeUser=1&ADMCMD_prev=IGNORE';
+
+ // Base URL for frontend preview links
+ $previewBaseUrl = BackendUtility::getViewDomain($this->pageId) . '/index.php?' . $queryString;
+
+ // Build the "list view" link to the review controller
+ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+ $wsSettingsUrl = $uriBuilder->buildUriFromRoute('web_WorkspacesWorkspaces', [
+ 'tx_workspaces_web_workspacesworkspaces' => ['action' => 'singleIndex']
+ ], UriBuilder::ABSOLUTE_URL);
+
+ if (!WorkspaceService::isNewPage($this->pageId)) {
+ $liveUrl = $previewBaseUrl . '&ADMCMD_noBeUser=1&ADMCMD_prev=IGNORE';
}
- $wsUrl = $wsBaseUrl . '&ADMCMD_prev=IGNORE&ADMCMD_view=1&ADMCMD_editIcons=1';
- $backendDomain = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY');
+ $wsUrl = $previewBaseUrl . '&ADMCMD_prev=IGNORE&ADMCMD_view=1&ADMCMD_editIcons=1';
+
+ // Evaluate available preview modes
$splitPreviewTsConfig = BackendUtility::getModTSconfig($this->pageId, 'workspaces.splitPreviewModes');
$splitPreviewModes = GeneralUtility::trimExplode(',', $splitPreviewTsConfig['value']);
$allPreviewModes = ['slider', 'vbox', 'hbox'];
if (!array_intersect($splitPreviewModes, $allPreviewModes)) {
$splitPreviewModes = $allPreviewModes;
}
+ $this->moduleTemplate->getPageRenderer()->addInlineSetting('Workspaces', 'SplitPreviewModes', $splitPreviewModes);
- $wsList = $wsService->getAvailableWorkspaces();
- $activeWorkspace = $backendUser->workspace;
-
- $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Preview');
- $this->pageRenderer->addInlineSetting('Workspaces', 'SplitPreviewModes', $splitPreviewModes);
-
- $cssFile = 'EXT:workspaces/Resources/Public/Css/preview.css';
- $cssFile = GeneralUtility::getFileAbsFileName($cssFile);
- $this->pageRenderer->addCssFile(PathUtility::getAbsoluteWebPath($cssFile));
-
- $backendUser->setAndSaveSessionData('workspaces.backend_domain', GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY'));
-
- $logoPath = GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Images/typo3_logo_orange.svg');
- $logoWidth = 22;
- $logoHeight = 22;
+ $backendDomain = $request->getAttribute('normalizedParams')->getRequestHostOnly();
+ $this->getBackendUser()->setAndSaveSessionData('workspaces.backend_domain', $backendDomain);
$this->view->assignMultiple([
- 'logoUrl' => PathUtility::getAbsoluteWebPath($logoPath),
'logoLink' => TYPO3_URL_GENERAL,
- 'logoWidth' => $logoWidth,
- 'logoHeight' => $logoHeight,
- 'liveUrl' => $liveUrl,
+ 'liveUrl' => $liveUrl ?? false,
'wsUrl' => $wsUrl,
'wsSettingsUrl' => $wsSettingsUrl,
'backendDomain' => $backendDomain,
- 'activeWorkspace' => $wsList[$activeWorkspace],
+ 'activeWorkspace' => $availableWorkspaces[$activeWorkspace],
'splitPreviewModes' => $splitPreviewModes,
'firstPreviewMode' => current($splitPreviewModes),
- 'enablePreviousStageButton' => !$this->isInvalidStage($previousStage),
- 'enableNextStageButton' => !$this->isInvalidStage($nextStage),
- 'enableDiscardStageButton' => !$this->isInvalidStage($nextStage) || !$this->isInvalidStage($previousStage),
+ 'enablePreviousStageButton' => $this->isValidStage($previousStage),
+ 'enableNextStageButton' => $this->isValidStage($nextStage),
+ 'enableDiscardStageButton' => $this->isValidStage($nextStage) || $this->isValidStage($previousStage),
'nextStage' => $nextStage['title'],
'nextStageId' => $nextStage['uid'],
'prevStage' => $previousStage['title'],
'prevStageId' => $previousStage['uid'],
]);
- foreach ($this->getAdditionalResourceService()->getLocalizationResources() as $localizationResource) {
- $this->pageRenderer->addInlineLanguageLabelFile($localizationResource);
- }
+
+ $this->moduleTemplate->setContent($this->view->render());
+ return new HtmlResponse($this->moduleTemplate->renderContent());
}
/**
* @param array $stageArray
* @return bool
*/
- protected function isInvalidStage($stageArray)
- {
- return !(is_array($stageArray) && !empty($stageArray));
- }
-
- /**
- */
- public function newPageAction()
+ protected function isValidStage($stageArray): bool
{
- /** @var FlashMessage $flashMessage */
- $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:info.newpage.detail'), $this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:info.newpage'), FlashMessage::INFO);
- /** @var $flashMessageService FlashMessageService */
- $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
- /** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
- $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
- $defaultFlashMessageQueue->enqueue($flashMessage);
+ return is_array($stageArray) && !empty($stageArray);
}
/**
* Generates the JavaScript code for the backend,
* and since we're loading a backend module outside of the actual backend
- * this copies parts of the index.php?M=main module
+ * this copies parts of the backend main script.
*
* @return string
*/
- protected function generateJavascript()
+ protected function generateJavascript(): string
{
- $backendUser = $this->getBackendUser();
// If another page module was specified, replace the default Page module with the new one
- $newPageModule = trim($backendUser->getTSConfigVal('options.overridePageModule'));
- $pageModule = BackendUtility::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
- if (!$backendUser->check('modules', $pageModule)) {
+ $pageModule = trim($this->getBackendUser()->getTSConfigVal('options.overridePageModule') ?? '');
+ $pageModule = BackendUtility::isModuleSetInTBE_MODULES($pageModule) ? $pageModule : 'web_layout';
+ if (!$this->getBackendUser()->check('modules', $pageModule)) {
$pageModule = '';
}
$t3Configuration = [
- 'username' => htmlspecialchars($backendUser->user['username']),
+ 'username' => htmlspecialchars($this->getBackendUser()->user['username']),
'pageModule' => $pageModule,
- 'inWorkspace' => $backendUser->workspace !== 0,
+ 'inWorkspace' => $this->getBackendUser()->workspace !== 0,
'showRefreshLoginPopup' => (bool)($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup'] ?? false)
];
}
/**
- * @return \TYPO3\CMS\Core\Localization\LanguageService
- */
- protected function getLanguageService()
- {
- return $GLOBALS['LANG'];
- }
-
- /**
- * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
+ * @return BackendUserAuthentication
*/
- protected function getBackendUser()
+ protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
* The TYPO3 project - inspiring people to share!
*/
+use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Backend\View\BackendTemplateView;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
+use TYPO3\CMS\Workspaces\Service\AdditionalColumnService;
+use TYPO3\CMS\Workspaces\Service\AdditionalResourceService;
use TYPO3\CMS\Workspaces\Service\WorkspaceService;
/**
* Review controller.
*/
-class ReviewController extends AbstractController
+class ReviewController extends ActionController
{
+ /**
+ * @var string
+ */
+ protected $defaultViewObjectName = BackendTemplateView::class;
+
+ /**
+ * @var BackendTemplateView
+ */
+ protected $view;
+
+ /**
+ * @var PageRenderer
+ */
+ protected $pageRenderer;
+
+ /**
+ * @var int
+ */
+ protected $pageId;
+
/**
* Set up the doc header properly here
*
$buttonBar->addButton($shortcutButton);
}
+ /**
+ * Initializes the controller before invoking an action method.
+ */
+ protected function initializeAction()
+ {
+ $this->pageRenderer = $this->getPageRenderer();
+ // @todo Evaluate how the (int) typecast can be used with Extbase validators/filters
+ $this->pageId = (int)GeneralUtility::_GP('id');
+ $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+ $lang = $this->getLanguageService();
+ $icons = [
+ 'language' => $iconFactory->getIcon('flags-multiple', Icon::SIZE_SMALL)->render(),
+ 'integrity' => $iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
+ 'success' => $iconFactory->getIcon('status-dialog-ok', Icon::SIZE_SMALL)->render(),
+ 'info' => $iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
+ 'warning' => $iconFactory->getIcon('status-dialog-warning', Icon::SIZE_SMALL)->render(),
+ 'error' => $iconFactory->getIcon('status-dialog-error', Icon::SIZE_SMALL)->render()
+ ];
+ $this->pageRenderer->addInlineSetting('Workspaces', 'icons', $icons);
+ $this->pageRenderer->addInlineSetting('Workspaces', 'id', $this->pageId);
+ $this->pageRenderer->addInlineSetting('Workspaces', 'depth', $this->pageId === 0 ? 999 : 1);
+ $this->pageRenderer->addInlineSetting('Workspaces', 'language', $this->getLanguageSelection());
+ $this->pageRenderer->addInlineLanguageLabelArray([
+ 'title' => $lang->getLL('title'),
+ 'path' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.path'),
+ 'table' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.table'),
+ 'depth' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_perm.xlf:Depth'),
+ 'depth_0' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
+ 'depth_1' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
+ 'depth_2' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
+ 'depth_3' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
+ 'depth_4' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
+ 'depth_infi' => $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
+ ]);
+ $this->pageRenderer->addInlineLanguageLabelFile('EXT:workspaces/Resources/Private/Language/locallang.xlf');
+ $states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
+ $this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
+
+ foreach ($this->getAdditionalResourceService()->getLocalizationResources() as $localizationResource) {
+ $this->pageRenderer->addInlineLanguageLabelFile($localizationResource);
+ }
+ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+ $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Backend');
+ $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
+ $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_history'));
+ $this->pageRenderer->addInlineSetting('Workspaces', 'id', (int)GeneralUtility::_GP('id'));
+
+ $this->assignExtensionSettings();
+ }
+
/**
* Renders the review module user dependent with all workspaces.
* The module will show all records of one workspace.
}
}
}
- /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
- $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
$this->pageRenderer->addInlineSetting('Workspaces', 'isLiveWorkspace', (int)$backendUser->workspace === 0);
$this->pageRenderer->addInlineSetting('Workspaces', 'workspaceTabs', $this->prepareWorkspaceTabs($wsList, $activeWorkspace));
$this->pageRenderer->addInlineSetting('Workspaces', 'activeWorkspaceId', $activeWorkspace);
- $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
$workspaceIsAccessible = !($backendUser->workspace === 0 && !$backendUser->isAdmin());
$this->view->assignMultiple([
'showGrid' => $workspaceIsAccessible,
'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace),
'activeWorkspaceUid' => $activeWorkspace,
'activeWorkspaceTitle' => WorkspaceService::getWorkspaceTitle($activeWorkspace),
- 'showPreviewLink' => $wsService->canCreatePreviewLink(GeneralUtility::_GP('id'), $activeWorkspace)
]);
if ($wsService->canCreatePreviewLink(GeneralUtility::_GP('id'), $activeWorkspace)) {
'showGrid' => true,
'showLegend' => true,
'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace),
- 'activeWorkspaceUid' => WorkspaceService::SELECT_ALL_WORKSPACES,
- 'showPreviewLink', false
+ 'activeWorkspaceUid' => WorkspaceService::SELECT_ALL_WORKSPACES
]);
$this->getBackendUser()->setAndSaveSessionData('tx_workspace_activeWorkspace', WorkspaceService::SELECT_ALL_WORKSPACES);
// set flag for javascript
$this->view->assignMultiple([
'pageUid' => (int)GeneralUtility::_GP('id'),
'showGrid' => true,
- 'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace, false),
+ 'workspaceList' => $this->prepareWorkspaceTabs($wsList, (int)$activeWorkspace, false),
'activeWorkspaceUid' => $activeWorkspace,
'backendDomain' => $backendDomain
]);
$this->pageRenderer->addInlineSetting('Workspaces', 'singleView', '1');
}
- /**
- * Initializes the controller before invoking an action method.
- */
- protected function initializeAction()
- {
- parent::initializeAction();
- $states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
- $this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
-
- foreach ($this->getAdditionalResourceService()->getLocalizationResources() as $localizationResource) {
- $this->pageRenderer->addInlineLanguageLabelFile($localizationResource);
- }
- /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
- $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-
- $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Backend');
- $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
- $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_history'));
- $this->pageRenderer->addInlineSetting('Workspaces', 'id', (int)GeneralUtility::_GP('id'));
- }
-
/**
* Prepares available workspace tabs.
*
* @param bool $showAllWorkspaceTab
* @return array
*/
- protected function prepareWorkspaceTabs(array $workspaceList, $activeWorkspace, $showAllWorkspaceTab = true)
+ protected function prepareWorkspaceTabs(array $workspaceList, int $activeWorkspace, bool $showAllWorkspaceTab = true)
{
$tabs = [];
* @param int $workspaceId
* @return string
*/
- protected function getModuleUri($workspaceId)
+ protected function getModuleUri(int $workspaceId): string
{
$parameters = [
- 'id' => (int)$this->pageId,
- 'workspace' => (int)$workspaceId,
+ 'id' => $this->pageId,
+ 'workspace' => $workspaceId,
];
// The "all workspaces" tab is handled in fullIndexAction
// which is required as additional GET parameter in the URI then
$this->uriBuilder->reset()->uriFor('fullIndex');
$parameters = array_merge($parameters, $this->uriBuilder->getArguments());
}
- /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
- $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
+ /** @var UriBuilder $uriBuilder */
+ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
return (string)$uriBuilder->buildUriFromRoute('web_WorkspacesWorkspaces', $parameters);
}
/**
- * @return \TYPO3\CMS\Core\Localization\LanguageService
+ * Assigns additional Workspace settings to TYPO3.settings.Workspaces.extension
+ */
+ protected function assignExtensionSettings()
+ {
+ $extension = [
+ 'AdditionalColumn' => [
+ 'Definition' => [],
+ 'Handler' => [],
+ ],
+ ];
+
+ $extension['AdditionalColumn']['Definition'] = $this->getAdditionalColumnService()->getDefinition();
+ $extension['AdditionalColumn']['Handler'] = $this->getAdditionalColumnService()->getHandler();
+ $this->pageRenderer->addInlineSetting('Workspaces', 'extension', $extension);
+ }
+
+ /**
+ * Gets the selected language.
+ *
+ * @return string
+ */
+ protected function getLanguageSelection(): string
+ {
+ $language = 'all';
+ $backendUser = $this->getBackendUser();
+ if (isset($backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'])) {
+ $language = $backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'];
+ }
+ return $language;
+ }
+
+ /**
+ * @return AdditionalColumnService
+ */
+ protected function getAdditionalColumnService(): AdditionalColumnService
+ {
+ return $this->objectManager->get(AdditionalColumnService::class);
+ }
+
+ /**
+ * @return AdditionalResourceService
+ */
+ protected function getAdditionalResourceService(): AdditionalResourceService
+ {
+ return $this->objectManager->get(AdditionalResourceService::class);
+ }
+
+ /**
+ * @return PageRenderer
+ */
+ protected function getPageRenderer(): PageRenderer
+ {
+ return GeneralUtility::makeInstance(PageRenderer::class);
+ }
+
+ /**
+ * @return LanguageService
*/
- protected function getLanguageService()
+ protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
/**
* @return BackendUserAuthentication
*/
- protected function getBackendUser()
+ protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
<?php
+declare(strict_types = 1);
namespace TYPO3\CMS\Workspaces\Hook;
/*
* The TYPO3 project - inspiring people to share!
*/
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Workspaces\Service\StagesService;
+use TYPO3\CMS\Workspaces\Service\WorkspaceService;
/**
* Befunc service
*/
-class BackendUtilityHook implements \TYPO3\CMS\Core\SingletonInterface
+class BackendUtilityHook implements SingletonInterface
{
/**
* Gets a singleton instance of this object.
*
- * @return \TYPO3\CMS\Workspaces\Hook\BackendUtilityHook
+ * @return BackendUtilityHook
*/
public static function getInstance()
{
public function preProcess(&$pageUid, $backPath, $rootLine, $anchorSection, &$viewScript, $additionalGetVars, $switchFocus)
{
if ($GLOBALS['BE_USER']->workspace !== 0) {
- $viewScript = $this->getWorkspaceService()->generateWorkspaceSplittedPreviewLink($pageUid);
+ $viewScript = GeneralUtility::makeInstance(WorkspaceService::class)->generateWorkspaceSplittedPreviewLink($pageUid);
}
}
- /**
- * Gets an instance of the workspaces service.
- *
- * @return \TYPO3\CMS\Workspaces\Service\WorkspaceService
- */
- protected function getWorkspaceService()
- {
- return GeneralUtility::makeInstance(\TYPO3\CMS\Workspaces\Service\WorkspaceService::class);
- }
-
/**
* Use that hook to show an info message in case someone starts editing
* a staged element
public function makeEditForm_accessCheck($params)
{
if ($GLOBALS['BE_USER']->workspace !== 0 && $GLOBALS['TCA'][$params['table']]['ctrl']['versioningWS']) {
- $record = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordWSOL($params['table'], $params['uid']);
- if (abs($record['t3ver_stage']) > \TYPO3\CMS\Workspaces\Service\StagesService::STAGE_EDIT_ID) {
- $stages = GeneralUtility::makeInstance(\TYPO3\CMS\Workspaces\Service\StagesService::class);
+ $record = BackendUtility::getRecordWSOL($params['table'], $params['uid']);
+ if (abs($record['t3ver_stage']) > StagesService::STAGE_EDIT_ID) {
+ $stages = GeneralUtility::makeInstance(StagesService::class);
$stageName = $stages->getStageTitle($record['t3ver_stage']);
- $editingName = $stages->getStageTitle(\TYPO3\CMS\Workspaces\Service\StagesService::STAGE_EDIT_ID);
+ $editingName = $stages->getStageTitle(StagesService::STAGE_EDIT_ID);
$message = $GLOBALS['LANG']->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:info.elementAlreadyModified');
- $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, sprintf($message, $stageName, $editingName), '', \TYPO3\CMS\Core\Messaging\FlashMessage::INFO, true);
- /** @var $flashMessageService \TYPO3\CMS\Core\Messaging\FlashMessageService */
- $flashMessageService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class);
+ $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, sprintf($message, $stageName, $editingName), '', FlashMessage::INFO, true);
+ /** @var $flashMessageService FlashMessageService */
+ $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
/** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
$defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
$defaultFlashMessageQueue->enqueue($flashMessage);
{
$backendDomain = $GLOBALS['BE_USER']->getSessionData('workspaces.backend_domain') ?: $normalizedParams->getRequestHostOnly();
- $content = $tsfe->cObj->cObjGetSingle('FLUIDTEMPLATE', [
- 'file' => 'EXT:workspaces/Resources/Private/Templates/Preview/Preview.html',
- 'variables.' => [
- 'backendDomain' => 'TEXT',
- 'backendDomain.' => ['value' => $backendDomain]
- ]
- ]);
+ $content = '<script type="text/javascript">
+ // having this is very important, otherwise the parent.resize call will fail
+ document.domain = ' . GeneralUtility::quoteJSvalue($backendDomain) . ';
+</script>';
if (!isset($tsfe->config['config']['disablePreviewNotification']) || (int)$tsfe->config['config']['disablePreviewNotification'] !== 1) {
// get the title of the current workspace
*/
use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
// Directly use pid value and consider move placeholders
$previewPageId = (empty($movePlaceholder['pid']) ? $liveRecord['pid'] : $movePlaceholder['pid']);
- $additionalParameters = '&tx_workspaces_web_workspacesworkspaces[previewWS]=' . $versionRecord['t3ver_wsid'];
+ $additionalParameters = '&previewWS=' . $versionRecord['t3ver_wsid'];
// Add language parameter if record is a localization
if (BackendUtility::isTableLocalizable($table)) {
$languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'];
if ($uid > 0) {
$uid = $this->getLivePageUid($uid);
}
- /** @var $uriBuilder \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder */
- $uriBuilder = $this->getObjectManager()->get(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
- $redirect = 'index.php?redirect_url=';
- $viewScript = $uriBuilder
- ->setArguments(['route' => '/web/WorkspacesWorkspaces/'])
- ->uriFor('index', [], 'Preview', 'workspaces', 'web_workspacesworkspaces') . '&id=';
+ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+ // the actual uid will be appended directly in BackendUtility Hook
+ $viewScript = $uriBuilder->buildUriFromRoute('workspace_previewcontrols', ['id' => '']);
if ($addDomain === true) {
- return BackendUtility::getViewDomain($uid) . $redirect . urlencode($viewScript) . $uid;
+ $viewScript = $uriBuilder->buildUriFromRoute('workspace_previewcontrols', ['id' => $uid]);
+ return BackendUtility::getViewDomain($uid) . 'index.php?redirect_url=' . urlencode($viewScript);
}
return $viewScript;
}
--- /dev/null
+<?php
+/**
+ * Definitions for routes provided by EXT:workspaces
+ */
+return [
+ 'workspace_previewcontrols' => [
+ 'path' => '/workspace/preview-control/',
+ 'target' => \TYPO3\CMS\Workspaces\Controller\PreviewController::class . '::handleRequest'
+ ]
+];
+++ /dev/null
-<f:render section="main" />
\ No newline at end of file
+++ /dev/null
-<f:render section="main" />
-<script type="text/javascript">
- document.domain = '{backendDomain}';
-</script>
<dd><span class="item-state-hidden"><f:translate key="legend.hidden" /></span> • </dd>
<dd><span class="item-state-deleted"><f:translate key="legend.deleted" /></span></dd>
</dl>
-</html>
\ No newline at end of file
+</html>
<input type="button" class="btn btn-sm btn-success" value="{nextStage}" data-stage-id="{nextStageId}" data-action="send-to-stage" data-direction="next">
</f:if>
<f:if condition="{enableDiscardStageButton}">
- <input type="button" class="btn btn-sm btn-danger" value="{f:translate(key: 'label_doaction_discard')}" data-action="discard">
+ <input type="button" class="btn btn-sm btn-danger" value="{f:translate(key: 'label_doaction_discard', extensionName: 'workspaces')}" data-action="discard">
</f:if>
-</html>
\ No newline at end of file
+</html>
+++ /dev/null
-<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
-<f:layout name="nodoc" />
-
-<f:section name="main">Help contents - not yet defined</f:section>
-</html>
\ No newline at end of file
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
-<f:layout name="popup" />
-
-<f:section name="main">
- <div id="typo3-topbar">
- <div class="typo3-topbar-container" role="navigation" id="typo3-top-container">
- <div class="typo3-topbar-site">
- <a class="typo3-topbar-site-logo" href="{logoLink}" target="_blank">
- <img src="{logoUrl}" width="{logoWidth}" height="{logoHeight}" title="TYPO3 Content Management System" alt="">
- </a>
- <span class="typo3-topbar-site-name">{activeWorkspace}</span>
- </div>
- <div class="typo3-topbar-tabs t3js-workspace-tabs">
- <ul class="nav nav-tabs" role="tablist">
- <li role="presentation" class="active"><a href="#visual" aria-controls="visual" role="tab" data-toggle="tab" data-actions="true"><f:translate key="preview.visualPreview" /></a></li>
- <li role="presentation"><a href="#list" aria-controls="list" role="tab" data-toggle="tab" data-actions="false"><f:translate key="preview.listView" /></a></li>
- </ul>
- </div>
- <div class="typo3-topbar-workspace-actions t3js-workspace-actions">
+<div id="typo3-topbar">
+ <div class="typo3-topbar-container" role="navigation" id="typo3-top-container">
+ <div class="typo3-topbar-site">
+ <a class="typo3-topbar-site-logo" href="{logoLink}" target="_blank">
+ <img src="{f:uri.resource(path: 'Images/typo3_logo_orange.svg', extensionName: 'backend')}" width="22" height="22" title="TYPO3 Content Management System" alt="">
+ </a>
+ <span class="typo3-topbar-site-name">{activeWorkspace}</span>
+ </div>
+ <div class="typo3-topbar-tabs t3js-workspace-tabs">
+ <ul class="nav nav-tabs" role="tablist">
+ <li role="presentation" class="active"><a href="#visual" aria-controls="visual" role="tab" data-toggle="tab" data-actions="true"><f:translate key="preview.visualPreview" extensionName="workspaces" /></a></li>
+ <li role="presentation"><a href="#list" aria-controls="list" role="tab" data-toggle="tab" data-actions="false"><f:translate key="preview.listView" extensionName="workspaces" /></a></li>
+ </ul>
+ </div>
+ <div class="typo3-topbar-workspace-actions t3js-workspace-actions">
+ <f:if condition="{liveUrl}">
<div class="workspace-action">
<div class="slider-wrapper">
<span>Published Version</span><div
<span>Staged Version</span>
</div>
</div>
- <div class="workspace-action t3js-stage-buttons">
- <f:render partial="Preview/StageButtons" arguments="{_all}"/>
- </div>
- <div class="workspace-action t3js-preview-mode">
- <div class="btn-group">
- <button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
- <span class="t3js-active-preview-mode active-preview-mode" data-active-preview-mode="{firstPreviewMode}"><f:translate key="preview.mode{firstPreviewMode -> f:format.case(mode: 'capital')}" /></span> <span class="caret"></span>
- </button>
- <ul class="dropdown-menu dropdown-menu-right">
- <f:for each="{splitPreviewModes}" as="mode">
- <li><a href="#" data-preview-mode="{mode}"><span><f:translate key="preview.mode{mode -> f:format.case(mode: 'capital')}" /></span></a></li>
- </f:for>
- </ul>
- </div>
- </div>
+ </f:if>
+ <div class="workspace-action t3js-stage-buttons">
+ <f:render partial="Preview/StageButtons" arguments="{_all}"/>
+ </div>
+ <div class="workspace-action t3js-preview-mode">
+ <f:if condition="{liveUrl}">
+ <f:then>
+ <div class="btn-group">
+ <button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <span class="t3js-active-preview-mode active-preview-mode" data-active-preview-mode="{firstPreviewMode}"><f:translate key="preview.mode{firstPreviewMode -> f:format.case(mode: 'capital')}" extensionName="workspaces" /></span> <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu dropdown-menu-right">
+ <f:for each="{splitPreviewModes}" as="mode">
+ <li><a href="#" data-preview-mode="{mode}"><span><f:translate key="preview.mode{mode -> f:format.case(mode: 'capital')}" extensionName="workspaces" /></span></a></li>
+ </f:for>
+ </ul>
+ </div>
+ </f:then>
+ <f:else>
+ <span><f:translate key="info.newpage.detail" extensionName="workspaces" /></span>
+ </f:else>
+ </f:if>
</div>
</div>
</div>
+</div>
- <div role="tabpanel" class="workspace-panel">
- <div class="tab-content">
- <div role="tabpanel" class="tab-pane active workspaces preview-mode-slider" id="visual">
- <div class="t3js-workspace-preview">
+<div role="tabpanel" class="workspace-panel">
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane active workspaces preview-mode-slider" id="visual">
+ <div class="t3js-workspace-preview">
+ <f:if condition="{liveUrl}">
<iframe src="{liveUrl}" style="height: 0px;" id="live-view"></iframe>
- <iframe src="{wsUrl}" id="workspace-view"></iframe>
- </div>
- </div>
- <div role="tabpanel" class="tab-pane workspaces" id="list">
- <iframe src="{wsSettingsUrl}" id="workspace-list"></iframe>
+ </f:if>
+ <iframe src="{wsUrl}" id="workspace-view"></iframe>
</div>
</div>
-
+ <div role="tabpanel" class="tab-pane workspaces" id="list">
+ <iframe src="{wsSettingsUrl}" id="workspace-list"></iframe>
+ </div>
</div>
-</f:section>
-</html>
\ No newline at end of file
+</div>
+<script type="text/javascript">
+ document.domain = '{backendDomain}';
+</script>
+</html>
+++ /dev/null
-<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
-<f:layout name="nodoc" />
-
-<f:section name="main"></f:section>
-</html>
\ No newline at end of file
+++ /dev/null
-<script type="text/javascript">
- // having this is very important, otherwise the parent.resize call will fail
- document.domain = '{backendDomain}';
-</script>
\ No newline at end of file
'before:info',
[
// An array holding the controller-action-combinations that are accessible
- 'Review' => 'index,fullIndex,singleIndex',
- 'Preview' => 'index,newPage'
+ 'Review' => 'index,fullIndex,singleIndex'
],
[
'access' => 'user,group',