[TASK] Refactor backend user module 91/51091/12
authorHelmut Hummel <typo3@helhum.io>
Mon, 2 Jan 2017 08:49:39 +0000 (09:49 +0100)
committerJigal van Hemert <jigal.van.hemert@typo3.org>
Thu, 30 Aug 2018 09:06:04 +0000 (11:06 +0200)
* Use module template view helpers to render the module layout
* Remove obsolete methods and inheritance
* Make compare view bookmarkable
* Remove obsolete returnUrl view variables
* Use xml syntax for Fluid namespace registration

Also move all module template related view helpers
to backend extension

Resolves: #85532
Releases: master
Change-Id: I3f8e63f57ac9cc5b8981dba23fe5652ea4adc3f1
Reviewed-on: https://review.typo3.org/51091
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Jigal van Hemert <jigal.van.hemert@typo3.org>
Tested-by: Jigal van Hemert <jigal.van.hemert@typo3.org>
23 files changed:
typo3/sysext/backend/Classes/Template/Components/Buttons/AbstractButton.php
typo3/sysext/backend/Classes/Template/ModuleTemplate.php
typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/AbstractButtonViewHelper.php [new file with mode: 0644]
typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/LinkButtonViewHelper.php [new file with mode: 0644]
typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/ShortcutButtonViewHelper.php [new file with mode: 0644]
typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/MenuItemViewHelper.php [new file with mode: 0644]
typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/MenuViewHelper.php [new file with mode: 0644]
typo3/sysext/backend/Classes/ViewHelpers/ModuleLayoutViewHelper.php [new file with mode: 0644]
typo3/sysext/belog/Resources/Private/Layouts/Default.html
typo3/sysext/beuser/Classes/Controller/BackendUserActionController.php [deleted file]
typo3/sysext/beuser/Classes/Controller/BackendUserController.php
typo3/sysext/beuser/Classes/Controller/BackendUserGroupController.php
typo3/sysext/beuser/Resources/Private/Language/locallang.xlf
typo3/sysext/beuser/Resources/Private/Layouts/Default.html
typo3/sysext/beuser/Resources/Private/Partials/BackendUser/IndexListRow.html
typo3/sysext/beuser/Resources/Private/Partials/BackendUser/PaginatedListWidgetBody.html
typo3/sysext/beuser/Resources/Private/Partials/BackendUserGroup/IndexListRow.html
typo3/sysext/beuser/Resources/Private/Partials/BackendUserGroup/PaginatedListWidgetBody.html
typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Compare.html
typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Index.html
typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Online.html
typo3/sysext/beuser/Resources/Private/Templates/BackendUserGroup/Index.html
typo3/sysext/fluid/Classes/ViewHelpers/Be/ModuleLayoutViewHelper.php [deleted file]

index a97d36e..4983302 100644 (file)
@@ -30,13 +30,6 @@ class AbstractButton extends AbstractControl implements ButtonInterface
     protected $icon;
 
     /**
-     * ButtonType
-     *
-     * @var string
-     */
-    protected $type;
-
-    /**
      * Defines whether to show the title as a label within the button
      *
      * @var bool
index 3c14910..e9d4c8c 100644 (file)
@@ -522,7 +522,7 @@ class ModuleTemplate
      */
     public function makeShortcutIcon($gvList, $setList, $modName, $motherModName = '', $displayName = '', $classes = 'btn btn-default btn-sm')
     {
-        $gvList = 'route,' . $gvList;
+        $gvList = 'route,id,' . $gvList;
         $storeUrl = $this->makeShortcutUrl($gvList, $setList);
         $pathInfo = parse_url(GeneralUtility::getIndpEnv('REQUEST_URI'));
         // Fallback for alt_mod. We still pass in the old xMOD... stuff,
diff --git a/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/AbstractButtonViewHelper.php b/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/AbstractButtonViewHelper.php
new file mode 100644 (file)
index 0000000..4803031
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Backend\ViewHelpers\ModuleLayout\Button;
+
+/*
+ * 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\Template\Components\ButtonBar;
+use TYPO3\CMS\Backend\Template\Components\Buttons\AbstractButton;
+use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
+use TYPO3\CMS\Backend\ViewHelpers\ModuleLayoutViewHelper;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
+use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
+use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;
+use TYPO3Fluid\Fluid\View\Exception;
+
+abstract class AbstractButtonViewHelper extends AbstractViewHelper
+{
+    use CompileWithRenderStatic;
+
+    /**
+     * Initialize arguments.
+     *
+     * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
+     */
+    public function initializeArguments(): void
+    {
+        $this->registerArgument('icon', 'string', 'Icon identifier for the button');
+        $this->registerArgument('title', 'string', 'Title of the button');
+        $this->registerArgument('disabled', 'bool', 'Whether the button is disabled', false, false);
+        $this->registerArgument('showLabel', 'bool', 'Defines whether to show the title as a label within the button', false, false);
+        $this->registerArgument('position', 'string', 'Position of the button (left or right)');
+        $this->registerArgument('group', 'integer', 'Button group of the button');
+    }
+
+    /**
+     * @param array $arguments
+     * @param \Closure $renderChildrenClosure
+     * @param RenderingContextInterface $renderingContext
+     * @throws \InvalidArgumentException
+     * @throws \TYPO3Fluid\Fluid\View\Exception
+     */
+    public static function renderStatic(
+        array $arguments,
+        \Closure $renderChildrenClosure,
+        RenderingContextInterface $renderingContext
+    ): void {
+        $viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
+        self::ensureProperNesting($viewHelperVariableContainer);
+
+        /** @var ModuleTemplate $moduleTemplate */
+        $moduleTemplate = $viewHelperVariableContainer->get(ModuleLayoutViewHelper::class, ModuleTemplate::class);
+        $buttonBar = $moduleTemplate->getDocHeaderComponent()->getButtonBar();
+
+        $position = $arguments['position'] ?? ButtonBar::BUTTON_POSITION_LEFT;
+        $group = $arguments['group'] ?? 1;
+        $button = static::createButton($buttonBar, $arguments, $renderingContext);
+        if ($button instanceof AbstractButton) {
+            self::addDefaultAttributes($button, $arguments, $renderingContext);
+        }
+        $buttonBar->addButton($button, $position, $group);
+    }
+
+    abstract protected static function createButton(ButtonBar $buttonBar, array $arguments, RenderingContextInterface $renderingContext): ButtonInterface;
+
+    /**
+     * @param ViewHelperVariableContainer $viewHelperVariableContainer
+     * @throws Exception
+     */
+    private static function ensureProperNesting(ViewHelperVariableContainer $viewHelperVariableContainer): void
+    {
+        if (!$viewHelperVariableContainer->exists(ModuleLayoutViewHelper::class, ModuleTemplate::class)) {
+            throw new Exception(sprintf('%s must be nested in <f.be.moduleLayout> view helper', self::class), 1531216505);
+        }
+    }
+
+    private static function addDefaultAttributes(AbstractButton $button, array $arguments, RenderingContextInterface $renderingContext): void
+    {
+        if (isset($arguments['title'])) {
+            $button->setTitle($arguments['title']);
+        }
+        /** @var ModuleTemplate $moduleTemplate */
+        $moduleTemplate = $renderingContext->getViewHelperVariableContainer()->get(ModuleLayoutViewHelper::class, ModuleTemplate::class);
+        $button->setIcon($moduleTemplate->getIconFactory()->getIcon($arguments['icon'], Icon::SIZE_SMALL));
+    }
+}
diff --git a/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/LinkButtonViewHelper.php b/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/LinkButtonViewHelper.php
new file mode 100644 (file)
index 0000000..ee7ff6d
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Backend\ViewHelpers\ModuleLayout\Button;
+
+/*
+ * 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\Template\Components\ButtonBar;
+use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+
+/**
+ * A view helper for adding a link button to the doc header area.
+ * It must be a child of <be:moduleLayout>
+ * = Examples =
+ * <code>
+ * <be:moduleLayout>
+ *      <be:moduleLayout.button.linkButton
+ *          icon="actions-add"
+ *          title="Add record')}"
+ *          link="{be:uri.newRecord(table: 'tx_my_table')}"
+ *      />
+ * </be:moduleLayout>
+ * </code>
+ */
+class LinkButtonViewHelper extends AbstractButtonViewHelper
+{
+    /**
+     * Initialize arguments.
+     *
+     * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
+     */
+    public function initializeArguments(): void
+    {
+        parent::initializeArguments();
+        $this->registerArgument('link', 'string', 'Link for the button', true);
+    }
+
+    protected static function createButton(ButtonBar $buttonBar, array $arguments, RenderingContextInterface $renderingContext): ButtonInterface
+    {
+        return $buttonBar->makeLinkButton()->setHref($arguments['link']);
+    }
+}
diff --git a/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/ShortcutButtonViewHelper.php b/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/Button/ShortcutButtonViewHelper.php
new file mode 100644 (file)
index 0000000..d8253bb
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Backend\ViewHelpers\ModuleLayout\Button;
+
+/*
+ * 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\Template\Components\ButtonBar;
+use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
+use TYPO3\CMS\Extbase\Service\ExtensionService;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+
+/**
+ * A view helper for adding a shortcut button to the doc header area.
+ * It must be a child of <be:moduleLayout>
+ * = Examples =
+ * <code>
+ * <be:moduleLayout>
+ *      <be:moduleLayout.button.shortcutButton displayName="Shortcut label" />
+ * </be:moduleLayout>
+ * </code>
+ */
+class ShortcutButtonViewHelper extends AbstractButtonViewHelper
+{
+    /**
+     * Initialize arguments.
+     *
+     * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
+     */
+    public function initializeArguments(): void
+    {
+        parent::initializeArguments();
+        $this->registerArgument('displayName', 'string', 'Name for the shortcut');
+        $this->registerArgument('getVars', 'array', 'List of additional GET variables to store. The current id, module and all module arguments will always be stored', false, []);
+    }
+
+    protected static function createButton(ButtonBar $buttonBar, array $arguments, RenderingContextInterface $renderingContext): ButtonInterface
+    {
+        $currentRequest = $renderingContext->getControllerContext()->getRequest();
+        $extensionName = $currentRequest->getControllerExtensionName();
+        $moduleName = $currentRequest->getPluginName();
+        $argumentPrefix = GeneralUtility::makeInstance(ObjectManager::class)
+            ->get(ExtensionService::class)
+            ->getPluginNamespace($extensionName, $moduleName);
+
+        $getVars = $arguments['getVars'];
+        $getVars[] = $argumentPrefix;
+
+        $shortcutButton = $buttonBar->makeShortcutButton()
+            ->setDisplayName($arguments['displayName'])
+            ->setGetVariables($getVars)
+            ->setModuleName($moduleName);
+
+        return $shortcutButton;
+    }
+}
diff --git a/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/MenuItemViewHelper.php b/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/MenuItemViewHelper.php
new file mode 100644 (file)
index 0000000..0bbcc0a
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Backend\ViewHelpers\ModuleLayout;
+
+/*
+ * 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\Template\Components\Menu\Menu;
+use TYPO3\CMS\Backend\ViewHelpers\ModuleLayoutViewHelper;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
+use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
+use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;
+use TYPO3Fluid\Fluid\View\Exception;
+
+/**
+ * A view helper for adding a menu item to a doc header menu.
+ * It must be a child of <be:moduleLayout.menu>
+ * = Examples =
+ * <code>
+ * <be:moduleLayout>
+ *     <be:moduleLayout.menu identifier="MenuIdentifier">
+ *          <be:moduleLayout.menuItem label="Menu item 1" uri="{f:uri.action(action: 'index')}"/>
+ *     </be:moduleLayout.menu>
+ * </be:moduleLayout>
+ * </code>
+ */
+class MenuItemViewHelper extends AbstractViewHelper
+{
+    use CompileWithRenderStatic;
+
+    /**
+     * Initialize arguments.
+     *
+     * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
+     */
+    public function initializeArguments()
+    {
+        parent::initializeArguments();
+        $this->registerArgument('label', 'string', 'Label of the menu item', true);
+        $this->registerArgument('uri', 'string', 'Action uri', true);
+    }
+
+    /**
+     * @param array $arguments
+     * @param \Closure $renderChildrenClosure
+     * @param RenderingContextInterface $renderingContext
+     * @throws Exception
+     * @throws \InvalidArgumentException
+     */
+    public static function renderStatic(
+        array $arguments,
+        \Closure $renderChildrenClosure,
+        RenderingContextInterface $renderingContext
+    ) {
+        $viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
+        self::ensureProperNesting($viewHelperVariableContainer);
+
+        /** @var Menu $menu */
+        $menu = $viewHelperVariableContainer->get(ModuleLayoutViewHelper::class, Menu::class);
+        $menuItem = $menu->makeMenuItem();
+        $menuItem->setTitle($arguments['label']);
+        $menuItem->setHref($arguments['uri']);
+        $menuItem->setActive(self::isCurrentUri($arguments['uri']));
+        $menu->addMenuItem($menuItem);
+    }
+
+    /**
+     * @param ViewHelperVariableContainer $viewHelperVariableContainer
+     * @throws Exception
+     */
+    private static function ensureProperNesting(ViewHelperVariableContainer $viewHelperVariableContainer): void
+    {
+        if (!$viewHelperVariableContainer->exists(ModuleLayoutViewHelper::class, Menu::class)) {
+            throw new Exception(sprintf('%s must be nested in <f.be.moduleLayout.menu> view helper', self::class), 1531235592);
+        }
+    }
+
+    /**
+     * @param string $uri
+     * @return bool
+     */
+    protected static function isCurrentUri(string $uri): bool
+    {
+        return GeneralUtility::getIndpEnv('REQUEST_URI') === $uri;
+    }
+}
diff --git a/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/MenuViewHelper.php b/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayout/MenuViewHelper.php
new file mode 100644 (file)
index 0000000..0cdc6b6
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Backend\ViewHelpers\ModuleLayout;
+
+/*
+ * 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\Template\Components\Menu\Menu;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
+use TYPO3\CMS\Backend\ViewHelpers\ModuleLayoutViewHelper;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
+use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
+use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;
+use TYPO3Fluid\Fluid\View\Exception;
+
+/**
+ * A view helper for adding a menu to the doc header area.
+ * It must be a child of <be:moduleLayout> and accepts
+ * only <be:moduleLayout.menuItem> view helpers as children.
+ * = Examples =
+ * <code>
+ * <be:moduleLayout>
+ *     <be:moduleLayout.menu identifier="MenuIdentifier">
+ *          <be:moduleLayout.menuItem label="Menu item 1" uri="{f:uri.action(action: 'index')}"/>
+ *     </be:moduleLayout.menu>
+ * </be:moduleLayout>
+ * </code>
+ */
+class MenuViewHelper extends AbstractViewHelper
+{
+    use CompileWithRenderStatic;
+
+    /**
+     * Initialize arguments.
+     *
+     * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
+     */
+    public function initializeArguments()
+    {
+        $this->registerArgument('identifier', 'string', 'Identifier of the menu', true);
+    }
+
+    /**
+     * @param array $arguments
+     * @param \Closure $renderChildrenClosure
+     * @param RenderingContextInterface $renderingContext
+     * @throws Exception
+     */
+    public static function renderStatic(
+        array $arguments,
+        \Closure $renderChildrenClosure,
+        RenderingContextInterface $renderingContext
+    ) {
+        $viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
+        self::ensureProperNesting($viewHelperVariableContainer);
+
+        /** @var ModuleTemplate $moduleTemplate */
+        $moduleTemplate = $viewHelperVariableContainer->get(ModuleLayoutViewHelper::class, ModuleTemplate::class);
+        $menu = $moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
+        $menu->setIdentifier($arguments['identifier']);
+
+        $viewHelperVariableContainer->add(ModuleLayoutViewHelper::class, Menu::class, $menu);
+        $renderChildrenClosure();
+        $moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
+        $viewHelperVariableContainer->remove(ModuleLayoutViewHelper::class, Menu::class);
+    }
+
+    /**
+     * @param ViewHelperVariableContainer $viewHelperVariableContainer
+     * @throws Exception
+     */
+    private static function ensureProperNesting(ViewHelperVariableContainer $viewHelperVariableContainer): void
+    {
+        if (!$viewHelperVariableContainer->exists(ModuleLayoutViewHelper::class, ModuleTemplate::class)) {
+            throw new Exception(sprintf('%s must be nested in <f.be.moduleLayout> view helper', self::class), 1531235715);
+        }
+        if ($viewHelperVariableContainer->exists(ModuleLayoutViewHelper::class, Menu::class)) {
+            throw new Exception(sprintf('%s can not be nested in <f.be.moduleLayout.menu> view helper', self::class), 1531235777);
+        }
+    }
+}
diff --git a/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayoutViewHelper.php b/typo3/sysext/backend/Classes/ViewHelpers/ModuleLayoutViewHelper.php
new file mode 100644 (file)
index 0000000..dbac1a7
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Backend\ViewHelpers;
+
+/*
+ * 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\Template\ModuleTemplate;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
+use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
+use TYPO3Fluid\Fluid\View\Exception;
+
+/**
+ * A view helper for having properly styled backend modules.
+ * It is recommended to use it in Fluid Layouts.
+ * It will render the required HTML for the doc header.
+ * All module specific output and further configuration of the doc header
+ * must be rendered as children of this view helper.
+ * = Examples =
+ * <code>
+ * <be:moduleLayout>
+ *     <f:render section="content" />
+ * </be:moduleLayout>
+ * </code>
+ * <output>
+ * <!-- HTML of the backend module -->
+ * </output>
+ */
+class ModuleLayoutViewHelper extends AbstractViewHelper
+{
+    use CompileWithRenderStatic;
+
+    /**
+     * @var bool
+     */
+    protected $escapeOutput = false;
+
+    public static function renderStatic(
+        array $arguments,
+        \Closure $renderChildrenClosure,
+        RenderingContextInterface $renderingContext
+    ) {
+        $viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
+        if ($viewHelperVariableContainer->exists(self::class, ModuleTemplate::class)) {
+            throw new Exception('ModuleLayoutViewHelper can only be used once per module.', 1483292643);
+        }
+
+        $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+        $moduleTemplate->setFlashMessageQueue($renderingContext->getControllerContext()->getFlashMessageQueue());
+
+        $viewHelperVariableContainer->add(self::class, ModuleTemplate::class, $moduleTemplate);
+        $moduleTemplate->setContent($renderChildrenClosure());
+        $viewHelperVariableContainer->remove(self::class, ModuleTemplate::class);
+
+        return $moduleTemplate->renderContent();
+    }
+}
index 0712c33..502aceb 100644 (file)
@@ -1,9 +1,10 @@
 <html
     xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
     data-namespace-typo3-fluid="true">
 
-<f:be.moduleLayout>
+<be:moduleLayout>
        <f:render section="Content" />
-</f:be.moduleLayout>
+</be:moduleLayout>
 
 </html>
diff --git a/typo3/sysext/beuser/Classes/Controller/BackendUserActionController.php b/typo3/sysext/beuser/Classes/Controller/BackendUserActionController.php
deleted file mode 100644 (file)
index a38370d..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-<?php
-namespace TYPO3\CMS\Beuser\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\Template\Components\ButtonBar;
-use TYPO3\CMS\Backend\View\BackendTemplateView;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
-use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
-use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
-
-/**
- * Backend module user/group action controller
- */
-class BackendUserActionController extends ActionController
-{
-    /**
-     * Backend Template Container
-     *
-     * @var string
-     */
-    protected $defaultViewObjectName = BackendTemplateView::class;
-
-    /**
-     * BackendTemplateContainer
-     *
-     * @var BackendTemplateView
-     */
-    protected $view;
-
-    /**
-     * Set up the doc header properly here
-     *
-     * @param ViewInterface $view
-     */
-    protected function initializeView(ViewInterface $view)
-    {
-        /** @var BackendTemplateView $view */
-        parent::initializeView($view);
-        if ($this->actionMethodName === 'indexAction'
-            || $this->actionMethodName === 'onlineAction'
-            || $this->actionMethodName === 'compareAction') {
-            $this->generateMenu();
-            $this->registerDocheaderButtons();
-            $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
-        }
-        if ($view instanceof BackendTemplateView) {
-            $view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Modal');
-        }
-    }
-
-    /**
-     * Generates the action menu
-     */
-    protected function generateMenu()
-    {
-        $menuItems = [
-            'index' => [
-                'controller' => 'BackendUser',
-                'action' => 'index',
-                'label' => $this->getLanguageService()->sL('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:backendUsers')
-            ],
-            'pages' => [
-                'controller' => 'BackendUserGroup',
-                'action' => 'index',
-                'label' => $this->getLanguageService()->sL('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:backendUserGroupsMenu')
-            ],
-            'online' => [
-                'controller' => 'BackendUser',
-                'action' => 'online',
-                'label' => $this->getLanguageService()->sL('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:onlineUsers')
-            ]
-        ];
-        $uriBuilder = $this->objectManager->get(UriBuilder::class);
-        $uriBuilder->setRequest($this->request);
-
-        $menu = $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
-        $menu->setIdentifier('BackendUserModuleMenu');
-
-        foreach ($menuItems as  $menuItemConfig) {
-            if ($this->request->getControllerName() === $menuItemConfig['controller']) {
-                $isActive = $this->request->getControllerActionName() === $menuItemConfig['action'] ? true : false;
-            } else {
-                $isActive = false;
-            }
-            $menuItem = $menu->makeMenuItem()
-                ->setTitle($menuItemConfig['label'])
-                ->setHref($this->getHref($menuItemConfig['controller'], $menuItemConfig['action']))
-                ->setActive($isActive);
-            $menu->addMenuItem($menuItem);
-        }
-
-        $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
-    }
-
-    /**
-     * Registers the Icons into the docheader
-     *
-     * @throws \InvalidArgumentException
-     */
-    protected function registerDocheaderButtons()
-    {
-        /** @var ButtonBar $buttonBar */
-        $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
-        $currentRequest = $this->request;
-        $moduleName = $currentRequest->getPluginName();
-        $getVars = $this->request->getArguments();
-
-        $extensionName = $currentRequest->getControllerExtensionName();
-        if (count($getVars) === 0) {
-            $modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
-            $getVars = ['id', 'route', $modulePrefix];
-        }
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-
-        $shortcutName = $this->getLanguageService()->sL('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:backendUsers');
-        if ($this->request->getControllerName() === 'BackendUser') {
-            if ($this->request->getControllerActionName() === 'index') {
-                $returnUrl = (string)$uriBuilder->buildUriFromRoute('system_BeuserTxBeuser');
-                $parameters = [
-                    'edit' => [
-                        'be_users' => [
-                            0 => 'new'
-                        ]
-                    ],
-                    'returnUrl' => $returnUrl,
-                ];
-                $addUserLink = (string)$uriBuilder->buildUriFromRoute('record_edit', $parameters);
-                $title = $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral');
-                $icon = $this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-add', Icon::SIZE_SMALL);
-                $addUserButton = $buttonBar->makeLinkButton()
-                    ->setHref($addUserLink)
-                    ->setTitle($title)
-                    ->setIcon($icon);
-                $buttonBar->addButton($addUserButton, ButtonBar::BUTTON_POSITION_LEFT);
-            }
-            if ($this->request->getControllerActionName() === 'compare') {
-                $addUserLink = (string)$uriBuilder->buildUriFromRoute('system_BeuserTxBeuser');
-                $title = $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack');
-                $icon = $this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL);
-                $addUserButton = $buttonBar->makeLinkButton()
-                    ->setHref($addUserLink)
-                    ->setTitle($title)
-                    ->setIcon($icon);
-                $buttonBar->addButton($addUserButton, ButtonBar::BUTTON_POSITION_LEFT);
-            }
-            if ($this->request->getControllerActionName() === 'online') {
-                $shortcutName = $this->getLanguageService()->sL('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:onlineUsers');
-            }
-        }
-        if ($this->request->getControllerName() === 'BackendUserGroup') {
-            $shortcutName = $this->getLanguageService()->sL('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:backendUserGroupsMenu');
-            $returnUrl = (string)$uriBuilder->buildUriFromRoute('system_BeuserTxBeuser', [
-                'tx_beuser_system_beusertxbeuser' => [
-                    'action' => 'index',
-                    'controller' => 'BackendUserGroup'
-                ]
-            ]);
-            $parameters = [
-                'edit' => [
-                    'be_groups' => [
-                        0 => 'new'
-                    ]
-                ],
-                'returnUrl' => $returnUrl,
-            ];
-            $addUserLink = (string)$uriBuilder->buildUriFromRoute('record_edit', $parameters);
-            $title = $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral');
-            $icon = $this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-add', Icon::SIZE_SMALL);
-            $addUserGroupButton = $buttonBar->makeLinkButton()
-                ->setHref($addUserLink)
-                ->setTitle($title)
-                ->setIcon($icon);
-            $buttonBar->addButton($addUserGroupButton, ButtonBar::BUTTON_POSITION_LEFT);
-        }
-        $shortcutButton = $buttonBar->makeShortcutButton()
-            ->setModuleName($moduleName)
-            ->setDisplayName($shortcutName)
-            ->setGetVariables($getVars);
-        $buttonBar->addButton($shortcutButton);
-    }
-
-    /**
-     * Creates te URI for a backend action
-     *
-     * @param string $controller
-     * @param string $action
-     * @param array $parameters
-     * @return string
-     */
-    protected function getHref($controller, $action, $parameters = [])
-    {
-        $uriBuilder = $this->objectManager->get(UriBuilder::class);
-        $uriBuilder->setRequest($this->request);
-        return $uriBuilder->reset()->uriFor($action, $parameters, $controller);
-    }
-
-    /**
-     * @return BackendUserAuthentication
-     */
-    protected function getBackendUserAuthentication()
-    {
-        return $GLOBALS['BE_USER'];
-    }
-
-    /**
-     * @return LanguageService
-     */
-    protected function getLanguageService()
-    {
-        return $GLOBALS['LANG'];
-    }
-}
index 116bffd..2a84890 100644 (file)
@@ -15,16 +15,17 @@ namespace TYPO3\CMS\Beuser\Controller;
  */
 
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
-use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\Session\Backend\SessionBackendInterface;
 use TYPO3\CMS\Core\Session\SessionManager;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 
 /**
  * Backend module user administration controller
  */
-class BackendUserController extends BackendUserActionController
+class BackendUserController extends ActionController
 {
     /**
      * @var int
@@ -109,20 +110,15 @@ class BackendUserController extends BackendUserActionController
     }
 
     /**
-     * Initialize actions
-     *
-     * @throws \RuntimeException
+     * Assign default variables to view
      */
-    public function initializeAction()
+    public function initializeView(ViewInterface $view)
     {
-        // @TODO: Extbase backend modules relies on frontend TypoScript for view, persistence
-        // and settings. Thus, we need a TypoScript root template, that then loads the
-        // ext_typoscript_setup.typoscript file of this module. This is nasty, but can not be
-        // circumvented until there is a better solution in extbase.
-        // For now we throw an exception if no settings are detected.
-        if (empty($this->settings)) {
-            throw new \RuntimeException('No settings detected. This module can not work then. This usually happens if there is no frontend TypoScript template with root flag set. ' . 'Please create a frontend page with a TypoScript root template.', 1344375003);
-        }
+        $view->assignMultiple([
+            'shortcutLabel' => 'backendUsers',
+            'dateFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],
+            'timeFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],
+        ]);
     }
 
     /**
@@ -153,21 +149,16 @@ class BackendUserController extends BackendUserActionController
                 $onlineBackendUsers[$onlineUser['ses_userid']] = true;
             }
         }
-        $this->view->assign('onlineBackendUsers', $onlineBackendUsers);
-
-        $this->view->assign('demand', $demand);
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-        $this->view->assign('returnUrl', (string)$uriBuilder->buildUriFromRoute('system_BeuserTxBeuser'));
-        $this->view->assign('dateFormat', $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']);
-        $this->view->assign('timeFormat', $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm']);
-        $this->view->assign('backendUsers', $this->backendUserRepository->findDemanded($demand));
-        $this->view->assign('backendUserGroups', array_merge([''], $this->backendUserGroupRepository->findAll()->toArray()));
-        $this->view->assign('compareUserUidList', array_map(function () {
-            return true;
-        }, array_flip((array)$compareUserList)));
-        $this->view->assign('currentUserUid', $this->getBackendUserAuthentication()->user['uid']);
-        $this->view->assign('compareUserList', !empty($compareUserList) ? $this->backendUserRepository->findByUidList($compareUserList) : '');
+
+        $this->view->assignMultiple([
+            'onlineBackendUsers' => $onlineBackendUsers,
+            'demand' => $demand,
+            'backendUsers' => $this->backendUserRepository->findDemanded($demand),
+            'backendUserGroups' => array_merge([''], $this->backendUserGroupRepository->findAll()->toArray()),
+            'compareUserUidList' => array_combine(array_keys($compareUserList), array_fill(0, count($compareUserList), true)),
+            'currentUserUid' => $this->getBackendUserAuthentication()->user['uid'],
+            'compareUserList' => !empty($compareUserList) ? $this->backendUserRepository->findByUidList($compareUserList) : '',
+        ]);
     }
 
     /**
@@ -183,10 +174,12 @@ class BackendUserController extends BackendUserActionController
                 'sessions' => $this->backendUserSessionRepository->findByBackendUser($onlineUser)
             ];
         }
-        $this->view->assign('dateFormat', $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']);
-        $this->view->assign('timeFormat', $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm']);
-        $this->view->assign('onlineUsersAndSessions', $onlineUsersAndSessions);
-        $this->view->assign('currentSessionId', $this->getBackendUserAuthentication()->user['ses_id']);
+
+        $this->view->assignMultiple([
+            'shortcutLabel' => 'onlineUsers',
+            'onlineUsersAndSessions' => $onlineUsersAndSessions,
+            'currentSessionId' => $this->getBackendUserAuthentication()->user['ses_id'],
+        ]);
     }
 
     /**
@@ -195,19 +188,14 @@ class BackendUserController extends BackendUserActionController
     public function compareAction()
     {
         $compareUserList = $this->moduleData->getCompareUserList();
-        $this->view->assign('dateFormat', $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']);
-        $this->view->assign('timeFormat', $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm']);
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-        $returnUrl = (string)$uriBuilder->buildUriFromRoute(
-            'system_BeuserTxBeuser',
-            [
-                'tx_beuser_system_beusertxbeuser[action]' => 'compare',
-                'tx_beuser_system_beusertxbeuser[controller]' => 'BackendUser'
-            ]
-        );
-        $this->view->assign('returnUrl', $returnUrl);
-        $this->view->assign('compareUserList', !empty($compareUserList) ? $this->backendUserRepository->findByUidList($compareUserList) : '');
+        if (empty($compareUserList)) {
+            $this->redirect('index');
+        }
+
+        $this->view->assignMultiple([
+            'shortcutLabel' => 'compareUsers',
+            'compareUserList' => $this->backendUserRepository->findByUidList($compareUserList),
+        ]);
     }
 
     /**
@@ -322,20 +310,12 @@ class BackendUserController extends BackendUserActionController
     /**
      * @return BackendUserAuthentication
      */
-    protected function getBackendUserAuthentication()
+    protected function getBackendUserAuthentication(): BackendUserAuthentication
     {
         return $GLOBALS['BE_USER'];
     }
 
     /**
-     * @return LanguageService
-     */
-    protected function getLanguageService()
-    {
-        return $GLOBALS['LANG'];
-    }
-
-    /**
      * @return SessionBackendInterface
      */
     protected function getSessionBackend()
index 00b3783..cc40b38 100644 (file)
@@ -14,12 +14,12 @@ namespace TYPO3\CMS\Beuser\Controller;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
 
 /**
  * Backend module user group administration controller
  */
-class BackendUserGroupController extends BackendUserActionController
+class BackendUserGroupController extends ActionController
 {
     /**
      * @var \TYPO3\CMS\Beuser\Domain\Repository\BackendUserGroupRepository
@@ -35,38 +35,15 @@ class BackendUserGroupController extends BackendUserActionController
     }
 
     /**
-     * Initialize actions
-     *
-     * @throws \RuntimeException
-     */
-    public function initializeAction()
-    {
-        // @TODO: Extbase backend modules relies on frontend TypoScript for view, persistence
-        // and settings. Thus, we need a TypoScript root template, that then loads the
-        // ext_typoscript_setup.typoscript file of this module. This is nasty, but can not be
-        // circumvented until there is a better solution in extbase.
-        // For now we throw an exception if no settings are detected.
-        if (empty($this->settings)) {
-            throw new \RuntimeException('No settings detected. This module can not work then. This usually happens if there is no frontend TypoScript template with root flag set. ' . 'Please create a frontend page with a TypoScript root template.', 1460976089);
-        }
-    }
-
-    /**
      * Displays all BackendUserGroups
      */
     public function indexAction()
     {
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-        $this->view->assign('backendUserGroups', $this->backendUserGroupRepository->findAll());
-        $this->view->assign('returnUrl', (string)$uriBuilder->buildUriFromRoute(
-            'system_BeuserTxBeuser',
+        $this->view->assignMultiple(
             [
-                'tx_beuser_system_beusertxbeuser' => [
-                    'action' => 'index',
-                    'controller' => 'BackendUserGroup'
-                ]
+                'shortcutLabel' => 'backendUserGroupsMenu',
+                'backendUserGroups' => $this->backendUserGroupRepository->findAll(),
             ]
-        ));
+        );
     }
 }
index ccee419..d2715fd 100644 (file)
                        <trans-unit id="backendUsers">
                                <source>Backend users</source>
                        </trans-unit>
+                       <trans-unit id="compareUsers">
+                               <source>Compare backend users</source>
+                       </trans-unit>
                        <trans-unit id="backendUserGroupsMenu">
                                <source>Backend user groups</source>
                        </trans-unit>
index f0df258..d792462 100644 (file)
@@ -1,8 +1,27 @@
-<f:be.pageRenderer
-       includeRequireJsModules="{
-               0:'TYPO3/CMS/Backend/ContextMenu'
-       }"
-/>
-
-<f:render section="headline" />
-<f:render section="content" />
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
+    data-namespace-typo3-fluid="true">
+
+<be:moduleLayout>
+       <f:be.pageRenderer
+               includeRequireJsModules="{
+                       0:'TYPO3/CMS/Backend/ContextMenu',
+                       1:'TYPO3/CMS/Backend/Modal'
+               }"
+       />
+
+       <be:moduleLayout.menu identifier="BackendUserModuleMenu">
+               <be:moduleLayout.menuItem label="{f:translate(id: 'backendUsers')}" uri="{f:uri.action(controller: 'BackendUser', action: 'index')}"/>
+               <be:moduleLayout.menuItem label="{f:translate(id: 'backendUserGroupsMenu')}" uri="{f:uri.action(controller: 'BackendUserGroup', action: 'index')}"/>
+               <be:moduleLayout.menuItem label="{f:translate(id: 'onlineUsers')}" uri="{f:uri.action(controller: 'BackendUser', action: 'online')}"/>
+       </be:moduleLayout.menu>
+
+       <f:render section="Buttons" />
+       <be:moduleLayout.button.shortcutButton displayName="{f:translate(id: shortcutLabel)}" />
+
+       <f:render section="Content" />
+
+</be:moduleLayout>
+
+</html>
index b2d6d20..0b9a8a8 100644 (file)
@@ -11,7 +11,7 @@
                </a>
        </td>
        <td class="col-title">
-               <be:link.editRecord table="be_users" uid="{backendUser.uid}" returnUrl="{returnUrl}" title="edit">
+               <be:link.editRecord table="be_users" uid="{backendUser.uid}" title="edit">
                        <b>{backendUser.userName}</b>
                </be:link.editRecord>
                <f:if condition="{bu:arrayElement(array: onlineBackendUsers, key: backendUser.uid)}">
@@ -19,7 +19,7 @@
                </f:if>
                <br />
                <f:if condition="{backendUser.realName}">
-                       <be:link.editRecord table="be_users" uid="{backendUser.uid}" returnUrl="{returnUrl}" title="edit">
+                       <be:link.editRecord table="be_users" uid="{backendUser.uid}" title="edit">
                                {backendUser.realName}
                        </be:link.editRecord>
                </f:if>
@@ -36,7 +36,7 @@
        </td>
        <td class="col-control">
                <div class="btn-group" role="group">
-                       <be:link.editRecord class="btn btn-default" table="be_users" uid="{backendUser.uid}" returnUrl="{returnUrl}" title="edit" >
+                       <be:link.editRecord class="btn btn-default" table="be_users" uid="{backendUser.uid}" title="edit" >
                                <core:icon identifier="actions-open" />
                        </be:link.editRecord>
                        <f:if condition="{backendUser.currentlyLoggedIn} == 1">
index 15b5ac4..b870e89 100644 (file)
@@ -10,7 +10,7 @@
         </thead>
         <tbody>
         <f:for each="{paginatedBackendUsers}" as="backendUser">
-            <f:render partial="BackendUser/IndexListRow" section="list_row" arguments="{demand: demand, backendUser: backendUser, onlineBackendUsers: onlineBackendUsers, dateFormat: dateFormat, timeFormat: timeFormat, returnUrl: returnUrl, compareUserUidList: compareUserUidList, currentUserUid: currentUserUid}" />
+            <f:render partial="BackendUser/IndexListRow" section="list_row" arguments="{demand: demand, backendUser: backendUser, onlineBackendUsers: onlineBackendUsers, dateFormat: dateFormat, timeFormat: timeFormat, compareUserUidList: compareUserUidList, currentUserUid: currentUserUid}" />
         </f:for>
         <f:comment>
             Footer row: no officially defined style yet
index 06df8fb..808b949 100644 (file)
                </a>
        </td>
        <td class="col-title">
-               <be:link.editRecord table="be_groups" uid="{backendUserGroup.uid}" returnUrl="{returnUrl}" title="edit">
+               <be:link.editRecord table="be_groups" uid="{backendUserGroup.uid}" title="edit">
                        <b>{backendUserGroup.title}</b><br />
                        {backendUser.realName}
                </be:link.editRecord>
        </td>
        <td>
                <f:for each="{backendUserGroup.subgroups}" as="subgroup" iteration="subGroupIterator">
-                       <be:link.editRecord table="be_groups" uid="{subgroup.uid}" returnUrl="{returnUrl}" title="edit">
+                       <be:link.editRecord table="be_groups" uid="{subgroup.uid}" title="edit">
                                {subgroup.title}
                        </be:link.editRecord>
                        <f:if condition="{subGroupIterator.isLast}"><f:else>, </f:else></f:if>
@@ -26,7 +26,7 @@
        </td>
        <td class="col-control">
                <div class="btn-group" role="group">
-                       <be:link.editRecord class="btn btn-default" table="be_groups" uid="{backendUserGroup.uid}" returnUrl="{returnUrl}" title="edit">
+                       <be:link.editRecord class="btn btn-default" table="be_groups" uid="{backendUserGroup.uid}" title="edit">
                                <core:icon identifier="actions-open" />
                        </be:link.editRecord>
                        <f:if condition="{backendUserGroup.hidden}">
index 5721b13..73cea6b 100644 (file)
@@ -10,7 +10,7 @@
         </thead>
         <tbody>
         <f:for each="{paginatedBackendUserGroups}" as="backendUserGroup">
-            <f:render partial="BackendUserGroup/IndexListRow" section="list_row" arguments="{demand: demand, backendUserGroup: backendUserGroup, dateFormat: dateFormat, timeFormat: timeFormat, returnUrl: returnUrl, currentUserUid: currentUserUid}" />
+            <f:render partial="BackendUserGroup/IndexListRow" section="list_row" arguments="{demand: demand, backendUserGroup: backendUserGroup, dateFormat: dateFormat, timeFormat: timeFormat, currentUserUid: currentUserUid}" />
         </f:for>
         <f:comment>
             Footer row: no officially defined style yet
index 9b62e59..dd211af 100644 (file)
@@ -5,11 +5,16 @@
 
 <f:layout name="Default" />
 
-<f:section name="headline">
-       <h1><f:translate key="compareBackendUsers">Compare backend users</f:translate></h1>
+<f:section name="Buttons">
+       <be:moduleLayout.button.linkButton
+               icon="actions-view-go-back"
+               title="{f:translate(id: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack')}"
+               link="{be:moduleLink(route: 'system_BeuserTxBeuser')}"
+       />
 </f:section>
 
-<f:section name="content">
+<f:section name="Content">
+       <h1><f:translate key="compareBackendUsers">Compare backend users</f:translate></h1>
        <div class="table-fit">
                <table border="0" cellpadding="0" cellspacing="0" id="tx_beuser_compare" class="table table-striped table-bordered table-hover">
                        <thead>
@@ -21,7 +26,7 @@
                                                                <be:avatar backendUser="{compareUser.uid}" showIcon="true" />
                                                        </a>
                                                        {compareUser.userName}
-                                                               <be:link.editRecord class="btn btn-default pull-right" table="be_users" uid="{compareUser.uid}" returnUrl="{returnUrl}" title="edit">
+                                                               <be:link.editRecord class="btn btn-default pull-right" table="be_users" uid="{compareUser.uid}" title="edit">
                                                                <core:icon identifier="actions-open" />
                                                                </be:link.editRecord>
                                                </th>
index 6adad08..3300ee9 100644 (file)
@@ -1,13 +1,21 @@
-{namespace be = TYPO3\CMS\Backend\ViewHelpers}
-{namespace bu = TYPO3\CMS\Beuser\ViewHelpers}
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
+    xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
+    data-namespace-typo3-fluid="true">
 
 <f:layout name="Default" />
 
-<f:section name="headline">
-       <h1><f:translate key="backendUserListing" /></h1>
+<f:section name="Buttons">
+       <be:moduleLayout.button.linkButton
+               icon="actions-add"
+               title="{f:translate(id: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral')}"
+               link="{be:uri.newRecord(table: 'be_users')}"
+       />
 </f:section>
 
-<f:section name="content">
+<f:section name="Content">
+       <h1><f:translate key="backendUserListing" /></h1>
        <f:comment>
                Listing of users on compare list
        </f:comment>
@@ -50,3 +58,5 @@
        <f:render partial="BackendUser/PaginatedListWidget" arguments="{_all}" />
 
 </f:section>
+
+</html>
index 375625d..45cb491 100644 (file)
@@ -2,11 +2,11 @@
 
 <f:layout name="Default" />
 
-<f:section name="headline">
-       <h1><f:translate key="onlineUsers" /></h1>
+<f:section name="Buttons">
 </f:section>
 
-<f:section name="content">
+<f:section name="Content">
+       <h1><f:translate key="onlineUsers" /></h1>
        <div class="table-fit">
                <table class="table table-striped table-hover">
                        <thead>
index 3213b04..3402300 100644 (file)
@@ -1,14 +1,19 @@
-{namespace be = TYPO3\CMS\Backend\ViewHelpers}
-{namespace bu = TYPO3\CMS\Beuser\ViewHelpers}
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
+    data-namespace-typo3-fluid="true">
 
 <f:layout name="Default" />
 
-<f:section name="headline">
-       <h1><f:translate key="backendUserGroupListing" /></h1>
+<f:section name="Buttons">
+       <be:moduleLayout.button.linkButton
+               icon="actions-add"
+               title="{f:translate(id: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral')}"
+               link="{be:uri.newRecord(table: 'be_groups')}"
+       />
 </f:section>
 
-<f:section name="content">
-
+<f:section name="Content">
+       <h1><f:translate key="backendUserGroupListing" /></h1>
        <f:render partial="BackendUserGroup/PaginatedListWidget" arguments="{_all}" />
-
 </f:section>
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/ModuleLayoutViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/ModuleLayoutViewHelper.php
deleted file mode 100644 (file)
index 6993db2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-declare(strict_types = 1);
-namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
-
-/*
- * 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\Template\ModuleTemplate;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
-use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
-use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
-use TYPO3Fluid\Fluid\View\Exception;
-
-/**
- * A view helper for having properly styled backend modules.
- * It is recommended to use it in Fluid Layouts.
- * It will render the required HTML for the doc header.
- * All module specific output and further configuration of the doc header
- * must be rendered as children of this view helper.
- * = Examples =
- * <code>
- * <f:be.moduleLayout>
- *     <f:render section="content" />
- * </f:be.moduleLayout>
- * </code>
- * <output>
- * <!-- HTML of the backend module -->
- * </output>
- */
-class ModuleLayoutViewHelper extends AbstractViewHelper
-{
-    use CompileWithRenderStatic;
-
-    /**
-     * @var bool
-     */
-    protected $escapeOutput = false;
-
-    public static function renderStatic(
-        array $arguments,
-        \Closure $renderChildrenClosure,
-        RenderingContextInterface $renderingContext
-    ) {
-        $viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
-        if ($viewHelperVariableContainer->exists(self::class, ModuleTemplate::class)) {
-            throw new Exception('ModuleLayoutViewHelper can only be used once per module.', 1483292643);
-        }
-
-        $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
-        $moduleTemplate->setFlashMessageQueue($renderingContext->getControllerContext()->getFlashMessageQueue());
-
-        $viewHelperVariableContainer->add(self::class, ModuleTemplate::class, $moduleTemplate);
-        $moduleTemplate->setContent($renderChildrenClosure());
-        $viewHelperVariableContainer->remove(self::class, ModuleTemplate::class);
-
-        return $moduleTemplate->renderContent();
-    }
-}