02f8d14a9263f5bee6ae8be54cb085b6e9665860
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / Classes / Report / Status / Status.php
1 <?php
2 namespace TYPO3\CMS\Reports\Report\Status;
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\Utility\IconUtility;
18 use TYPO3\CMS\Reports\ExtendedStatusProviderInterface;
19 use TYPO3\CMS\Reports\ReportInterface;
20 use TYPO3\CMS\Reports\StatusProviderInterface;
21
22 /**
23 * The status report
24 *
25 * @author Ingo Renner <ingo@typo3.org>
26 */
27 class Status implements ReportInterface {
28
29 /**
30 * @var StatusProviderInterface[][]
31 */
32 protected $statusProviders = array();
33
34 /**
35 * Constructor for class tx_reports_report_Status
36 */
37 public function __construct() {
38 $this->getStatusProviders();
39 $GLOBALS['LANG']->includeLLFile('EXT:reports/reports/locallang.xlf');
40 }
41
42 /**
43 * Takes care of creating / rendering the status report
44 *
45 * @return string The status report as HTML
46 */
47 public function getReport() {
48 $content = '';
49 $status = $this->getSystemStatus();
50 $highestSeverity = $this->getHighestSeverity($status);
51 // Updating the registry
52 $registry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Registry::class);
53 $registry->set('tx_reports', 'status.highestSeverity', $highestSeverity);
54 $content .= '<p class="lead">' . $GLOBALS['LANG']->getLL('status_report_explanation') . '</p>';
55 return $content . $this->renderStatus($status);
56 }
57
58 /**
59 * Gets all registered status providers and creates instances of them.
60 *
61 * @return void
62 */
63 protected function getStatusProviders() {
64 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['reports']['tx_reports']['status']['providers'] as $key => $statusProvidersList) {
65 $this->statusProviders[$key] = array();
66 foreach ($statusProvidersList as $statusProvider) {
67 $statusProviderInstance = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($statusProvider);
68 if ($statusProviderInstance instanceof StatusProviderInterface) {
69 $this->statusProviders[$key][] = $statusProviderInstance;
70 }
71 }
72 }
73 }
74
75 /**
76 * Runs through all status providers and returns all statuses collected.
77 *
78 * @return \TYPO3\CMS\Reports\Status[]
79 */
80 public function getSystemStatus() {
81 $status = array();
82 foreach ($this->statusProviders as $statusProviderId => $statusProviderList) {
83 $status[$statusProviderId] = array();
84 foreach ($statusProviderList as $statusProvider) {
85 $statuses = $statusProvider->getStatus();
86 $status[$statusProviderId] = array_merge($status[$statusProviderId], $statuses);
87 }
88 }
89 return $status;
90 }
91
92 /**
93 * Runs through all status providers and returns all statuses collected, which are detailed.
94 *
95 * @return \TYPO3\CMS\Reports\Status[]
96 */
97 public function getDetailedSystemStatus() {
98 $status = array();
99 foreach ($this->statusProviders as $statusProviderId => $statusProviderList) {
100 $status[$statusProviderId] = array();
101 foreach ($statusProviderList as $statusProvider) {
102 if ($statusProvider instanceof ExtendedStatusProviderInterface) {
103 $statuses = $statusProvider->getDetailedStatus();
104 $status[$statusProviderId] = array_merge($status[$statusProviderId], $statuses);
105 }
106 }
107 }
108 return $status;
109 }
110
111 /**
112 * Determines the highest severity from the given statuses.
113 *
114 * @param array $statusCollection An array of \TYPO3\CMS\Reports\Status objects.
115 * @return int The highest severity found from the statuses.
116 */
117 public function getHighestSeverity(array $statusCollection) {
118 $highestSeverity = \TYPO3\CMS\Reports\Status::NOTICE;
119 foreach ($statusCollection as $statusProvider => $providerStatuses) {
120 /** @var $status \TYPO3\CMS\Reports\Status */
121 foreach ($providerStatuses as $status) {
122 if ($status->getSeverity() > $highestSeverity) {
123 $highestSeverity = $status->getSeverity();
124 }
125 // Reached the highest severity level, no need to go on
126 if ($highestSeverity == \TYPO3\CMS\Reports\Status::ERROR) {
127 break;
128 }
129 }
130 }
131 return $highestSeverity;
132 }
133
134 /**
135 * Renders the system's status
136 *
137 * @param array $statusCollection An array of statuses as returned by the available status providers
138 * @return string The system status as an HTML table
139 */
140 protected function renderStatus(array $statusCollection) {
141 $content = '';
142 $template = '
143 <tr>
144 <td class="###CLASS### col-xs-6">###HEADER###</td>
145 <td class="###CLASS### col-xs-6">###STATUS###<br>###CONTENT###</td>
146 </tr>
147 ';
148 $statuses = $this->sortStatusProviders($statusCollection);
149 $id = 0;
150 foreach ($statuses as $provider => $providerStatus) {
151 $providerState = $this->sortStatuses($providerStatus);
152 $id++;
153 $classes = array(
154 \TYPO3\CMS\Reports\Status::NOTICE => 'notice',
155 \TYPO3\CMS\Reports\Status::INFO => 'info',
156 \TYPO3\CMS\Reports\Status::OK => 'success',
157 \TYPO3\CMS\Reports\Status::WARNING => 'warning',
158 \TYPO3\CMS\Reports\Status::ERROR => 'danger'
159 );
160 $messages = '';
161 /** @var $status \TYPO3\CMS\Reports\Status */
162 foreach ($providerState as $status) {
163 $severity = $status->getSeverity();
164 $messages .= strtr($template, array(
165 '###CLASS###' => $classes[$severity],
166 '###HEADER###' => $status->getTitle(),
167 '###STATUS###' => $status->getValue(),
168 '###CONTENT###' => $status->getMessage()
169 ));
170 }
171 $header = '<h2>' . $provider . '</h2>';
172 $table = '<table class="t3-table">';
173 $table .= '<tbody>' . $messages . '</tbody>';
174 $table .= '</table>';
175
176 $content .= $header . $table;
177 }
178 return $content;
179 }
180
181 /**
182 * Sorts the status providers (alphabetically and puts primary status providers at the beginning)
183 *
184 * @param array $statusCollection A collection of statuses (with providers)
185 * @return array The collection of statuses sorted by provider (beginning with provider "_install")
186 */
187 protected function sortStatusProviders(array $statusCollection) {
188 // Extract the primary status collections, i.e. the status groups
189 // that must appear on top of the status report
190 // Change their keys to localized collection titles
191 $primaryStatuses = array(
192 $GLOBALS['LANG']->getLL('status_typo3') => $statusCollection['typo3'],
193 $GLOBALS['LANG']->getLL('status_system') => $statusCollection['system'],
194 $GLOBALS['LANG']->getLL('status_security') => $statusCollection['security'],
195 $GLOBALS['LANG']->getLL('status_configuration') => $statusCollection['configuration']
196 );
197 unset($statusCollection['typo3'], $statusCollection['system'], $statusCollection['security'], $statusCollection['configuration']);
198 // Assemble list of secondary status collections with left-over collections
199 // Change their keys using localized labels if available
200 // TODO extract into getLabel() method
201 $secondaryStatuses = array();
202 foreach ($statusCollection as $statusProviderId => $collection) {
203 $label = '';
204 if (strpos($statusProviderId, 'LLL:') === 0) {
205 // Label provided by extension
206 $label = $GLOBALS['LANG']->sL($statusProviderId);
207 } else {
208 // Generic label
209 $label = $GLOBALS['LANG']->getLL('status_' . $statusProviderId);
210 }
211 $providerLabel = empty($label) ? $statusProviderId : $label;
212 $secondaryStatuses[$providerLabel] = $collection;
213 }
214 // Sort the secondary status collections alphabetically
215 ksort($secondaryStatuses);
216 $orderedStatusCollection = array_merge($primaryStatuses, $secondaryStatuses);
217 return $orderedStatusCollection;
218 }
219
220 /**
221 * Sorts the statuses by severity
222 *
223 * @param array $statusCollection A collection of statuses per provider
224 * @return array The collection of statuses sorted by severity
225 */
226 protected function sortStatuses(array $statusCollection) {
227 $statuses = array();
228 $sortTitle = array();
229 $header = NULL;
230 /** @var $status \TYPO3\CMS\Reports\Status */
231 foreach ($statusCollection as $status) {
232 if ($status->getTitle() === 'TYPO3') {
233 $header = $status;
234 continue;
235 }
236 $statuses[] = $status;
237 $sortTitle[] = $status->getSeverity();
238 }
239 array_multisort($sortTitle, SORT_DESC, $statuses);
240 // Making sure that the core version information is always on the top
241 if (is_object($header)) {
242 array_unshift($statuses, $header);
243 }
244 return $statuses;
245 }
246
247 }