Completed
Branch master (d17104)
by Christian
21:20
created

Log   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 73
dl 0
loc 171
rs 10
c 0
b 0
f 0
wmc 21

9 Methods

Rating   Name   Duplication   Size   Complexity  
B getContent() 0 32 7
A getConfigOption() 0 3 1
A initializeModule() 0 10 1
A getIdentifier() 0 3 1
A getLabel() 0 4 1
A __construct() 0 3 1
A getDataToStore() 0 25 3
A setLoggingConfigRecursive() 0 11 4
A getSettings() 0 24 2
1
<?php
2
declare(strict_types = 1);
3
4
namespace TYPO3\CMS\Adminpanel\Modules\Debug;
5
6
/*
7
 * This file is part of the TYPO3 CMS project.
8
 *
9
 * It is free software; you can redistribute it and/or modify it under
10
 * the terms of the GNU General Public License, either version 2
11
 * of the License, or any later version.
12
 *
13
 * For the full copyright and license information, please read the
14
 * LICENSE.txt file that was distributed with this source code.
15
 *
16
 * The TYPO3 project - inspiring people to share!
17
 */
18
19
use Psr\Http\Message\ServerRequestInterface;
20
use TYPO3\CMS\Adminpanel\Log\InMemoryLogWriter;
21
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
22
use TYPO3\CMS\Adminpanel\ModuleApi\ContentProviderInterface;
23
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
24
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
25
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
26
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleSettingsProviderInterface;
27
use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
28
use TYPO3\CMS\Core\Log\LogLevel;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
30
use TYPO3\CMS\Fluid\View\StandaloneView;
31
32
/**
33
 * Log Sub Module of the AdminPanel
34
 *
35
 * @internal
36
 */
37
class Log extends AbstractSubModule implements DataProviderInterface, ContentProviderInterface, ModuleSettingsProviderInterface, InitializableInterface
38
{
39
    protected $logLevel = LogLevel::INFO;
40
41
    /**
42
     * @var ConfigurationService
43
     */
44
    protected $configurationService;
45
46
    public function __construct()
47
    {
48
        $this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
49
    }
50
51
    /**
52
     * @return string
53
     */
54
    public function getIdentifier(): string
55
    {
56
        return 'debug_log';
57
    }
58
59
    /**
60
     * Sub-Module label
61
     *
62
     * @return string
63
     */
64
    public function getLabel(): string
65
    {
66
        return $this->getLanguageService()->sL(
67
            'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.log.label'
68
        );
69
    }
70
71
    /**
72
     * @inheritdoc
73
     */
74
    public function getDataToStore(ServerRequestInterface $request): ModuleData
75
    {
76
        $levels = [];
77
        for ($i = 1; $i <= LogLevel::DEBUG; $i++) {
78
            $levels[] = [
79
                'level' => $i,
80
                'levelName' => LogLevel::getName($i),
81
            ];
82
        }
83
84
        $log = InMemoryLogWriter::$log;
85
86
        $logArray = [];
87
        /** @var \TYPO3\CMS\Core\Log\LogRecord $logRecord */
88
        foreach ($log as $logRecord) {
89
            $entry = $logRecord->toArray();
90
            // store only necessary info
91
            unset($entry['data']);
92
            $logArray[] = $entry;
93
        }
94
        return new ModuleData(
95
            [
96
                'levels' => $levels,
97
                'startLevel' => (int)$this->getConfigOption('startLevel'),
98
                'log' => $logArray,
99
            ]
100
        );
101
    }
102
103
    /**
104
     * @inheritdoc
105
     */
106
    public function getSettings(): string
107
    {
108
        $view = GeneralUtility::makeInstance(StandaloneView::class);
109
        $templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Debug/LogSettings.html';
110
        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
111
        $view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
112
113
        $levels = [];
114
        for ($i = 1; $i <= LogLevel::DEBUG; $i++) {
115
            $levels[] = [
116
                'level' => $i,
117
                'levelName' => LogLevel::getName($i),
118
            ];
119
        }
120
        $view->assignMultiple(
121
            [
122
                'levels' => $levels,
123
                'startLevel' => (int)$this->getConfigOption('startLevel'),
124
                'groupByComponent' => $this->getConfigOption('groupByComponent'),
125
                'groupByLevel' => $this->getConfigOption('groupByLevel'),
126
            ]
127
        );
128
129
        return $view->render();
130
    }
131
132
    /**
133
     * Sub-Module content as rendered HTML
134
     *
135
     * @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleData $data
136
     * @return string
137
     */
138
    public function getContent(ModuleData $data): string
139
    {
140
        $this->logLevel = $this->getConfigOption('startLevel');
141
        $view = GeneralUtility::makeInstance(StandaloneView::class);
142
        $templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Debug/Log.html';
143
        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
144
        $view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
145
        $sortedLog = [];
146
        // settings for this module
147
        $groupByComponent = $this->getConfigOption('groupByComponent');
148
        $groupByLevel = $this->getConfigOption('groupByLevel');
149
150
        foreach ($data['log'] as $logRecord) {
151
            if ($logRecord['level'] > $this->logLevel) {
152
                continue;
153
            }
154
            if ($groupByComponent && $groupByLevel) {
155
                $sortedLog[$logRecord['component']][LogLevel::getName($logRecord['level'])][] = $logRecord;
156
            } elseif ($groupByComponent) {
157
                $sortedLog[$logRecord['component']][] = $logRecord;
158
            } elseif ($groupByLevel) {
159
                $sortedLog[$logRecord['level']][] = $logRecord;
160
            } else {
161
                $sortedLog[] = $logRecord;
162
            }
163
        }
164
        $data['log'] = $sortedLog;
165
        $data['groupByComponent'] = $groupByComponent;
166
        $data['groupByLevel'] = $groupByLevel;
167
        $view->assignMultiple($data->getArrayCopy());
168
169
        return $view->render();
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175
    public function initializeModule(ServerRequestInterface $request): void
176
    {
177
        $this->logLevel = $this->getConfigOption('startLevel');
178
179
        // set inMemoryLogWriter recursively for all configured namespaces/areas so we don't lose log entries
180
        $configWithInMemoryWriter = $this->setLoggingConfigRecursive($GLOBALS['TYPO3_CONF_VARS']['LOG'] ?? []);
181
182
        // in case there are empty array parts, remove them
183
        $GLOBALS['TYPO3_CONF_VARS']['LOG'] = array_filter(
184
            $configWithInMemoryWriter
185
        );
186
    }
187
188
    protected function setLoggingConfigRecursive(array $logConfig): array
189
    {
190
        foreach ($logConfig as $key => $value) {
191
            if ($key === 'writerConfiguration') {
192
                $logConfig[$key] = $value;
193
                $logConfig[$key][LogLevel::DEBUG][InMemoryLogWriter::class] = [];
194
            } elseif (is_array($value)) {
195
                $logConfig[$key] = $this->setLoggingConfigRecursive($value);
196
            }
197
        }
198
        return $logConfig;
199
    }
200
201
    /**
202
     * @param string $option
203
     * @return string
204
     */
205
    protected function getConfigOption(string $option): string
206
    {
207
        return $this->configurationService->getConfigurationOption('debug_log', $option);
208
    }
209
}
210