[TASK] Remove dependency to extbase from reports module
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / Classes / Report / ServicesListReport.php
1 <?php
2 namespace TYPO3\CMS\Reports\Report;
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\Core\Exception;
18 use TYPO3\CMS\Core\Utility\CommandUtility;
19 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Fluid\View\StandaloneView;
22 use TYPO3\CMS\Reports\Controller\ReportController;
23 use TYPO3\CMS\Reports\ReportInterface;
24
25 /**
26 * This class provides a report displaying a list of all installed services
27 */
28 class ServicesListReport implements ReportInterface
29 {
30 /**
31 * @var ReportController
32 */
33 protected $reportsModule;
34
35 /**
36 * Constructor
37 *
38 * @param ReportController $reportsModule Back-reference to the calling reports module
39 */
40 public function __construct(ReportController $reportsModule)
41 {
42 $this->reportsModule = $reportsModule;
43 $this->getLanguageService()->includeLLFile('EXT:reports/Resources/Private/Language/locallang_servicereport.xlf');
44 }
45
46 /**
47 * This method renders the report
48 *
49 * @return string The status report as HTML
50 */
51 public function getReport()
52 {
53 // Rendering of the output via fluid
54 $view = GeneralUtility::makeInstance(StandaloneView::class);
55 $view->getRequest()->setControllerExtensionName('Reports');
56 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
57 'EXT:reports/Resources/Private/Templates/ServicesListReport.html'
58 ));
59
60 $view->assignMultiple([
61 'servicesList' => $this->getServicesList(),
62 'searchPaths' => $this->getExecutablesSearchPathList()
63 ]);
64
65 return $view->render();
66 }
67
68 /**
69 * This method assembles a list of all installed services
70 *
71 * @return array with data to display
72 */
73 protected function getServicesList()
74 {
75 $servicesList = [];
76 $services = $this->getInstalledServices();
77 foreach ($services as $serviceType => $installedServices) {
78 $servicesList[] = $this->getServiceTypeList($serviceType, $installedServices);
79 }
80 return $servicesList;
81 }
82
83 /**
84 * Get the services list for a single service type.
85 *
86 * @param string $serviceType The service type to render the installed services list for
87 * @param array $services List of services for the given type
88 * @return array Service list as array for one service type
89 */
90 protected function getServiceTypeList($serviceType, $services)
91 {
92 $lang = $this->getLanguageService();
93 $serviceList = [];
94 $serviceList['Type'] = sprintf($lang->getLL('service_type'), $serviceType);
95
96 $serviceList['Services'] = [];
97 foreach ($services as $serviceKey => $serviceInformation) {
98 $serviceList['Services'][] = $this->getServiceRow($serviceKey, $serviceInformation);
99 }
100
101 return $serviceList;
102 }
103
104 /**
105 * Get data of a single service's row.
106 *
107 * @param string $serviceKey The service key to access the service.
108 * @param array $serviceInformation registration information of the service.
109 * @return array data for one row for the service.
110 */
111 protected function getServiceRow($serviceKey, $serviceInformation)
112 {
113 $result = [
114 'Key' => $serviceKey,
115 'Information' => $serviceInformation,
116 'Subtypes' => $serviceInformation['serviceSubTypes'] ? implode(', ', $serviceInformation['serviceSubTypes']) : '-',
117 'OperatingSystem' => $serviceInformation['os'] ?: $this->getLanguageService()->getLL('any'),
118 'RequiredExecutables' => $serviceInformation['exec'] ?: '-',
119 'AvailabilityClass' => 'danger',
120 'Available' => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:no'),
121 ];
122
123 try {
124 $serviceDetails = ExtensionManagementUtility::findServiceByKey($serviceKey);
125 if ($serviceDetails['available']) {
126 $result['AvailabilityClass'] = 'success';
127 $result['Available'] = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:yes');
128 }
129 } catch (Exception $e) {
130 }
131
132 return $result;
133 }
134
135 /**
136 * This method assembles a list of all defined executables search paths
137 *
138 * @return array data to display
139 */
140 protected function getExecutablesSearchPathList()
141 {
142 $searchPaths = CommandUtility::getPaths(true);
143 $result = [];
144
145 foreach ($searchPaths as $path => $isValid) {
146 $searchPathData = $this->getServicePathStatus($isValid);
147 $result[] = [
148 'class' => $searchPathData['statusCSSClass'],
149 'accessible' => 'LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:' . $searchPathData['accessible'],
150 'path' => GeneralUtility::fixWindowsFilePath($path),
151 ];
152 }
153
154 return $result;
155 }
156
157 /**
158 * This method filters the $T3_SERVICES global array to return a relevant,
159 * ordered list of installed services.
160 *
161 * Every installed service appears twice in $T3_SERVICES: once as a service key
162 * for a given service type, and once a service type all by itself
163 * The list of services to display must avoid these duplicates
164 *
165 * Furthermore, inside each service type, installed services must be
166 * ordered by priority and quality
167 *
168 * @return array List of filtered and ordered services
169 */
170 protected function getInstalledServices()
171 {
172 $filteredServices = [];
173 foreach ($GLOBALS['T3_SERVICES'] as $serviceType => $serviceList) {
174 // If the (first) key of the service list is not the same as the service type,
175 // it's a "true" service type. Keep it and sort it.
176 if (key($serviceList) !== $serviceType) {
177 uasort($serviceList, [$this, 'sortServices']);
178 $filteredServices[$serviceType] = $serviceList;
179 }
180 }
181 return $filteredServices;
182 }
183
184 /**
185 * Utility method used to sort services according to their priority and
186 * quality.
187 *
188 * @param array $a First service to compare
189 * @param array $b Second service to compare
190 * @return int 1, 0 or -1 if $a is smaller, equal or greater than $b, respectively
191 */
192 protected function sortServices(array $a, array $b)
193 {
194 $result = 0;
195 // If priorities are the same, test quality
196 if ($a['priority'] === $b['priority']) {
197 if ($a['quality'] !== $b['quality']) {
198 // Service with highest quality should come first,
199 // thus it must be marked as smaller
200 $result = $a['quality'] > $b['quality'] ? -1 : 1;
201 }
202 } else {
203 // Service with highest priority should come first,
204 // thus it must be marked as smaller
205 $result = $a['priority'] > $b['priority'] ? -1 : 1;
206 }
207 return $result;
208 }
209
210 /**
211 * Method to check if the service in path is available
212 * @param bool|string $isValid
213 * @return array
214 */
215 private function getServicePathStatus($isValid): array
216 {
217 $statusCSSClass = 'danger';
218 $accessible = 'no';
219
220 if ($isValid) {
221 $statusCSSClass = 'success';
222 $accessible = 'yes';
223 }
224 return [
225 'statusCSSClass' => $statusCSSClass,
226 'accessible' => $accessible
227 ];
228 }
229
230 /**
231 * Returns LanguageService
232 *
233 * @return \TYPO3\CMS\Core\Localization\LanguageService
234 */
235 protected function getLanguageService()
236 {
237 return $GLOBALS['LANG'];
238 }
239 }