5f2f4ee03bf1bb23b9b35c5bf33a884dccd8263d
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / Classes / Report / Status / Status.php
1 <?php
2 namespace TYPO3\CMS\Reports\Report\Status;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2009-2013 Ingo Renner <ingo@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26 /**
27 * The status report
28 *
29 * @author Ingo Renner <ingo@typo3.org>
30 */
31 class Status implements \TYPO3\CMS\Reports\ReportInterface {
32
33 /**
34 * @var array
35 */
36 protected $statusProviders = array();
37
38 /**
39 * Constructor for class tx_reports_report_Status
40 */
41 public function __construct() {
42 $this->getStatusProviders();
43 $GLOBALS['LANG']->includeLLFile('EXT:reports/reports/locallang.xlf');
44 }
45
46 /**
47 * Takes care of creating / rendering the status report
48 *
49 * @return string The status report as HTML
50 */
51 public function getReport() {
52 $content = '';
53 $status = $this->getSystemStatus();
54 $highestSeverity = $this->getHighestSeverity($status);
55 // Updating the registry
56 $registry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Registry');
57 $registry->set('tx_reports', 'status.highestSeverity', $highestSeverity);
58 $content .= '<p class="lead">' . $GLOBALS['LANG']->getLL('status_report_explanation') . '</p>';
59 return $content . $this->renderStatus($status);
60 }
61
62 /**
63 * Gets all registered status providers and creates instances of them.
64 *
65 * @return void
66 */
67 protected function getStatusProviders() {
68 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['reports']['tx_reports']['status']['providers'] as $key => $statusProvidersList) {
69 $this->statusProviders[$key] = array();
70 foreach ($statusProvidersList as $statusProvider) {
71 $statusProviderInstance = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($statusProvider);
72 if ($statusProviderInstance instanceof \TYPO3\CMS\Reports\StatusProviderInterface) {
73 $this->statusProviders[$key][] = $statusProviderInstance;
74 }
75 }
76 }
77 }
78
79 /**
80 * Runs through all status providers and returns all statuses collected.
81 *
82 * @return array An array of \TYPO3\CMS\Reports\Status objects
83 */
84 public function getSystemStatus() {
85 $status = array();
86 foreach ($this->statusProviders as $statusProviderId => $statusProviderList) {
87 $status[$statusProviderId] = array();
88 foreach ($statusProviderList as $statusProvider) {
89 $statuses = $statusProvider->getStatus();
90 $status[$statusProviderId] = array_merge($status[$statusProviderId], $statuses);
91 }
92 }
93 return $status;
94 }
95
96 /**
97 * Determines the highest severity from the given statuses.
98 *
99 * @param array $statusCollection An array of \TYPO3\CMS\Reports\Status objects.
100 * @return integer The highest severity found from the statuses.
101 */
102 public function getHighestSeverity(array $statusCollection) {
103 $highestSeverity = \TYPO3\CMS\Reports\Status::NOTICE;
104 foreach ($statusCollection as $statusProvider => $providerStatuses) {
105 /** @var $status \TYPO3\CMS\Reports\Status */
106 foreach ($providerStatuses as $status) {
107 if ($status->getSeverity() > $highestSeverity) {
108 $highestSeverity = $status->getSeverity();
109 }
110 // Reached the highest severity level, no need to go on
111 if ($highestSeverity == \TYPO3\CMS\Reports\Status::ERROR) {
112 break;
113 }
114 }
115 }
116 return $highestSeverity;
117 }
118
119 /**
120 * Renders the system's status
121 *
122 * @param array $statusCollection An array of statuses as returned by the available status providers
123 * @return string The system status as an HTML table
124 */
125 protected function renderStatus(array $statusCollection) {
126 // TODO refactor into separate methods, status list and single status
127 $content = '';
128 $template = '
129 <div class="typo3-message message-###CLASS###">
130 <div class="header-container">
131 <div class="message-header message-left">###HEADER###</div>
132 <div class="message-header message-right">###STATUS###</div>
133 </div>
134 <div class="message-body">###CONTENT###</div>
135 </div>';
136 $statuses = $this->sortStatusProviders($statusCollection);
137 foreach ($statuses as $provider => $providerStatus) {
138 $providerState = $this->sortStatuses($providerStatus);
139 $id = str_replace(' ', '-', $provider);
140 $classes = array(
141 \TYPO3\CMS\Reports\Status::NOTICE => 'notice',
142 \TYPO3\CMS\Reports\Status::INFO => 'information',
143 \TYPO3\CMS\Reports\Status::OK => 'ok',
144 \TYPO3\CMS\Reports\Status::WARNING => 'warning',
145 \TYPO3\CMS\Reports\Status::ERROR => 'error'
146 );
147 $icon[\TYPO3\CMS\Reports\Status::WARNING] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-dialog-warning');
148 $icon[\TYPO3\CMS\Reports\Status::ERROR] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-dialog-error');
149 $messages = '';
150 $headerIcon = '';
151 $sectionSeverity = 0;
152 /** @var $status \TYPO3\CMS\Reports\Status */
153 foreach ($providerState as $status) {
154 $severity = $status->getSeverity();
155 $sectionSeverity = $severity > $sectionSeverity ? $severity : $sectionSeverity;
156 $messages .= strtr($template, array(
157 '###CLASS###' => $classes[$severity],
158 '###HEADER###' => $status->getTitle(),
159 '###STATUS###' => $status->getValue(),
160 '###CONTENT###' => $status->getMessage()
161 ));
162 }
163 if ($sectionSeverity > 0) {
164 $headerIcon = $icon[$sectionSeverity];
165 }
166 $content .= $GLOBALS['TBE_TEMPLATE']->collapseableSection($headerIcon . $provider, $messages, $id, 'reports.states');
167 }
168 return $content;
169 }
170
171 /**
172 * Sorts the status providers (alphabetically and puts primary status providers at the beginning)
173 *
174 * @param array $statusCollection A collection of statuses (with providers)
175 * @return array The collection of statuses sorted by provider (beginning with provider "_install")
176 */
177 protected function sortStatusProviders(array $statusCollection) {
178 // Extract the primary status collections, i.e. the status groups
179 // that must appear on top of the status report
180 // Change their keys to localized collection titles
181 $primaryStatuses = array(
182 $GLOBALS['LANG']->getLL('status_typo3') => $statusCollection['typo3'],
183 $GLOBALS['LANG']->getLL('status_system') => $statusCollection['system'],
184 $GLOBALS['LANG']->getLL('status_security') => $statusCollection['security'],
185 $GLOBALS['LANG']->getLL('status_configuration') => $statusCollection['configuration']
186 );
187 unset($statusCollection['typo3'], $statusCollection['system'], $statusCollection['security'], $statusCollection['configuration']);
188 // Assemble list of secondary status collections with left-over collections
189 // Change their keys using localized labels if available
190 // TODO extract into getLabel() method
191 $secondaryStatuses = array();
192 foreach ($statusCollection as $statusProviderId => $collection) {
193 $label = '';
194 if (strpos($statusProviderId, 'LLL:') === 0) {
195 // Label provided by extension
196 $label = $GLOBALS['LANG']->sL($statusProviderId);
197 } else {
198 // Generic label
199 $label = $GLOBALS['LANG']->getLL('status_' . $statusProviderId);
200 }
201 $providerLabel = empty($label) ? $statusProviderId : $label;
202 $secondaryStatuses[$providerLabel] = $collection;
203 }
204 // Sort the secondary status collections alphabetically
205 ksort($secondaryStatuses);
206 $orderedStatusCollection = array_merge($primaryStatuses, $secondaryStatuses);
207 return $orderedStatusCollection;
208 }
209
210 /**
211 * Sorts the statuses by severity
212 *
213 * @param array $statusCollection A collection of statuses per provider
214 * @return array The collection of statuses sorted by severity
215 */
216 protected function sortStatuses(array $statusCollection) {
217 $statuses = array();
218 $sortTitle = array();
219 /** @var $status \TYPO3\CMS\Reports\Status */
220 foreach ($statusCollection as $status) {
221 if ($status->getTitle() === 'TYPO3') {
222 $header = $status;
223 continue;
224 }
225 $statuses[] = $status;
226 $sortTitle[] = $status->getSeverity();
227 }
228 array_multisort($sortTitle, SORT_DESC, $statuses);
229 // Making sure that the core version information is always on the top
230 if (is_object($header)) {
231 array_unshift($statuses, $header);
232 }
233 return $statuses;
234 }
235
236 }