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