[TASK] Use view helper to configure ModuleTemplate in log module 88/51088/17
authorHelmut Hummel <typo3@helhum.io>
Sun, 1 Jan 2017 12:56:01 +0000 (13:56 +0100)
committerHelmut Hummel <typo3@helhum.io>
Fri, 10 Aug 2018 20:13:03 +0000 (22:13 +0200)
With implementation of ModuleTemplate as view helpers,
we can remove class inheritance for the two purposes
where we render the log module and use Fluid layouts for that.

By doing so, we can clean up the Fluid templates,
add xml based namespace registration, remove unnecessary partials
and also get rid of persistent object inheritance of
the filter DTO.

Resolves: #85521
Releases: master
Change-Id: I5e35ea97ce419fc3a7ffbee309c466118e22ab80
Reviewed-on: https://review.typo3.org/51088
Reviewed-by: Tim Schreiner <schreiner.tim@gmail.com>
Tested-by: Tim Schreiner <schreiner.tim@gmail.com>
Reviewed-by: Mona Muzaffar <mona.muzaffar@gmx.de>
Tested-by: Mona Muzaffar <mona.muzaffar@gmx.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Helmut Hummel <typo3@helhum.io>
Tested-by: Helmut Hummel <typo3@helhum.io>
17 files changed:
typo3/sysext/belog/Classes/Controller/AbstractController.php [deleted file]
typo3/sysext/belog/Classes/Controller/BackendLogController.php [new file with mode: 0644]
typo3/sysext/belog/Classes/Controller/ToolsController.php [deleted file]
typo3/sysext/belog/Classes/Controller/WebInfoController.php [deleted file]
typo3/sysext/belog/Classes/Domain/Model/Constraint.php
typo3/sysext/belog/Classes/Domain/Repository/LogEntryRepository.php
typo3/sysext/belog/Classes/Module/BackendLogModuleBootstrap.php
typo3/sysext/belog/Resources/Private/Layouts/Default.html [new file with mode: 0644]
typo3/sysext/belog/Resources/Private/Layouts/Plain.html [new file with mode: 0644]
typo3/sysext/belog/Resources/Private/Partials/Content.html [deleted file]
typo3/sysext/belog/Resources/Private/Partials/Content/Filter.html
typo3/sysext/belog/Resources/Private/Partials/Content/LogEntries.html
typo3/sysext/belog/Resources/Private/Templates/BackendLog/List.html [new file with mode: 0644]
typo3/sysext/belog/Resources/Private/Templates/Tools/Index.html [deleted file]
typo3/sysext/belog/Resources/Private/Templates/WebInfo/Index.html [deleted file]
typo3/sysext/belog/ext_tables.php
typo3/sysext/fluid/Classes/ViewHelpers/Be/ModuleLayoutViewHelper.php [new file with mode: 0644]

diff --git a/typo3/sysext/belog/Classes/Controller/AbstractController.php b/typo3/sysext/belog/Classes/Controller/AbstractController.php
deleted file mode 100644 (file)
index 48b01d8..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-<?php
-namespace TYPO3\CMS\Belog\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\Utility\ExtensionManagementUtility;
-use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
-use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
-use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
-
-/**
- * Abstract class to show log entries from sys_log
- */
-abstract class AbstractController extends ActionController
-{
-    /**
-     * @var int
-     */
-    const TIMEFRAME_THISWEEK = 0;
-
-    /**
-     * @var int
-     */
-    const TIMEFRAME_LASTWEEK = 1;
-
-    /**
-     * @var int
-     */
-    const TIMEFRAME_LASTSEVENDAYS = 2;
-
-    /**
-     * @var int
-     */
-    const TIMEFRAME_THISMONTH = 10;
-
-    /**
-     * @var int
-     */
-    const TIMEFRAME_LASTMONTH = 11;
-
-    /**
-     * @var int
-     */
-    const TIMEFRAME_LAST31DAYS = 12;
-
-    /**
-     * @var int
-     */
-    const TIMEFRAME_CUSTOM = 30;
-
-    /**
-     * Whether plugin is running in page context (sub module of Web > Info)
-     *
-     * @var bool
-     */
-    protected $isInPageContext = false;
-
-    /**
-     * Page ID in page context
-     *
-     * @var int
-     */
-    protected $pageId = 0;
-
-    /**
-     * @var \TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository
-     */
-    protected $logEntryRepository;
-
-    /**
-     * @var BackendTemplateView
-     */
-    protected $view;
-
-    /**
-     * @param \TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository $logEntryRepository
-     */
-    public function injectLogEntryRepository(\TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository $logEntryRepository)
-    {
-        $this->logEntryRepository = $logEntryRepository;
-    }
-
-    /**
-     * Initialize the view
-     *
-     * @param ViewInterface $view The view
-     */
-    protected function initializeView(ViewInterface $view)
-    {
-        if ($view instanceof BackendTemplateView) {
-            parent::initializeView($view);
-            $view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/DateTimePicker');
-        }
-    }
-
-    /**
-     * init all actions
-     */
-    public function initializeAction()
-    {
-        if ($this->isInPageContext === false) {
-            $this->defaultViewObjectName = BackendTemplateView::class;
-        }
-    }
-
-    /**
-     * Initialize index action
-     *
-     * @throws \RuntimeException
-     */
-    public function initializeIndexAction()
-    {
-        // @TODO: Extbase backend modules rely 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 usually happens if there is no frontend TypoScript template with root flag set. Please create one.',
-                1333650506
-            );
-        }
-        if (!isset($this->settings['dateFormat'])) {
-            $this->settings['dateFormat'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? 'm-d-Y' : 'd-m-Y';
-        }
-        if (!isset($this->settings['timeFormat'])) {
-            $this->settings['timeFormat'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
-        }
-        $constraintConfiguration = $this->arguments->getArgument('constraint')->getPropertyMappingConfiguration();
-        $constraintConfiguration->allowProperties('action')->setTypeConverterOption(PersistentObjectConverter::class, PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true);
-    }
-
-    /**
-     * Show general information and the installed modules
-     *
-     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
-     */
-    public function indexAction(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint = null)
-    {
-        // Constraint object handling:
-        // If there is none from GET, try to get it from BE user data, else create new
-        if ($constraint === null) {
-            $constraint = $this->getConstraintFromBeUserData();
-            if ($constraint === null) {
-                $constraint = $this->objectManager->get(\TYPO3\CMS\Belog\Domain\Model\Constraint::class);
-            }
-        } else {
-            $this->persistConstraintInBeUserData($constraint);
-        }
-        $constraint->setIsInPageContext($this->isInPageContext);
-        $constraint->setPageId($this->pageId);
-        $this->setStartAndEndTimeFromTimeSelector($constraint);
-        $this->forceWorkspaceSelectionIfInWorkspace($constraint);
-        $logEntries = $this->logEntryRepository->findByConstraint($constraint);
-        $groupedLogEntries = $this->groupLogEntriesByPageAndDay($logEntries, $constraint->getGroupByPage());
-        $this->view->assign('workspacesExtensionLoaded', ExtensionManagementUtility::isLoaded('workspaces'));
-        $this->view->assign('groupedLogEntries', $groupedLogEntries)->assign('constraint', $constraint)->assign('userGroups', $this->createUserAndGroupListForSelectOptions())->assign('workspaces', $this->createWorkspaceListForSelectOptions())->assign('pageDepths', $this->createPageDepthOptions());
-    }
-
-    /**
-     * Get module states (the constraint object) from user data
-     *
-     * @return \TYPO3\CMS\Belog\Domain\Model\Constraint|null
-     */
-    protected function getConstraintFromBeUserData()
-    {
-        $serializedConstraint = $GLOBALS['BE_USER']->getModuleData(static::class);
-        if (!is_string($serializedConstraint) || empty($serializedConstraint)) {
-            return null;
-        }
-        return @unserialize($serializedConstraint);
-    }
-
-    /**
-     * Save current constraint object in be user settings (uC)
-     *
-     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
-     */
-    protected function persistConstraintInBeUserData(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint)
-    {
-        $GLOBALS['BE_USER']->pushModuleData(static::class, serialize($constraint));
-    }
-
-    /**
-     * Create a sorted array for day and page view from
-     * the query result of the sys log repository.
-     *
-     * If group by page is FALSE, pid is always -1 (will render a flat list),
-     * otherwise the output is splitted by pages.
-     * '12345' is a sub array to split entries by day, number is first second of day
-     *
-     * [pid][dayTimestamp][items]
-     *
-     * @param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface<\TYPO3\CMS\Belog\Domain\Model\LogEntry> $logEntries
-     * @param bool $groupByPage Whether or not log entries should be grouped by page
-     * @return array
-     */
-    protected function groupLogEntriesByPageAndDay(\TYPO3\CMS\Extbase\Persistence\QueryResultInterface $logEntries, $groupByPage = false)
-    {
-        $targetStructure = [];
-        /** @var $entry \TYPO3\CMS\Belog\Domain\Model\LogEntry */
-        foreach ($logEntries as $entry) {
-            // Create page split list or flat list
-            if ($groupByPage) {
-                $pid = $entry->getEventPid();
-            } else {
-                $pid = -1;
-            }
-            // Create array if it is not defined yet
-            if (!is_array($targetStructure[$pid])) {
-                $targetStructure[$pid] = [];
-            }
-            // Get day timestamp of log entry and create sub array if needed
-            $timestampDay = strtotime(strftime('%d.%m.%Y', $entry->getTstamp()));
-            if (!is_array($targetStructure[$pid][$timestampDay])) {
-                $targetStructure[$pid][$timestampDay] = [];
-            }
-            // Add row
-            $targetStructure[$pid][$timestampDay][] = $entry;
-        }
-        ksort($targetStructure);
-        return $targetStructure;
-    }
-
-    /**
-     * Create options for the user / group drop down.
-     * This is not moved to a repository by intention to not mix up this 'meta' data
-     * with real repository work
-     *
-     * @return array Key is the option name, value its label
-     */
-    protected function createUserAndGroupListForSelectOptions()
-    {
-        $userGroupArray = [];
-        // Two meta entries: 'all' and 'self'
-        $userGroupArray[0] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('allUsers', 'Belog');
-        $userGroupArray[-1] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('self', 'Belog');
-        // List of groups, key is gr-'uid'
-        $groups = \TYPO3\CMS\Backend\Utility\BackendUtility::getGroupNames();
-        foreach ($groups as $group) {
-            $userGroupArray['gr-' . $group['uid']] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('group', 'Belog') . ' ' . $group['title'];
-        }
-        // List of users, key is us-'uid'
-        $users = \TYPO3\CMS\Backend\Utility\BackendUtility::getUserNames();
-        foreach ($users as $user) {
-            $userGroupArray['us-' . $user['uid']] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('user', 'Belog') . ' ' . $user['username'];
-        }
-        return $userGroupArray;
-    }
-
-    /**
-     * Create options for the workspace selector
-     *
-     * @return array Key is uid of workspace, value its label
-     */
-    protected function createWorkspaceListForSelectOptions()
-    {
-        if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('workspaces')) {
-            return [];
-        }
-        $workspaceArray = [];
-        // Two meta entries: 'all' and 'live'
-        $workspaceArray[-99] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('any', 'Belog');
-        $workspaceArray[0] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('live', 'Belog');
-        $workspaces = $this->objectManager->get(\TYPO3\CMS\Belog\Domain\Repository\WorkspaceRepository::class)->findAll();
-        /** @var $workspace \TYPO3\CMS\Belog\Domain\Model\Workspace */
-        foreach ($workspaces as $workspace) {
-            $workspaceArray[$workspace->getUid()] = $workspace->getUid() . ': ' . $workspace->getTitle();
-        }
-        return $workspaceArray;
-    }
-
-    /**
-     * If the user is in a workspace different than LIVE,
-     * we force to show only log entries from the selected workspace,
-     * and the workspace selector is not shown.
-     *
-     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
-     */
-    protected function forceWorkspaceSelectionIfInWorkspace(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint)
-    {
-        if ($GLOBALS['BE_USER']->workspace !== 0) {
-            $constraint->setWorkspaceUid($GLOBALS['BE_USER']->workspace);
-            $this->view->assign('showWorkspaceSelector', false);
-        } else {
-            $this->view->assign('showWorkspaceSelector', true);
-        }
-    }
-
-    /**
-     * Create options for the 'depth of page levels' selector.
-     * This is shown if the module is displayed in page -> info
-     *
-     * @return array Key is depth identifier (1 = One level), value the localized select option label
-     */
-    protected function createPageDepthOptions()
-    {
-        $options = [
-            0 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0', 'lang'),
-            1 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1', 'lang'),
-            2 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2', 'lang'),
-            3 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3', 'lang'),
-            4 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4', 'lang'),
-            999 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi', 'lang')
-        ];
-        return $options;
-    }
-
-    /**
-     * Calculate the start- and end timestamp from the different time selector options
-     *
-     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
-     */
-    protected function setStartAndEndTimeFromTimeSelector(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint)
-    {
-        $startTime = 0;
-        $endTime = $GLOBALS['EXEC_TIME'];
-        // @TODO: Refactor this construct
-        switch ($constraint->getTimeFrame()) {
-            case self::TIMEFRAME_THISWEEK:
-                // This week
-                $week = (date('w') ?: 7) - 1;
-                $startTime = mktime(0, 0, 0) - $week * 3600 * 24;
-                break;
-            case self::TIMEFRAME_LASTWEEK:
-                // Last week
-                $week = (date('w') ?: 7) - 1;
-                $startTime = mktime(0, 0, 0) - ($week + 7) * 3600 * 24;
-                $endTime = mktime(0, 0, 0) - $week * 3600 * 24;
-                break;
-            case self::TIMEFRAME_LASTSEVENDAYS:
-                // Last 7 days
-                $startTime = mktime(0, 0, 0) - 7 * 3600 * 24;
-                break;
-            case self::TIMEFRAME_THISMONTH:
-                // This month
-                $startTime = mktime(0, 0, 0, date('m'), 1);
-                break;
-            case self::TIMEFRAME_LASTMONTH:
-                // Last month
-                $startTime = mktime(0, 0, 0, date('m') - 1, 1);
-                $endTime = mktime(0, 0, 0, date('m'), 1);
-                break;
-            case self::TIMEFRAME_LAST31DAYS:
-                // Last 31 days
-                $startTime = mktime(0, 0, 0) - 31 * 3600 * 24;
-                break;
-            case self::TIMEFRAME_CUSTOM:
-                $startDate = $constraint->getManualDateStart();
-                $endDate = $constraint->getManualDateStop();
-                $endTime = $GLOBALS['EXEC_TIME'];
-                if (!$startDate) {
-                    $startDate = \DateTime::createFromFormat(
-                        'U',
-                        0
-                    );
-                    $constraint->setManualDateStart(
-                        $startDate
-                    );
-                }
-
-                if (!$endDate) {
-                    $endDate = \DateTime::createFromFormat(
-                        'U',
-                        $endTime
-                    )->setTimezone(new \DateTimeZone(date_default_timezone_get()));
-                    $constraint->setManualDateStop(
-                        $endDate
-                    );
-                }
-                $startTime = $startDate->getTimestamp();
-                if ($endDate->getTimestamp() > $startDate->getTimestamp()) {
-                    $endTime = $endDate->getTimestamp();
-                }
-
-                break;
-            default:
-        }
-        $constraint->setStartTimestamp($startTime);
-        $constraint->setEndTimestamp($endTime);
-    }
-}
diff --git a/typo3/sysext/belog/Classes/Controller/BackendLogController.php b/typo3/sysext/belog/Classes/Controller/BackendLogController.php
new file mode 100644 (file)
index 0000000..9128020
--- /dev/null
@@ -0,0 +1,351 @@
+<?php
+namespace TYPO3\CMS\Belog\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\Belog\Domain\Model\Constraint;
+use TYPO3\CMS\Belog\Domain\Model\LogEntry;
+use TYPO3\CMS\Core\Messaging\AbstractMessage;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
+use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
+
+/**
+ * Abstract class to show log entries from sys_log
+ */
+class BackendLogController extends ActionController
+{
+    /**
+     * @var int
+     */
+    private const TIMEFRAME_THISWEEK = 0;
+
+    /**
+     * @var int
+     */
+    private const TIMEFRAME_LASTWEEK = 1;
+
+    /**
+     * @var int
+     */
+    private const TIMEFRAME_LASTSEVENDAYS = 2;
+
+    /**
+     * @var int
+     */
+    private const TIMEFRAME_THISMONTH = 10;
+
+    /**
+     * @var int
+     */
+    private const TIMEFRAME_LASTMONTH = 11;
+
+    /**
+     * @var int
+     */
+    private const TIMEFRAME_LAST31DAYS = 12;
+
+    /**
+     * @var int
+     */
+    private const TIMEFRAME_CUSTOM = 30;
+
+    /**
+     * @var \TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository
+     */
+    protected $logEntryRepository;
+
+    /**
+     * @var BackendTemplateView
+     */
+    protected $view;
+
+    /**
+     * @param \TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository $logEntryRepository
+     */
+    public function injectLogEntryRepository(\TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository $logEntryRepository)
+    {
+        $this->logEntryRepository = $logEntryRepository;
+    }
+
+    /**
+     * Initialize list action
+     */
+    public function initializeListAction()
+    {
+        if (!isset($this->settings['dateFormat'])) {
+            $this->settings['dateFormat'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? 'm-d-Y' : 'd-m-Y';
+        }
+        if (!isset($this->settings['timeFormat'])) {
+            $this->settings['timeFormat'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
+        }
+        $constraintConfiguration = $this->arguments->getArgument('constraint')->getPropertyMappingConfiguration();
+        $constraintConfiguration->allowAllProperties();
+    }
+
+    /**
+     * Show general information and the installed modules
+     *
+     * @param Constraint $constraint
+     * @param int $pageId
+     * @param string $layout
+     */
+    public function listAction(Constraint $constraint = null, int $pageId = null, string $layout = 'Default')
+    {
+        // Constraint object handling:
+        // If there is none from GET, try to get it from BE user data, else create new
+        if ($constraint === null) {
+            $constraint = $this->getConstraintFromBeUserData();
+        } else {
+            $this->persistConstraintInBeUserData($constraint);
+        }
+        $constraint->setPageId($pageId);
+        $this->setStartAndEndTimeFromTimeSelector($constraint);
+        $this->forceWorkspaceSelectionIfInWorkspace($constraint);
+        $logEntries = $this->logEntryRepository->findByConstraint($constraint);
+        $groupedLogEntries = $this->groupLogEntriesByPageAndDay($logEntries, $constraint->getGroupByPage());
+        $this->view->assignMultiple([
+            'pageId' => $pageId,
+            'layout' => $layout,
+            'groupedLogEntries' => $groupedLogEntries,
+            'constraint' => $constraint,
+            'userGroups' => $this->createUserAndGroupListForSelectOptions(),
+            'workspaces' => $this->createWorkspaceListForSelectOptions(),
+            'pageDepths' => $this->createPageDepthOptions(),
+        ]);
+    }
+
+    /**
+     * Delete all log entries that share the same message with the log entry given
+     * in $errorUid
+     *
+     * @param int $errorUid
+     */
+    public function deleteMessageAction(int $errorUid)
+    {
+        /** @var \TYPO3\CMS\Belog\Domain\Model\LogEntry $logEntry */
+        $logEntry = $this->logEntryRepository->findByUid($errorUid);
+        if (!$logEntry) {
+            $this->addFlashMessage(LocalizationUtility::translate('actions.delete.noRowFound', 'belog'), '', AbstractMessage::WARNING);
+            $this->redirect('list');
+        }
+        $numberOfDeletedRows = $this->logEntryRepository->deleteByMessageDetails($logEntry);
+        $this->addFlashMessage(sprintf(LocalizationUtility::translate('actions.delete.message', 'belog'), $numberOfDeletedRows));
+        $this->redirect('list');
+    }
+
+    /**
+     * Get module states (the constraint object) from user data
+     *
+     * @return Constraint
+     */
+    protected function getConstraintFromBeUserData()
+    {
+        $serializedConstraint = $GLOBALS['BE_USER']->getModuleData(static::class);
+        $constraint = null;
+        if (is_string($serializedConstraint) && !empty($serializedConstraint)) {
+            $constraint = @unserialize($serializedConstraint, ['allowed_classes' => [Constraint::class, \DateTime::class]]);
+        }
+        return $constraint ?: $this->objectManager->get(Constraint::class);
+    }
+
+    /**
+     * Save current constraint object in be user settings (uC)
+     *
+     * @param Constraint $constraint
+     */
+    protected function persistConstraintInBeUserData(Constraint $constraint)
+    {
+        $GLOBALS['BE_USER']->pushModuleData(static::class, serialize($constraint));
+    }
+
+    /**
+     * Create a sorted array for day and page view from
+     * the query result of the sys log repository.
+     *
+     * If group by page is FALSE, pid is always -1 (will render a flat list),
+     * otherwise the output is split by pages.
+     * '12345' is a sub array to split entries by day, number is first second of day
+     *
+     * [pid][dayTimestamp][items]
+     *
+     * @param QueryResultInterface $logEntries
+     * @param bool $groupByPage Whether or not log entries should be grouped by page
+     * @return array
+     */
+    protected function groupLogEntriesByPageAndDay(QueryResultInterface $logEntries, $groupByPage = false)
+    {
+        $targetStructure = [];
+        /** @var $entry LogEntry */
+        foreach ($logEntries as $entry) {
+            // Create page split list or flat list
+            if ($groupByPage) {
+                $pid = $entry->getEventPid();
+            } else {
+                $pid = -1;
+            }
+            // Create array if it is not defined yet
+            if (!is_array($targetStructure[$pid])) {
+                $targetStructure[$pid] = [];
+            }
+            // Get day timestamp of log entry and create sub array if needed
+            $timestampDay = strtotime(strftime('%d.%m.%Y', $entry->getTstamp()));
+            if (!is_array($targetStructure[$pid][$timestampDay])) {
+                $targetStructure[$pid][$timestampDay] = [];
+            }
+            // Add row
+            $targetStructure[$pid][$timestampDay][] = $entry;
+        }
+        ksort($targetStructure);
+        return $targetStructure;
+    }
+
+    /**
+     * Create options for the user / group drop down.
+     * This is not moved to a repository by intention to not mix up this 'meta' data
+     * with real repository work
+     *
+     * @return array Key is the option name, value its label
+     */
+    protected function createUserAndGroupListForSelectOptions()
+    {
+        $userGroupArray = [];
+        // Two meta entries: 'all' and 'self'
+        $userGroupArray[0] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('allUsers', 'Belog');
+        $userGroupArray[-1] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('self', 'Belog');
+        // List of groups, key is gr-'uid'
+        $groups = \TYPO3\CMS\Backend\Utility\BackendUtility::getGroupNames();
+        foreach ($groups as $group) {
+            $userGroupArray['gr-' . $group['uid']] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('group', 'Belog') . ' ' . $group['title'];
+        }
+        // List of users, key is us-'uid'
+        $users = \TYPO3\CMS\Backend\Utility\BackendUtility::getUserNames();
+        foreach ($users as $user) {
+            $userGroupArray['us-' . $user['uid']] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('user', 'Belog') . ' ' . $user['username'];
+        }
+        return $userGroupArray;
+    }
+
+    /**
+     * Create options for the workspace selector
+     *
+     * @return array Key is uid of workspace, value its label
+     */
+    protected function createWorkspaceListForSelectOptions()
+    {
+        if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('workspaces')) {
+            return [];
+        }
+        $workspaceArray = [];
+        // Two meta entries: 'all' and 'live'
+        $workspaceArray[-99] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('any', 'Belog');
+        $workspaceArray[0] = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('live', 'Belog');
+        $workspaces = $this->objectManager->get(\TYPO3\CMS\Belog\Domain\Repository\WorkspaceRepository::class)->findAll();
+        /** @var $workspace \TYPO3\CMS\Belog\Domain\Model\Workspace */
+        foreach ($workspaces as $workspace) {
+            $workspaceArray[$workspace->getUid()] = $workspace->getUid() . ': ' . $workspace->getTitle();
+        }
+        return $workspaceArray;
+    }
+
+    /**
+     * If the user is in a workspace different than LIVE,
+     * we force to show only log entries from the selected workspace,
+     * and the workspace selector is not shown.
+     *
+     * @param Constraint $constraint
+     */
+    protected function forceWorkspaceSelectionIfInWorkspace(Constraint $constraint)
+    {
+        if ($GLOBALS['BE_USER']->workspace !== 0) {
+            $constraint->setWorkspaceUid($GLOBALS['BE_USER']->workspace);
+            $this->view->assign('showWorkspaceSelector', false);
+        } else {
+            $this->view->assign('showWorkspaceSelector', true);
+        }
+    }
+
+    /**
+     * Create options for the 'depth of page levels' selector.
+     * This is shown if the module is displayed in page -> info
+     *
+     * @return array Key is depth identifier (1 = One level), value the localized select option label
+     */
+    protected function createPageDepthOptions()
+    {
+        $options = [
+            0 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0', 'lang'),
+            1 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1', 'lang'),
+            2 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2', 'lang'),
+            3 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3', 'lang'),
+            4 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4', 'lang'),
+            999 => \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi', 'lang')
+        ];
+        return $options;
+    }
+
+    /**
+     * Calculate the start- and end timestamp from the different time selector options
+     *
+     * @param Constraint $constraint
+     */
+    protected function setStartAndEndTimeFromTimeSelector(Constraint $constraint)
+    {
+        $startTime = 0;
+        $endTime = $GLOBALS['EXEC_TIME'];
+        // @TODO: Refactor this construct
+        switch ($constraint->getTimeFrame()) {
+            case self::TIMEFRAME_THISWEEK:
+                // This week
+                $week = (date('w') ?: 7) - 1;
+                $startTime = mktime(0, 0, 0) - $week * 3600 * 24;
+                break;
+            case self::TIMEFRAME_LASTWEEK:
+                // Last week
+                $week = (date('w') ?: 7) - 1;
+                $startTime = mktime(0, 0, 0) - ($week + 7) * 3600 * 24;
+                $endTime = mktime(0, 0, 0) - $week * 3600 * 24;
+                break;
+            case self::TIMEFRAME_LASTSEVENDAYS:
+                // Last 7 days
+                $startTime = mktime(0, 0, 0) - 7 * 3600 * 24;
+                break;
+            case self::TIMEFRAME_THISMONTH:
+                // This month
+                $startTime = mktime(0, 0, 0, date('m'), 1);
+                break;
+            case self::TIMEFRAME_LASTMONTH:
+                // Last month
+                $startTime = mktime(0, 0, 0, date('m') - 1, 1);
+                $endTime = mktime(0, 0, 0, date('m'), 1);
+                break;
+            case self::TIMEFRAME_LAST31DAYS:
+                // Last 31 days
+                $startTime = mktime(0, 0, 0) - 31 * 3600 * 24;
+                break;
+            case self::TIMEFRAME_CUSTOM:
+                $startTime = $constraint->getStartTimestamp();
+                if ($constraint->getEndTimestamp() > $constraint->getStartTimestamp()) {
+                    $endTime = $constraint->getEndTimestamp();
+                } else {
+                    $endTime = $GLOBALS['EXEC_TIME'];
+                }
+                break;
+            default:
+        }
+        $constraint->setStartTimestamp($startTime);
+        $constraint->setEndTimestamp($endTime);
+    }
+}
diff --git a/typo3/sysext/belog/Classes/Controller/ToolsController.php b/typo3/sysext/belog/Classes/Controller/ToolsController.php
deleted file mode 100644 (file)
index c474c3a..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-namespace TYPO3\CMS\Belog\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\Core\Messaging\AbstractMessage;
-use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
-
-/**
- * Show log entries from table sys_log
- */
-class ToolsController extends \TYPO3\CMS\Belog\Controller\AbstractController
-{
-    /**
-     * Delete all log entries that share the same message with the log entry given
-     * in $errorUid
-     *
-     * @param int $errorUid
-     */
-    public function deleteMessageAction(int $errorUid)
-    {
-        /** @var \TYPO3\CMS\Belog\Domain\Model\LogEntry $logEntry */
-        $logEntry = $this->logEntryRepository->findByUid($errorUid);
-        if (!$logEntry) {
-            $this->addFlashMessage(LocalizationUtility::translate('actions.delete.noRowFound', 'belog'), '', AbstractMessage::WARNING);
-            $this->redirect('index');
-        }
-        $numberOfDeletedRows = $this->logEntryRepository->deleteByMessageDetails($logEntry);
-        $this->addFlashMessage(sprintf(LocalizationUtility::translate('actions.delete.message', 'belog'), $numberOfDeletedRows));
-        $this->redirect('index');
-    }
-}
diff --git a/typo3/sysext/belog/Classes/Controller/WebInfoController.php b/typo3/sysext/belog/Classes/Controller/WebInfoController.php
deleted file mode 100644 (file)
index c0085d0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-namespace TYPO3\CMS\Belog\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!
- */
-
-/**
- * Controller for log entry listings in Web->Info module
- */
-class WebInfoController extends \TYPO3\CMS\Belog\Controller\AbstractController
-{
-    /**
-     * Set context to 'in page mode'
-     */
-    public function initializeAction()
-    {
-        $this->isInPageContext = true;
-        $this->pageId = (int)\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id');
-        parent::initializeAction();
-    }
-}
index 5585baf..6feb38b 100644 (file)
@@ -17,7 +17,7 @@ namespace TYPO3\CMS\Belog\Domain\Model;
 /**
  * Constraints for log entries
  */
-class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
+class Constraint
 {
     /**
      * Selected user/group; possible values are "gr-<uid>" for a group, "us-<uid>" for a user or -1 for "all users"
@@ -88,13 +88,6 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
     protected $manualDateStop;
 
     /**
-     * Whether the plugin is called in page context (submodule of Web > Info)
-     *
-     * @var bool
-     */
-    protected $isInPageContext = false;
-
-    /**
      * Selected page ID in page context
      *
      * @var int
@@ -109,24 +102,6 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
     protected $depth = 0;
 
     /**
-     * Default constructor
-     */
-    public function __construct()
-    {
-    }
-
-    /**
-     * added to prevent the deprecation message
-     * in Extbase\DomainObject\AbstractDomainObject
-     *
-     * @todo the constraints model needs another way of storing
-     * persisted search data than serialisation
-     */
-    public function __wakeup()
-    {
-    }
-
-    /**
      * Set user
      *
      * @param string $user
@@ -287,26 +262,6 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
     }
 
     /**
-     * Set page context
-     *
-     * @param bool $pageContext
-     */
-    public function setIsInPageContext($pageContext)
-    {
-        $this->isInPageContext = $pageContext;
-    }
-
-    /**
-     * Get page context
-     *
-     * @return bool
-     */
-    public function getIsInPageContext()
-    {
-        return (bool)$this->isInPageContext;
-    }
-
-    /**
      * Set page id
      *
      * @param int $id
index c9874bf..a31e22d 100644 (file)
@@ -101,9 +101,6 @@ class LogEntryRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
      */
     protected function addPageTreeConstraintsToQuery(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint, \TYPO3\CMS\Extbase\Persistence\QueryInterface $query, array &$queryConstraints)
     {
-        if (!$constraint->getIsInPageContext()) {
-            return;
-        }
         $pageIds = [];
         // Check if we should get a whole tree of pages and not only a single page
         if ($constraint->getDepth() > 0) {
@@ -115,8 +112,12 @@ class LogEntryRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
             $pageTree->getTree($constraint->getPageId(), $constraint->getDepth());
             $pageIds = $pageTree->ids;
         }
-        $pageIds[] = $constraint->getPageId();
-        $queryConstraints[] = $query->in('eventPid', $pageIds);
+        if (!empty($constraint->getPageId())) {
+            $pageIds[] = $constraint->getPageId();
+        }
+        if (!empty($pageIds)) {
+            $queryConstraints[] = $query->in('eventPid', $pageIds);
+        }
     }
 
     /**
index 13f366b..b67dee6 100644 (file)
@@ -54,7 +54,9 @@ class BackendLogModuleBootstrap
         // in extbase to force a specific controller in backend mode.
         // Overwriting $_GET was the most simple solution here until extbase
         // provides a clean way to solve this.
-        $_GET['tx_belog_system_beloglog']['controller'] = 'WebInfo';
+        $_GET['tx_belog_system_beloglog']['controller'] = 'BackendLog';
+        $_GET['tx_belog_system_beloglog']['pageId'] = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id');
+        $_GET['tx_belog_system_beloglog']['layout'] = 'Plain';
         /** @var $extbaseBootstrap \TYPO3\CMS\Extbase\Core\Bootstrap */
         $extbaseBootstrap = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Core\Bootstrap::class);
         return $extbaseBootstrap->run('', $configuration);
diff --git a/typo3/sysext/belog/Resources/Private/Layouts/Default.html b/typo3/sysext/belog/Resources/Private/Layouts/Default.html
new file mode 100644 (file)
index 0000000..0712c33
--- /dev/null
@@ -0,0 +1,9 @@
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    data-namespace-typo3-fluid="true">
+
+<f:be.moduleLayout>
+       <f:render section="Content" />
+</f:be.moduleLayout>
+
+</html>
diff --git a/typo3/sysext/belog/Resources/Private/Layouts/Plain.html b/typo3/sysext/belog/Resources/Private/Layouts/Plain.html
new file mode 100644 (file)
index 0000000..290c79c
--- /dev/null
@@ -0,0 +1,8 @@
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    data-namespace-typo3-fluid="true">
+
+<f:variable name="isSubmoduleLayout" value="true"/>
+<f:render section="Content"/>
+
+</html>
diff --git a/typo3/sysext/belog/Resources/Private/Partials/Content.html b/typo3/sysext/belog/Resources/Private/Partials/Content.html
deleted file mode 100644 (file)
index d05d1c0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<h1>
-       <f:translate key="adminLog" />
-</h1>
-
-<div>
-       <f:render
-               partial="Content/Filter"
-               arguments="{_all}"
-       />
-</div>
-
-<div class="divider"></div>
-
-<f:render
-       partial="Content/LogEntries"
-       arguments="{_all}"
-/>
\ No newline at end of file
index d512521..b5a89cb 100644 (file)
@@ -1,4 +1,7 @@
-{namespace belog=TYPO3\CMS\Belog\ViewHelpers}
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    xmlns:belog="http://typo3.org/ns/TYPO3/CMS/Belog/ViewHelpers"
+    data-namespace-typo3-fluid="true">
 
 <f:comment>
        This is an ugly workaround.
        that is not extbase based to figure the permissions. Thus, we have to add
        the page Id manually to hint the info module about that.
 </f:comment>
-<f:if condition="{constraint.isInPageContext}">
+<f:if condition="{isSubmoduleLayout}">
        <input type="hidden" name="id" value="{constraint.pageId}" />
 </f:if>
 
-<f:form object="{constraint}" action="index" name="constraint" class="form-inline form-inline-spaced">
+<f:form object="{constraint}" action="list" name="constraint" class="form-inline form-inline-spaced">
        <div class="form-group">
                <label for="belog-users"><f:translate key="users" /></label>
                <f:form.select
@@ -50,7 +53,7 @@
                </f:if>
        </f:if>
 
-       <f:if condition="{constraint.isInPageContext}">
+       <f:if condition="{isSubmoduleLayout}">
                <div class="form-group">
                        <label for="belog-depth"><f:translate key="chLog_menuDepth" /></label>
                        <f:form.select
 
 
        <f:if condition="{constraint.timeFrame} == 30">
+               <f:be.pageRenderer includeRequireJsModules="{0: 'TYPO3/CMS/Backend/DateTimePicker'}" />
                <div class="form-group">
                        <label for="manualDateStart"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:from" /></label>
                        <div class="input-group input-group-sm">
                </div>
        </f:if>
 </f:form>
+
+</html>
index d9b051f..564604f 100644 (file)
@@ -1,5 +1,9 @@
-{namespace be=TYPO3\CMS\Backend\ViewHelpers}
-{namespace belog=TYPO3\CMS\Belog\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"
+    xmlns:belog="http://typo3.org/ns/TYPO3/CMS/Belog/ViewHelpers"
+    data-namespace-typo3-fluid="true">
 
 <f:if condition="{constraint.groupByPage}">
        <div>
@@ -9,8 +13,8 @@
                <f:translate
                        key="timeInfo"
                        arguments="{
-                               0: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStart}\')}',
-                               1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStop}\')}'
+                               0: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.startTimestamp}\')}',
+                               1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.endTimestamp}\')}'
                        }"
                />
                <p>
@@ -42,8 +46,8 @@
                                                                        key="logForNonPageRelatedActionsOrRootLevelOrPage"
                                                                        arguments="{
                                                                                0: '{f:translate(key:\'forNonPageRelatedActions\')}',
-                                                                               1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStart}\')}',
-                                                                               2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStop}\')}'
+                                                                               1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.startTimestamp}\')}',
+                                                                               2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.endTimestamp}\')}'
                                                                        }"
                                                                />
                                                        </f:if>
@@ -52,8 +56,8 @@
                                                                        key="logForNonPageRelatedActionsOrRootLevelOrPage"
                                                                        arguments="{
                                                                                0: '{f:translate(key:\'forRootLevel\')}',
-                                                                               1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStart}\')}',
-                                                                               2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStop}\')}'
+                                                                               1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.startTimestamp}\')}',
+                                                                               2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.endTimestamp}\')}'
                                                                        }"
                                                                />
                                                        </f:if>
                                                                2. Use this as argument for 'forPage' translate
                                                                3. Use this as argument for 'logForNonPageRelatedActionsOrRootLevelOrPage' translate
                                                        </f:comment>
-                                                       <f:format.raw>
-                                                               <f:translate
-                                                                       key="logForNonPageRelatedActionsOrRootLevelOrPage"
-                                                                       arguments="{
+                                                       <f:translate
+                                                               key="logForNonPageRelatedActionsOrRootLevelOrPage"
+                                                               arguments="{
                                                                        0: '{f:translate(
                                                                                key:\'forPage\',
                                                                                arguments:\'{
                                                                                        1:\\\'{pid}\\\'
                                                                                }\'
                                                                        )}',
-                                                                       1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStart}\')}',
-                                                                       2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStop}\')}'
+                                                                       1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.startTimestamp}\')}',
+                                                                       2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.endTimestamp}\')}'
                                                                }"
-                                                               />
-                                                       </f:format.raw>
+                                                       />
                                                </f:else>
                                        </f:if>
                                </f:then>
@@ -89,8 +91,8 @@
                                                key="logForNonPageRelatedActionsOrRootLevelOrPage"
                                                arguments="{
                                                        0: '',
-                                                       1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStart}\')}',
-                                                       2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'{constraint.manualDateStop}\')}'
+                                                       1: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.startTimestamp}\')}',
+                                                       2: '{f:format.date(format:\'{settings.dateFormat} {settings.timeFormat}\', date:\'@{constraint.endTimestamp}\')}'
                                                }"
                                        />
                                </f:else>
                                                                <f:translate key="chLog_l_user"/>
                                                        </th>
                                                        <th>
-                                                               <f:if condition="{constraint.isInPageContext}">
+                                                               <f:if condition="{isSubmoduleLayout}">
                                                                        <f:then>
                                                                                <f:translate key="chLog_l_table"/>
                                                                        </f:then>
                                                                        </span>
                                                                </td>
                                                                <td>
-                                                                       <f:if condition="{constraint.isInPageContext}">
+                                                                       <f:if condition="{isSubmoduleLayout}">
                                                                                <f:then>
                                                                                        {logItem.tableName}
                                                                                </f:then>
                                                                </td>
                                                                <td>
                                                                        <f:if condition="{logItem.error} == 1">
-                                                                               <f:link.action action="deleteMessage" arguments="{errorUid:logItem.uid}"
-                                                                                                          class="btn btn-warning">
+                                                                               <f:link.action action="deleteMessage" arguments="{errorUid:logItem.uid}" class="btn btn-warning">
                                                                                        <f:translate key="actions.deleteWarnings"/>
                                                                                </f:link.action>
                                                                        </f:if>
                                                                        <f:if condition="{logItem.error} == 2">
-                                                                               <f:link.action action="deleteMessage" arguments="{errorUid:logItem.uid}"
-                                                                                                          class="btn btn-danger">
+                                                                               <f:link.action action="deleteMessage" arguments="{errorUid:logItem.uid}" class="btn btn-danger">
                                                                                        <f:translate key="actions.delete"/>
                                                                                </f:link.action>
                                                                        </f:if>
                </f:for>
        </div>
 </f:for>
+
+</html>
diff --git a/typo3/sysext/belog/Resources/Private/Templates/BackendLog/List.html b/typo3/sysext/belog/Resources/Private/Templates/BackendLog/List.html
new file mode 100644 (file)
index 0000000..61f4f53
--- /dev/null
@@ -0,0 +1,26 @@
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    data-namespace-typo3-fluid="true">
+
+<f:layout name="{layout}"/>
+<f:section name="Content">
+       <h1>
+               <f:translate key="adminLog" />
+       </h1>
+
+       <div>
+               <f:render
+                       partial="Content/Filter"
+                       arguments="{_all}"
+               />
+       </div>
+
+       <div class="divider"></div>
+
+       <f:render
+               partial="Content/LogEntries"
+               arguments="{_all}"
+       />
+</f:section>
+
+</html>
diff --git a/typo3/sysext/belog/Resources/Private/Templates/Tools/Index.html b/typo3/sysext/belog/Resources/Private/Templates/Tools/Index.html
deleted file mode 100644 (file)
index 7ab52f6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<f:flashMessages />
-<f:render partial="Content" arguments="{_all}" />
\ No newline at end of file
diff --git a/typo3/sysext/belog/Resources/Private/Templates/WebInfo/Index.html b/typo3/sysext/belog/Resources/Private/Templates/WebInfo/Index.html
deleted file mode 100644 (file)
index b2de4e7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<f:render partial="Content" arguments="{_all}" />
\ No newline at end of file
index b74dd94..499b38c 100644 (file)
@@ -16,8 +16,7 @@ defined('TYPO3_MODE') or die();
     'log',
     '',
     [
-        'Tools' => 'index,deleteMessage',
-        'WebInfo' => 'index',
+        'BackendLog' => 'list,deleteMessage',
     ],
     [
         'access' => 'admin',
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/ModuleLayoutViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/ModuleLayoutViewHelper.php
new file mode 100644 (file)
index 0000000..6993db2
--- /dev/null
@@ -0,0 +1,69 @@
+<?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();
+    }
+}