[TASK] Extract request processing from OpendocsToolbarItem
[Packages/TYPO3.CMS.git] / typo3 / sysext / opendocs / Classes / Backend / ToolbarItems / OpendocsToolbarItem.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Opendocs\Backend\ToolbarItems;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Backend\Routing\UriBuilder;
19 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
21 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Fluid\View\StandaloneView;
24 use TYPO3\CMS\Opendocs\Service\OpenDocumentService;
25
26 /**
27 * Main functionality to render a list of all open documents in the top bar of the TYPO3 Backend
28 */
29 class OpendocsToolbarItem implements ToolbarItemInterface
30 {
31 /**
32 * @var array
33 */
34 protected $recentDocs = [];
35
36 /**
37 * @var OpenDocumentService
38 */
39 protected $documentService;
40
41 /**
42 * Set up dependencies
43 *
44 * @param OpenDocumentService|null $documentService
45 */
46 public function __construct(OpenDocumentService $documentService = null)
47 {
48 $this->documentService = $documentService ?: GeneralUtility::makeInstance(OpenDocumentService::class);
49 }
50
51 /**
52 * Checks whether the user has access to this toolbar item
53 *
54 * @return bool TRUE if user has access, FALSE if not
55 */
56 public function checkAccess()
57 {
58 $disabled = $this->getBackendUser()->getTSConfig('backendToolbarItem.tx_opendocs.disabled');
59
60 return (int)$disabled['value'] !== 1;
61 }
62
63 /**
64 * Render toolbar icon via Fluid
65 *
66 * @return string HTML
67 */
68 public function getItem()
69 {
70 $view = $this->getFluidTemplateObject('ToolbarItem.html');
71 $view->assign('numDocs', count($this->documentService->getOpenDocuments()));
72
73 return $view->render();
74 }
75
76 /**
77 * This item has a drop down
78 *
79 * @return bool
80 */
81 public function hasDropDown()
82 {
83 return true;
84 }
85
86 /**
87 * Render drop down via Fluid
88 *
89 * @return string HTML
90 */
91 public function getDropDown()
92 {
93 $view = $this->getFluidTemplateObject('DropDown.html');
94 $view->assignMultiple([
95 'openDocuments' => $this->getMenuEntries($this->documentService->getOpenDocuments()),
96 // If there are "recent documents" in the list, add them
97 'recentDocuments' => $this->getMenuEntries($this->documentService->getRecentDocuments()),
98 ]);
99
100 return $view->render();
101 }
102
103 /**
104 * No additional attributes
105 *
106 * @return array List of attributes
107 */
108 public function getAdditionalAttributes()
109 {
110 return [];
111 }
112
113 /**
114 * Position relative to others
115 *
116 * @return int
117 */
118 public function getIndex()
119 {
120 return 30;
121 }
122
123 /**
124 * Called as a hook in \TYPO3\CMS\Backend\Utility\BackendUtility::getUpdateSignalCode, calls a JS function to change
125 * the number of opened documents
126 *
127 * @param array $params
128 */
129 public function updateNumberOfOpenDocsHook(&$params)
130 {
131 $params['JScode'] = '
132 if (top && top.TYPO3.OpendocsMenu) {
133 top.TYPO3.OpendocsMenu.updateMenu();
134 }
135 ';
136 }
137
138 /**
139 * Get menu entries for all eligible records
140 *
141 * @param array $documents
142 * @return array
143 */
144 protected function getMenuEntries(array $documents): array
145 {
146 $entries = [];
147
148 foreach ($documents as $identifier => $document) {
149 $menuEntry = $this->getMenuEntry($document, $identifier);
150
151 if (!empty($menuEntry)) {
152 $entries[] = $menuEntry;
153 }
154 }
155
156 return $entries;
157 }
158
159 /**
160 * Returns the data for a recent or open document
161 *
162 * @param array $document
163 * @param string $identifier
164 * @return array The data of a recent or closed document, or empty array if no record was found (e.g. deleted)
165 */
166 protected function getMenuEntry(array $document, string $identifier): array
167 {
168 $table = $document[3]['table'];
169 $uid = $document[3]['uid'];
170 $record = BackendUtility::getRecordWSOL($table, $uid);
171
172 if (!is_array($record)) {
173 // Record seems to be deleted
174 return [];
175 }
176
177 $result = [];
178 $result['table'] = $table;
179 $result['record'] = $record;
180 $result['label'] = htmlspecialchars(strip_tags(htmlspecialchars_decode($document[0])));
181 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
182 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
183 $uri = (string)$uriBuilder->buildUriFromRoute('record_edit') . '&' . $document[2];
184 $pid = (int)$document[3]['pid'];
185
186 if ($document[3]['table'] === 'pages') {
187 $pid = (int)$document[3]['uid'];
188 }
189
190 $result['onClickCode'] = 'jump(' . GeneralUtility::quoteJSvalue($uri) . ', \'web_list\', \'web\', ' . $pid . '); TYPO3.OpendocsMenu.toggleMenu(); return false;';
191 $result['md5sum'] = $identifier;
192
193 return $result;
194 }
195
196 /**
197 * Returns a new standalone view, shorthand function
198 *
199 * @param string $filename Which templateFile should be used.
200 * @return StandaloneView
201 */
202 protected function getFluidTemplateObject(string $filename): StandaloneView
203 {
204 $view = GeneralUtility::makeInstance(StandaloneView::class);
205 $view->setLayoutRootPaths(['EXT:opendocs/Resources/Private/Layouts']);
206 $view->setPartialRootPaths([
207 'EXT:backend/Resources/Private/Partials/ToolbarItems',
208 'EXT:opendocs/Resources/Private/Partials/ToolbarItems',
209 ]);
210 $view->setTemplateRootPaths(['EXT:opendocs/Resources/Private/Templates/ToolbarItems']);
211 $view->setTemplate($filename);
212 $view->getRequest()->setControllerExtensionName('Opendocs');
213
214 return $view;
215 }
216
217 /**
218 * @return BackendUserAuthentication
219 */
220 protected function getBackendUser(): BackendUserAuthentication
221 {
222 return $GLOBALS['BE_USER'];
223 }
224 }