[TASK] Create own response instance in controller actions
[Packages/TYPO3.CMS.git] / typo3 / sysext / documentation / Classes / Controller / DocumentController.php
1 <?php
2 namespace TYPO3\CMS\Documentation\Controller;
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 Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\View\BackendTemplateView;
20 use TYPO3\CMS\Core\Http\JsonResponse;
21 use TYPO3\CMS\Core\Localization\LanguageService;
22 use TYPO3\CMS\Core\Messaging\FlashMessage;
23 use TYPO3\CMS\Core\Page\PageRenderer;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Documentation\Domain\Repository\DocumentRepository;
26 use TYPO3\CMS\Documentation\Service\DocumentationService;
27 use TYPO3\CMS\Documentation\Utility\LanguageUtility;
28 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
29 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
30 use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
31 use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
32 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
33
34 /**
35 * Main controller of the Documentation module.
36 */
37 class DocumentController extends ActionController
38 {
39 /**
40 * @var DocumentRepository
41 */
42 protected $documentRepository;
43
44 /**
45 * @var DocumentationService
46 */
47 protected $documentationService;
48
49 /**
50 * @var LanguageUtility
51 */
52 protected $languageUtility;
53
54 /**
55 * @var Dispatcher
56 */
57 protected $signalSlotDispatcher;
58
59 /**
60 * Backend Template Container
61 *
62 * @var BackendTemplateView
63 */
64 protected $defaultViewObjectName = BackendTemplateView::class;
65
66 /**
67 * BackendTemplateContainer
68 *
69 * @var BackendTemplateView
70 */
71 protected $view;
72
73 /**
74 * Set up the doc header properly here
75 *
76 * @param ViewInterface $view
77 */
78 protected function initializeView(ViewInterface $view)
79 {
80 if ($view instanceof BackendTemplateView) {
81 /** @var BackendTemplateView $view */
82 parent::initializeView($view);
83 $view->getModuleTemplate()->getDocHeaderComponent()->setMetaInformation([]);
84 $uriBuilder = $this->objectManager->get(UriBuilder::class);
85 $uriBuilder->setRequest($this->request);
86
87 $this->view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Documentation/Main');
88 $menu = $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
89 $menu->setIdentifier('DocumentationModuleMenu');
90
91 $isListActive = $this->request->getControllerActionName() === 'list' ? true : false;
92 $uri = $uriBuilder->reset()->uriFor('list', [], 'Document');
93 $listMenuItem = $menu->makeMenuItem()
94 ->setTitle($this->getLanguageService()
95 ->sL('LLL:EXT:documentation/Resources/Private/Language/locallang.xlf:showDocumentation'))
96 ->setHref($uri)
97 ->setActive($isListActive);
98 $menu->addMenuItem($listMenuItem);
99
100 if ($this->getBackendUser()->isAdmin()) {
101 $isDownloadActive = $this->request->getControllerActionName() ===
102 'download' ? true : false;
103 $uri =
104 $uriBuilder->reset()->uriFor('download', [], 'Document');
105 $downloadMenuItem = $menu->makeMenuItem()
106 ->setTitle($this->getLanguageService()
107 ->sL('LLL:EXT:documentation/Resources/Private/Language/locallang.xlf:downloadDocumentation'))
108 ->setHref($uri)
109 ->setActive($isDownloadActive);
110 $menu->addMenuItem($downloadMenuItem);
111 }
112
113 $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
114 $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
115 }
116 }
117
118 /**
119 * @param DocumentRepository $documentRepository
120 */
121 public function injectDocumentRepository(DocumentRepository $documentRepository)
122 {
123 $this->documentRepository = $documentRepository;
124 }
125
126 /**
127 * @param DocumentationService $documentationService
128 */
129 public function injectDocumentationService(DocumentationService $documentationService)
130 {
131 $this->documentationService = $documentationService;
132 }
133
134 /**
135 * @param LanguageUtility $languageUtility
136 */
137 public function injectLanguageUtility(LanguageUtility $languageUtility)
138 {
139 $this->languageUtility = $languageUtility;
140 }
141
142 /**
143 * @param Dispatcher $signalSlotDispatcher
144 */
145 public function injectSignalSlotDispatcher(Dispatcher $signalSlotDispatcher)
146 {
147 $this->signalSlotDispatcher = $signalSlotDispatcher;
148 }
149
150 /**
151 * Lists the available documents.
152 */
153 public function listAction()
154 {
155 $this->view->getModuleTemplate()->getDocHeaderComponent()->setMetaInformation([]);
156
157 $documents = $this->getDocuments();
158
159 // Filter documents to be shown for current user
160 $hideDocuments = $this->getBackendUser()->getTSConfigVal('mod.help_DocumentationDocumentation.documents.hide');
161 $hideDocuments = GeneralUtility::trimExplode(',', $hideDocuments, true);
162 if (!empty($hideDocuments)) {
163 $documents = array_diff_key($documents, array_flip($hideDocuments));
164 }
165 $showDocuments = $this->getBackendUser()->getTSConfigVal('mod.help_DocumentationDocumentation.documents.show');
166 $showDocuments = GeneralUtility::trimExplode(',', $showDocuments, true);
167 if (!empty($showDocuments)) {
168 $documents = array_intersect_key($documents, array_flip($showDocuments));
169 }
170
171 $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
172 $pageRenderer->addInlineLanguageLabelFile('EXT:documentation/Resources/Private/Language/locallang.xlf');
173 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Documentation/Main');
174
175 $this->view->assign('documents', $documents);
176 }
177
178 /**
179 * Delete documentation with given packageKey
180 *
181 * @param ServerRequestInterface $request
182 * @return ResponseInterface
183 */
184 public function deleteAction(ServerRequestInterface $request): ResponseInterface
185 {
186 $basePath = 'typo3conf/Documentation/';
187 $packageKey = $request->getParsedBody();
188 $isDirDeleted = GeneralUtility::rmdir(PATH_site . $basePath . $packageKey['documentationKey'], true);
189 if (!$isDirDeleted) {
190 $this->addFlashMessage(LocalizationUtility::translate('deleteFailed', 'Documentation'), '', FlashMessage::ERROR);
191 }
192 return new JsonResponse([$isDirDeleted]);
193 }
194
195 /**
196 * Returns available documents.
197 *
198 * @return \TYPO3\CMS\Documentation\Domain\Model\Document[]
199 * @api
200 */
201 public function getDocuments()
202 {
203 $language = $this->languageUtility->getDocumentationLanguage();
204 $documents = $this->documentRepository->findByLanguage($language);
205
206 $documents = $this->emitAfterInitializeDocumentsSignal($language, $documents);
207
208 return $documents;
209 }
210
211 /**
212 * Emits a signal after the documents are initialized
213 *
214 * @param string $language
215 * @param \TYPO3\CMS\Documentation\Domain\Model\Document[] $documents
216 * @return \TYPO3\CMS\Documentation\Domain\Model\Document[]
217 */
218 protected function emitAfterInitializeDocumentsSignal($language, array $documents)
219 {
220 $this->signalSlotDispatcher->dispatch(
221 __CLASS__,
222 'afterInitializeDocuments',
223 [
224 $language,
225 &$documents,
226 ]
227 );
228 return $documents;
229 }
230
231 /**
232 * Shows documents to be downloaded/fetched from a remote location.
233 */
234 public function downloadAction()
235 {
236 // This action is reserved for admin users. Redirect to default view if not.
237 if (!$this->getBackendUser()->isAdmin()) {
238 $this->redirect('list');
239 }
240
241 // Retrieve the list of official documents
242 $documents = $this->documentationService->getOfficialDocuments();
243
244 // Merge with the list of local extensions
245 $extensions = $this->documentationService->getLocalExtensions();
246 $allDocuments = array_merge($documents, $extensions);
247
248 $this->view->assign('documents', $allDocuments);
249 }
250
251 /**
252 * Fetches a document from a remote URL.
253 *
254 * @param string $url
255 * @param string $key
256 * @param string $version
257 */
258 public function fetchAction($url, $key, $version = null)
259 {
260 // This action is reserved for admin users. Redirect to default view if not.
261 if (!$this->getBackendUser()->isAdmin()) {
262 $this->redirect('list');
263 }
264
265 $language = $this->languageUtility->getDocumentationLanguage();
266 try {
267 $result = $this->documentationService->fetchNearestDocument($url, $key, $version ?: 'latest', $language);
268 if ($result) {
269 $this->addFlashMessage(
270 LocalizationUtility::translate(
271 'downloadSucceeded',
272 'documentation'
273 ),
274 '',
275 FlashMessage::OK
276 );
277 } else {
278 $this->addFlashMessage(
279 LocalizationUtility::translate(
280 'downloadFailedNoArchive',
281 'documentation'
282 ),
283 LocalizationUtility::translate(
284 'downloadFailed',
285 'documentation'
286 ),
287 FlashMessage::ERROR
288 );
289 }
290 } catch (\Exception $e) {
291 $this->addFlashMessage(
292 LocalizationUtility::translate(
293 'downloadFailedDetails',
294 'documentation',
295 [
296 $key,
297 $e->getMessage(),
298 $e->getCode()
299 ]
300 ),
301 LocalizationUtility::translate(
302 'downloadFailed',
303 'documentation'
304 ),
305 FlashMessage::ERROR
306 );
307 }
308 $this->redirect('download');
309 }
310
311 /**
312 * Get backend user
313 *
314 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
315 */
316 protected function getBackendUser()
317 {
318 return $GLOBALS['BE_USER'];
319 }
320
321 /**
322 * Returns the LanguageService
323 *
324 * @return LanguageService
325 */
326 protected function getLanguageService()
327 {
328 return $GLOBALS['LANG'];
329 }
330 }