c5a8d06e33349fa614a679e5b050796967d7b9db
[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\Toolbar\ToolbarItemInterface;
18 use TYPO3\CMS\Backend\Toolbar\Enumeration\InformationStatus;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
20 use TYPO3\CMS\Backend\Utility\IconUtility;
21 use TYPO3\CMS\Core\Http\AjaxRequestHandler;
22 use \TYPO3\CMS\Core\Page\PageRenderer;
23 use TYPO3\CMS\Core\Utility\CommandUtility;
24 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26 use TYPO3\CMS\Core\Utility\StringUtility;
27 use TYPO3\CMS\Fluid\View\StandaloneView;
28
29 /**
30 * Render system info toolbar item
31 */
32 class SystemInformationToolbarItem implements ToolbarItemInterface {
33
34 /**
35 * @var StandaloneView
36 */
37 protected $standaloneView = NULL;
38
39 /**
40 * Template file for the dropdown menu
41 */
42 const TOOLBAR_MENU_TEMPLATE = 'SystemInformation.html';
43
44 /**
45 * Number displayed as badge on the dropdown trigger
46 *
47 * @var int
48 */
49 protected $totalCount = 0;
50
51 /**
52 * Holds the highest severity
53 *
54 * @var string
55 */
56 protected $highestSeverity = '';
57
58 /**
59 * The CSS class for the badge
60 *
61 * @var string
62 */
63 protected $severityBadgeClass = '';
64
65 /**
66 * @var array
67 */
68 protected $systemInformation = array();
69
70 /**
71 * @var array
72 */
73 protected $systemMessages = array();
74
75 /**
76 * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
77 */
78 protected $signalSlotDispatcher = NULL;
79
80 /**
81 * Constructor
82 */
83 public function __construct() {
84 if (!$this->checkAccess()) {
85 return;
86 }
87
88 $extPath = ExtensionManagementUtility::extPath('backend');
89 /* @var $view StandaloneView */
90 $this->standaloneView = GeneralUtility::makeInstance(StandaloneView::class);
91 $this->standaloneView->setTemplatePathAndFilename($extPath . 'Resources/Private/Templates/ToolbarMenu/' . static::TOOLBAR_MENU_TEMPLATE);
92
93 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/SystemInformationMenu');
94 }
95
96 /**
97 * Collect the information for the menu
98 */
99 protected function collectInformation() {
100 $this->getWebServer();
101 $this->getPhpVersion();
102 $this->getDatabase();
103 $this->getApplicationContext();
104 $this->getGitRevision();
105 $this->getOperatingSystem();
106
107 $this->emitGetSystemInformation();
108 $this->emitLoadMessages();
109
110 $this->severityBadgeClass = $this->highestSeverity !== InformationStatus::STATUS_NOTICE ? 'badge-' . $this->highestSeverity : '';
111 }
112
113 /**
114 * Renders the menu for AJAX calls
115 *
116 * @param array $params
117 * @param AjaxRequestHandler $ajaxObj
118 */
119 public function renderAjax($params = array(), $ajaxObj) {
120 $this->collectInformation();
121 $ajaxObj->addContent('systemInformationMenu', $this->getDropDown());
122 }
123
124 /**
125 * Gets the PHP version
126 *
127 * @return void
128 */
129 protected function getPhpVersion() {
130 $this->systemInformation[] = array(
131 'title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.phpversion', TRUE),
132 'value' => PHP_VERSION,
133 'icon' => '<span class="fa fa-code"></span>'
134 );
135 }
136
137 /**
138 * Get the database info
139 *
140 * @return void
141 */
142 protected function getDatabase() {
143 $this->systemInformation[] = array(
144 'title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.database', TRUE),
145 'value' => $this->getDatabaseConnection()->getServerVersion(),
146 'icon' => '<span class="fa fa-database"></span>'
147 );
148 }
149
150 /**
151 * Gets the application context
152 *
153 * @return void
154 */
155 protected function getApplicationContext() {
156 $applicationContext = GeneralUtility::getApplicationContext();
157 $this->systemInformation[] = array(
158 'title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.applicationcontext', TRUE),
159 'value' => (string)$applicationContext,
160 'status' => $applicationContext->isProduction() ? InformationStatus::STATUS_OK : InformationStatus::STATUS_WARNING,
161 'icon' => '<span class="fa fa-tasks"></span>'
162 );
163 }
164
165 /**
166 * Gets the current GIT revision and branch
167 *
168 * @return void
169 */
170 protected function getGitRevision() {
171 if (!StringUtility::endsWith(TYPO3_version, '-dev') || \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::isFunctionDisabled('exec')) {
172 return;
173 }
174 // check if git exists
175 CommandUtility::exec('git --version', $_, $returnCode);
176 if ((int)$returnCode !== 0) {
177 // git is not available
178 return;
179 }
180
181 $revision = trim(CommandUtility::exec('git rev-parse --short HEAD'));
182 $branch = trim(CommandUtility::exec('git rev-parse --abbrev-ref HEAD'));
183 if (!empty($revision) && !empty($branch)) {
184 $this->systemInformation[] = array(
185 'title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.gitrevision', TRUE),
186 'value' => sprintf('%s [%s]', $revision, $branch),
187 'icon' => '<span class="fa fa-git"></span>'
188 );
189 }
190 }
191
192 /**
193 * Gets the system kernel and version
194 *
195 * @return void
196 */
197 protected function getOperatingSystem() {
198 $kernelName = php_uname('s');
199 switch (strtolower($kernelName)) {
200 case 'linux':
201 $icon = 'linux';
202 break;
203 case 'darwin':
204 $icon = 'apple';
205 break;
206 default:
207 $icon = 'windows';
208 }
209 $this->systemInformation[] = array(
210 'title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.operatingsystem', TRUE),
211 'value' => $kernelName . ' ' . php_uname('r'),
212 'icon' => '<span class="fa fa-' . htmlspecialchars($icon) . '"></span>'
213 );
214 }
215
216 /**
217 * Gets the webserver software
218 */
219 protected function getWebServer() {
220 $this->systemInformation[] = array(
221 'title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo.webserver', TRUE),
222 'value' => htmlspecialchars($_SERVER['SERVER_SOFTWARE']),
223 'icon' => '<span class="fa fa-server"></span>'
224 );
225 }
226
227 /**
228 * Emits the "getSystemInformation" signal
229 *
230 * @return void
231 */
232 protected function emitGetSystemInformation() {
233 list($systemInformation) = $this->getSignalSlotDispatcher()->dispatch(__CLASS__, 'getSystemInformation', array(array()));
234 if (!empty($systemInformation)) {
235 $this->systemInformation[] = $systemInformation;
236 }
237 }
238
239 /**
240 * Emits the "loadMessages" signal
241 *
242 * @return void
243 */
244 protected function emitLoadMessages() {
245 list($message) = $this->getSignalSlotDispatcher()->dispatch(__CLASS__, 'loadMessages', array(array()));
246 if (empty($message)) {
247 return;
248 }
249
250 // increase counter
251 if (isset($message['count'])) {
252 $this->totalCount += (int)$message['count'];
253 }
254
255 // define the severity for the badge
256 if (InformationStatus::mapStatusToInt($message['status']) > InformationStatus::mapStatusToInt($this->highestSeverity)) {
257 $this->highestSeverity = $message['status'];
258 }
259
260 $this->systemMessages[] = $message;
261 }
262
263 /**
264 * Checks whether the user has access to this toolbar item
265 *
266 * @return bool TRUE if user has access, FALSE if not
267 */
268 public function checkAccess() {
269 return $this->getBackendUserAuthentication()->isAdmin();
270 }
271
272 /**
273 * Render system information dropdown
274 *
275 * @return string Icon HTML
276 */
277 public function getItem() {
278 $title = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.sysinfo', TRUE);
279 return IconUtility::getSpriteIcon('actions-system-list-open', array('title' => $title))
280 . '<span id="t3js-systeminformation-counter" class="badge"></span>';
281 }
282
283 /**
284 * Render drop down
285 *
286 * @return string Drop down HTML
287 */
288 public function getDropDown() {
289 if (!$this->checkAccess()) {
290 return '';
291 }
292
293 $request = $this->standaloneView->getRequest();
294 $request->setControllerExtensionName('backend');
295 $this->standaloneView->assignMultiple(array(
296 'installToolUrl' => BackendUtility::getModuleUrl('system_InstallInstall'),
297 'messages' => $this->systemMessages,
298 'count' => $this->totalCount,
299 'severityBadgeClass' => $this->severityBadgeClass,
300 'systemInformation' => $this->systemInformation
301 ));
302 return $this->standaloneView->render();
303 }
304
305 /**
306 * No additional attributes needed.
307 *
308 * @return array
309 */
310 public function getAdditionalAttributes() {
311 return array();
312 }
313
314 /**
315 * This item has a drop down
316 *
317 * @return bool
318 */
319 public function hasDropDown() {
320 return TRUE;
321 }
322
323 /**
324 * Position relative to others
325 *
326 * @return int
327 */
328 public function getIndex() {
329 return 75;
330 }
331
332 /**
333 * Returns the current BE user.
334 *
335 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
336 */
337 protected function getBackendUserAuthentication() {
338 return $GLOBALS['BE_USER'];
339 }
340
341 /**
342 * Returns DatabaseConnection
343 *
344 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
345 */
346 protected function getDatabaseConnection() {
347 return $GLOBALS['TYPO3_DB'];
348 }
349
350 /**
351 * Returns current PageRenderer
352 *
353 * @return PageRenderer
354 */
355 protected function getPageRenderer() {
356 return GeneralUtility::makeInstance(PageRenderer::class);
357 }
358
359 /**
360 * Returns LanguageService
361 *
362 * @return \TYPO3\CMS\Lang\LanguageService
363 */
364 protected function getLanguageService() {
365 return $GLOBALS['LANG'];
366 }
367
368 /**
369 * Get the SignalSlot dispatcher
370 *
371 * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
372 */
373 protected function getSignalSlotDispatcher() {
374 if (!isset($this->signalSlotDispatcher)) {
375 $this->signalSlotDispatcher = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class)
376 ->get(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
377 }
378 return $this->signalSlotDispatcher;
379 }
380 }