0aea761f904a82bb19c00acc82c88d619e11f90d
[Packages/TYPO3.CMS.git] / typo3 / sysext / opendocs / Classes / Backend / ToolbarItems / OpendocsToolbarItem.php
1 <?php
2 namespace TYPO3\CMS\Opendocs\Backend\ToolbarItems;
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\Toolbar\ToolbarItemInterface;
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Fluid\View\StandaloneView;
23
24 /**
25 * Alist of all open documents
26 */
27 class OpendocsToolbarItem implements ToolbarItemInterface
28 {
29 /**
30 * @var array
31 */
32 protected $openDocs = [];
33
34 /**
35 * @var array
36 */
37 protected $recentDocs = [];
38
39 /**
40 * Constructor
41 */
42 public function __construct()
43 {
44 $this->loadDocsFromUserSession();
45 }
46
47 /**
48 * Checks whether the user has access to this toolbar item
49 *
50 * @return bool TRUE if user has access, FALSE if not
51 */
52 public function checkAccess()
53 {
54 $conf = $this->getBackendUser()->getTSConfig('backendToolbarItem.tx_opendocs.disabled');
55 return $conf['value'] != 1;
56 }
57
58 /**
59 * Loads the opened and recently opened documents from the user
60 */
61 public function loadDocsFromUserSession()
62 {
63 $backendUser = $this->getBackendUser();
64 $openDocs = $backendUser->getModuleData('FormEngine', 'ses');
65 if ($openDocs !== null) {
66 list($this->openDocs, ) = $openDocs;
67 }
68 $this->recentDocs = $backendUser->getModuleData('opendocs::recent') ?: [];
69 }
70
71 /**
72 * Render toolbar icon
73 *
74 * @return string HTML
75 */
76 public function getItem()
77 {
78 // Rendering of the output via fluid
79 $view = GeneralUtility::makeInstance(StandaloneView::class);
80 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
81 'EXT:opendocs/Resources/Private/Templates/ToolbarItem.html'
82 ));
83 $view->assign('numDocs', count($this->openDocs));
84 return $view->render();
85 }
86
87 /**
88 * Render drop down
89 *
90 * @return string HTML
91 */
92 public function getDropDown()
93 {
94 $assigns = [];
95 $openDocuments = $this->openDocs;
96 $recentDocuments = $this->recentDocs;
97 $assigns['openDocuments'] = $this->getMenuEntries($openDocuments);
98 // If there are "recent documents" in the list, add them
99 $assigns['recentDocuments'] = $this->getMenuEntries($recentDocuments);
100
101 // Rendering of the output via fluid
102 $view = GeneralUtility::makeInstance(StandaloneView::class);
103 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
104 'EXT:opendocs/Resources/Private/Templates/DropDown.html'
105 ));
106 $view->assignMultiple($assigns);
107 return $view->render();
108 }
109
110 /**
111 * Get menu entries for all eligible records
112 *
113 * @param array $documents
114 * @return array
115 */
116 protected function getMenuEntries(array $documents) : array
117 {
118 $entries = [];
119 foreach ($documents as $md5sum => $recentDocument) {
120 $menuEntry = $this->getMenuEntry($recentDocument, $md5sum);
121 if ($menuEntry !== '') {
122 $entries[] = $menuEntry;
123 }
124 }
125 return $entries;
126 }
127
128 /**
129 * Returns the data for a recent or open document
130 *
131 * @param array $document
132 * @param string $md5sum
133 * @return array The data of a recent or closed document
134 */
135 protected function getMenuEntry($document, $md5sum)
136 {
137 $table = $document[3]['table'];
138 $uid = $document[3]['uid'];
139 $record = BackendUtility::getRecordWSOL($table, $uid);
140 if (!is_array($record)) {
141 // Record seems to be deleted
142 return '';
143 }
144 $result = [];
145 $result['table'] = $table;
146 $result['record'] = $record;
147 $label = htmlspecialchars(strip_tags(htmlspecialchars_decode($document[0])));
148 $result['label'] = $label;
149 $link = BackendUtility::getModuleUrl('record_edit') . '&' . $document[2];
150 $pageId = (int)$document[3]['uid'];
151 if ($document[3]['table'] !== 'pages') {
152 $pageId = (int)$document[3]['pid'];
153 }
154 $onClickCode = 'jump(' . GeneralUtility::quoteJSvalue($link) . ', \'web_list\', \'web\', ' . $pageId . '); TYPO3.OpendocsMenu.toggleMenu(); return false;';
155 $result['onClickCode'] = $onClickCode;
156 $result['md5sum'] = $md5sum;
157 return $result;
158 }
159
160 /**
161 * No additional attributes
162 *
163 * @return string List item HTML attibutes
164 */
165 public function getAdditionalAttributes()
166 {
167 return [];
168 }
169
170 /**
171 * This item has a drop down
172 *
173 * @return bool
174 */
175 public function hasDropDown()
176 {
177 return true;
178 }
179
180 /*******************
181 *** HOOKS ***
182 *******************/
183 /**
184 * Called as a hook in \TYPO3\CMS\Backend\Utility\BackendUtility::setUpdateSignal, calls a JS function to change
185 * the number of opened documents
186 *
187 * @param array $params
188 * @param unknown_type $ref
189 * @return string list item HTML attributes
190 */
191 public function updateNumberOfOpenDocsHook(&$params, $ref)
192 {
193 $params['JScode'] = '
194 if (top && top.TYPO3.OpendocsMenu) {
195 top.TYPO3.OpendocsMenu.updateMenu();
196 }
197 ';
198 }
199
200 /******************
201 *** AJAX CALLS ***
202 ******************/
203 /**
204 * Closes a document in the session and
205 *
206 * @param ServerRequestInterface $request
207 * @param ResponseInterface $response
208 * @return ResponseInterface
209 */
210 public function closeDocument(ServerRequestInterface $request, ResponseInterface $response)
211 {
212 $backendUser = $this->getBackendUser();
213 $md5sum = isset($request->getParsedBody()['md5sum']) ? $request->getParsedBody()['md5sum'] : $request->getQueryParams()['md5sum'];
214 if ($md5sum && isset($this->openDocs[$md5sum])) {
215 // Add the document to be closed to the recent documents
216 $this->recentDocs = array_merge([$md5sum => $this->openDocs[$md5sum]], $this->recentDocs);
217 // Allow a maximum of 8 recent documents
218 if (count($this->recentDocs) > 8) {
219 $this->recentDocs = array_slice($this->recentDocs, 0, 8);
220 }
221 // Remove it from the list of the open documents, and store the status
222 unset($this->openDocs[$md5sum]);
223 list(, $docDat) = $backendUser->getModuleData('FormEngine', 'ses');
224 $backendUser->pushModuleData('FormEngine', [$this->openDocs, $docDat]);
225 $backendUser->pushModuleData('opendocs::recent', $this->recentDocs);
226 }
227 return $this->renderMenu($request, $response);
228 }
229
230 /**
231 * Renders the menu so that it can be returned as response to an AJAX call
232 *
233 * @param ServerRequestInterface $request
234 * @param ResponseInterface $response
235 * @return ResponseInterface
236 */
237 public function renderMenu(ServerRequestInterface $request, ResponseInterface $response)
238 {
239 $response->getBody()->write($this->getDropDown());
240 return $response->withHeader('Content-Type', 'text/html; charset=utf-8');
241 }
242
243 /**
244 * Position relative to others
245 *
246 * @return int
247 */
248 public function getIndex()
249 {
250 return 30;
251 }
252
253 /**
254 * Returns the current BE user.
255 *
256 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
257 */
258 protected function getBackendUser()
259 {
260 return $GLOBALS['BE_USER'];
261 }
262 }