[TASK] Update typo3/icons to 1.7.0
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Backend / ToolbarItems / SystemInformationToolbarItem.php
1 <?php
2 namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Routing\UriBuilder;
18 use TYPO3\CMS\Backend\Toolbar\Enumeration\InformationStatus;
19 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
20 use TYPO3\CMS\Core\Core\Environment;
21 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
22 use TYPO3\CMS\Core\Database\ConnectionPool;
23 use TYPO3\CMS\Core\Page\PageRenderer;
24 use TYPO3\CMS\Core\Utility\CommandUtility;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26 use TYPO3\CMS\Core\Utility\StringUtility;
27 use TYPO3\CMS\Core\Utility\VersionNumberUtility;
28 use TYPO3\CMS\Extbase\Object\ObjectManager;
29 use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
30 use TYPO3\CMS\Fluid\View\StandaloneView;
31
32 /**
33 * Render system info toolbar item
34 */
35 class SystemInformationToolbarItem implements ToolbarItemInterface
36 {
37 /**
38 * Number displayed as badge on the dropdown trigger
39 *
40 * @var int
41 */
42 protected $totalCount = 0;
43
44 /**
45 * Holds the highest severity
46 *
47 * @var InformationStatus
48 */
49 protected $highestSeverity;
50
51 /**
52 * The CSS class for the badge
53 *
54 * @var string
55 */
56 protected $severityBadgeClass = '';
57
58 /**
59 * @var array
60 */
61 protected $systemInformation = [];
62
63 /**
64 * @var array
65 */
66 protected $systemMessages = [];
67
68 /**
69 * @var Dispatcher
70 */
71 protected $signalSlotDispatcher = null;
72
73 /**
74 * @var int
75 */
76 protected $maximumCountInBadge = 99;
77
78 /**
79 * Constructor
80 */
81 public function __construct()
82 {
83 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/SystemInformationMenu');
84 $this->highestSeverity = InformationStatus::cast(InformationStatus::STATUS_INFO);
85 }
86
87 /**
88 * Add a system message.
89 * This is a callback method for signal receivers.
90 *
91 * @param string $text The text to be displayed
92 * @param string $status The status of this system message
93 * @param int $count Will be added to the total count
94 * @param string $module The associated module
95 * @param string $params Query string with additional parameters
96 */
97 public function addSystemMessage($text, $status = InformationStatus::STATUS_OK, $count = 0, $module = '', $params = '')
98 {
99 $this->totalCount += (int)$count;
100
101 /** @var InformationStatus $messageSeverity */
102 $messageSeverity = InformationStatus::cast($status);
103 // define the severity for the badge
104 if ($messageSeverity->isGreaterThan($this->highestSeverity)) {
105 $this->highestSeverity = $messageSeverity;
106 }
107
108 $this->systemMessages[] = [
109 'module' => $module,
110 'params' => $params,
111 'count' => (int)$count,
112 'status' => $messageSeverity,
113 'text' => $text
114 ];
115 }
116
117 /**
118 * Add a system information.
119 * This is a callback method for signal receivers.
120 *
121 * @param string $title The title of this system information
122 * @param string $value The associated value
123 * @param string $iconIdentifier The icon identifier
124 * @param string $status The status of this system information
125 */
126 public function addSystemInformation($title, $value, $iconIdentifier, $status = InformationStatus::STATUS_NOTICE)
127 {
128 $this->systemInformation[] = [
129 'title' => $title,
130 'value' => $value,
131 'iconIdentifier' => $iconIdentifier,
132 'status' => $status
133 ];
134 }
135
136 /**
137 * Checks whether the user has access to this toolbar item
138 *
139 * @return bool TRUE if user has access, FALSE if not
140 */
141 public function checkAccess()
142 {
143 return $this->getBackendUserAuthentication()->isAdmin();
144 }
145
146 /**
147 * Render system information dropdown
148 *
149 * @return string Icon HTML
150 */
151 public function getItem()
152 {
153 return $this->getFluidTemplateObject('SystemInformationToolbarItem.html')->render();
154 }
155
156 /**
157 * Render drop down
158 *
159 * @return string Drop down HTML
160 */
161 public function getDropDown()
162 {
163 if (!$this->checkAccess()) {
164 return '';
165 }
166
167 $this->collectInformation();
168
169 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
170 $view = $this->getFluidTemplateObject('SystemInformationDropDown.html');
171 $view->assignMultiple([
172 'environmentToolUrl' => (string)$uriBuilder->buildUriFromRoute('tools_toolsenvironment'),
173 'messages' => $this->systemMessages,
174 'count' => $this->totalCount > $this->maximumCountInBadge ? $this->maximumCountInBadge . '+' : $this->totalCount,
175 'severityBadgeClass' => $this->severityBadgeClass,
176 'systemInformation' => $this->systemInformation
177 ]);
178 return $view->render();
179 }
180
181 /**
182 * No additional attributes needed.
183 *
184 * @return array
185 */
186 public function getAdditionalAttributes()
187 {
188 return [];
189 }
190
191 /**
192 * This item has a drop down
193 *
194 * @return bool
195 */
196 public function hasDropDown()
197 {
198 return true;
199 }
200
201 /**
202 * Position relative to others
203 *
204 * @return int
205 */
206 public function getIndex()
207 {
208 return 75;
209 }
210
211 /**
212 * Collect the information for the menu
213 */
214 protected function collectInformation()
215 {
216 $this->getTypo3Version();
217 $this->getWebServer();
218 $this->getPhpVersion();
219 $this->getDatabase();
220 $this->getApplicationContext();
221 $this->getComposerMode();
222 $this->getGitRevision();
223 $this->getOperatingSystem();
224
225 $this->emitGetSystemInformation();
226 $this->emitLoadMessages();
227
228 $this->severityBadgeClass = !$this->highestSeverity->equals(InformationStatus::STATUS_NOTICE) ? 'badge-' . (string)$this->highestSeverity : '';
229 }
230
231 /**
232 * Gets the TYPO3 version
233 */
234 protected function getTypo3Version()
235 {
236 $this->systemInformation[] = [
237 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.typo3-version',
238 'value' => VersionNumberUtility::getCurrentTypo3Version(),
239 'iconIdentifier' => 'information-typo3-version'
240 ];
241 }
242
243 /**
244 * Gets the webserver software
245 */
246 protected function getWebServer()
247 {
248 $this->systemInformation[] = [
249 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.webserver',
250 'value' => $_SERVER['SERVER_SOFTWARE'],
251 'iconIdentifier' => 'information-webserver'
252 ];
253 }
254
255 /**
256 * Gets the PHP version
257 */
258 protected function getPhpVersion()
259 {
260 $this->systemInformation[] = [
261 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.phpversion',
262 'value' => PHP_VERSION,
263 'iconIdentifier' => 'information-php-version'
264 ];
265 }
266
267 /**
268 * Get the database info
269 */
270 protected function getDatabase()
271 {
272 foreach (GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionNames() as $connectionName) {
273 $this->systemInformation[] = [
274 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.database',
275 'titleAddition' => $connectionName,
276 'value' => GeneralUtility::makeInstance(ConnectionPool::class)
277 ->getConnectionByName($connectionName)
278 ->getServerVersion(),
279 'iconIdentifier' => 'information-database'
280 ];
281 }
282 }
283
284 /**
285 * Gets the application context
286 */
287 protected function getApplicationContext()
288 {
289 $applicationContext = GeneralUtility::getApplicationContext();
290 $this->systemInformation[] = [
291 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.applicationcontext',
292 'value' => (string)$applicationContext,
293 'status' => $applicationContext->isProduction() ? InformationStatus::STATUS_OK : InformationStatus::STATUS_WARNING,
294 'iconIdentifier' => 'information-application-context'
295 ];
296 }
297
298 /**
299 * Adds the information if the Composer mode is enabled or disabled to the displayed system information
300 */
301 protected function getComposerMode()
302 {
303 if (!Environment::isComposerMode()) {
304 return;
305 }
306
307 $this->systemInformation[] = [
308 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.composerMode',
309 'value' => $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.enabled'),
310 'iconIdentifier' => 'information-composer-mode'
311 ];
312 }
313
314 /**
315 * Gets the current GIT revision and branch
316 */
317 protected function getGitRevision()
318 {
319 if (!StringUtility::endsWith(TYPO3_version, '-dev') || SystemEnvironmentBuilder::isFunctionDisabled('exec')) {
320 return;
321 }
322 // check if git exists
323 CommandUtility::exec('git --version', $_, $returnCode);
324 if ((int)$returnCode !== 0) {
325 // git is not available
326 return;
327 }
328
329 $revision = trim(CommandUtility::exec('git rev-parse --short HEAD'));
330 $branch = trim(CommandUtility::exec('git rev-parse --abbrev-ref HEAD'));
331 if (!empty($revision) && !empty($branch)) {
332 $this->systemInformation[] = [
333 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.gitrevision',
334 'value' => sprintf('%s [%s]', $revision, $branch),
335 'iconIdentifier' => 'information-git'
336 ];
337 }
338 }
339
340 /**
341 * Gets the system kernel and version
342 */
343 protected function getOperatingSystem()
344 {
345 $kernelName = php_uname('s');
346 switch (strtolower($kernelName)) {
347 case 'linux':
348 $icon = 'linux';
349 break;
350 case 'darwin':
351 $icon = 'apple';
352 break;
353 default:
354 $icon = 'windows';
355 }
356 $this->systemInformation[] = [
357 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.operatingsystem',
358 'value' => $kernelName . ' ' . php_uname('r'),
359 'iconIdentifier' => 'information-os-' . $icon
360 ];
361 }
362
363 /**
364 * Emits the "getSystemInformation" signal
365 */
366 protected function emitGetSystemInformation()
367 {
368 $this->getSignalSlotDispatcher()->dispatch(__CLASS__, 'getSystemInformation', [$this]);
369 }
370
371 /**
372 * Emits the "loadMessages" signal
373 */
374 protected function emitLoadMessages()
375 {
376 $this->getSignalSlotDispatcher()->dispatch(__CLASS__, 'loadMessages', [$this]);
377 }
378
379 /**
380 * Returns a new standalone view, shorthand function
381 *
382 * @param string $filename Which templateFile should be used.
383 * @return StandaloneView
384 */
385 protected function getFluidTemplateObject(string $filename): StandaloneView
386 {
387 $view = GeneralUtility::makeInstance(StandaloneView::class);
388 $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']);
389 $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']);
390 $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']);
391
392 $view->setTemplate($filename);
393
394 $view->getRequest()->setControllerExtensionName('Backend');
395 return $view;
396 }
397
398 /**
399 * Returns the current BE user.
400 *
401 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
402 */
403 protected function getBackendUserAuthentication()
404 {
405 return $GLOBALS['BE_USER'];
406 }
407
408 /**
409 * Returns current PageRenderer
410 *
411 * @return PageRenderer
412 */
413 protected function getPageRenderer()
414 {
415 return GeneralUtility::makeInstance(PageRenderer::class);
416 }
417
418 /**
419 * Get the SignalSlot dispatcher
420 *
421 * @return Dispatcher
422 */
423 protected function getSignalSlotDispatcher()
424 {
425 if (!isset($this->signalSlotDispatcher)) {
426 $this->signalSlotDispatcher = GeneralUtility::makeInstance(ObjectManager::class)->get(Dispatcher::class);
427 }
428 return $this->signalSlotDispatcher;
429 }
430 }