[FEATURE] Migrate open-docs counter to .badge
[Packages/TYPO3.CMS.git] / typo3 / sysext / opendocs / Classes / Controller / OpendocsController.php
1 <?php
2 namespace TYPO3\CMS\Opendocs\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 /**
18 * Adding a list of all open documents of a user to the backend.php
19 *
20 * @author Benjamin Mack <benni@typo3.org>
21 * @author Ingo Renner <ingo@typo3.org>
22 */
23 class OpendocsController implements \TYPO3\CMS\Backend\Toolbar\ToolbarItemHookInterface {
24
25 /**
26 * reference back to the backend object
27 *
28 * @var TYPO3backend
29 */
30 protected $backendReference;
31
32 protected $openDocs;
33
34 protected $recentDocs;
35
36 protected $EXTKEY = 'opendocs';
37
38 /**
39 * Constructor, loads the documents from the user control
40 *
41 * @param \TYPO3\CMS\Backend\Controller\BackendController TYPO3 backend object reference
42 */
43 public function __construct(\TYPO3\CMS\Backend\Controller\BackendController &$backendReference = NULL) {
44 $GLOBALS['LANG']->includeLLFile('EXT:opendocs/locallang_opendocs.xlf');
45 $this->backendReference = $backendReference;
46 $this->loadDocsFromUserSession();
47 }
48
49 /**
50 * Checks whether the user has access to this toolbar item
51 *
52 * @return boolean TRUE if user has access, FALSE if not
53 */
54 public function checkAccess() {
55 $conf = $GLOBALS['BE_USER']->getTSConfig('backendToolbarItem.tx_opendocs.disabled');
56 return $conf['value'] != 1;
57 }
58
59 /**
60 * Loads the opened and recently opened documents from the user
61 *
62 * @return void
63 */
64 public function loadDocsFromUserSession() {
65 list($this->openDocs, ) = $GLOBALS['BE_USER']->getModuleData('alt_doc.php', 'ses');
66 $this->recentDocs = $GLOBALS['BE_USER']->getModuleData('opendocs::recent');
67 }
68
69 /**
70 * Renders the toolbar item and the initial menu
71 *
72 * @return string The toolbar item including the initial menu content as HTML
73 */
74 public function render() {
75 $this->addJavascriptToBackend();
76 $this->addCssToBackend();
77 $numDocs = count($this->openDocs);
78 $opendocsMenu = array();
79 $title = $GLOBALS['LANG']->getLL('toolbaritem', TRUE);
80
81 // Toolbar item icon
82 $opendocsMenu[] = '<a href="#" class="toolbar-item">';
83 $opendocsMenu[] = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('apps-toolbar-menu-opendocs', array('title' => $title));
84 $opendocsMenu[] = '<span class="badge" id="tx-opendocs-counter">' . $numDocs . '</span>';
85 $opendocsMenu[] = '</a>';
86
87 // Toolbar item menu and initial content
88 $opendocsMenu[] = '<div class="toolbar-item-menu" style="display: none;">';
89 $opendocsMenu[] = $this->renderMenu();
90 $opendocsMenu[] = '</div>';
91 return implode(LF, $opendocsMenu);
92 }
93
94 /**
95 * renders the pure contents of the menu
96 *
97 * @return string The menu's content
98 */
99 public function renderMenu() {
100 $openDocuments = $this->openDocs;
101 $recentDocuments = $this->recentDocs;
102 $entries = array();
103 $content = '';
104 if (count($openDocuments)) {
105 $entries[] = '<tr><th colspan="3">' . $GLOBALS['LANG']->getLL('open_docs', TRUE) . '</th></tr>';
106 $i = 0;
107 foreach ($openDocuments as $md5sum => $openDocument) {
108 $i++;
109 $entries[] = $this->renderMenuEntry($openDocument, $md5sum, FALSE, $i == 1);
110 }
111 }
112 // If there are "recent documents" in the list, add them
113 if (count($recentDocuments)) {
114 $entries[] = '<tr><th colspan="3">' . $GLOBALS['LANG']->getLL('recent_docs', TRUE) . '</th></tr>';
115 $i = 0;
116 foreach ($recentDocuments as $md5sum => $recentDocument) {
117 $i++;
118 $entries[] = $this->renderMenuEntry($recentDocument, $md5sum, TRUE, $i == 1);
119 }
120 }
121 if (count($entries)) {
122 $content = '<table class="list" cellspacing="0" cellpadding="0" border="0">' . implode('', $entries) . '</table>';
123 } else {
124 $content = '<div class="no-docs">' . $GLOBALS['LANG']->getLL('no_docs', TRUE) . '</div>';
125 }
126 return $content;
127 }
128
129 /**
130 * Returns the recent documents list as an array
131 *
132 * @return array All recent documents as list-items
133 */
134 public function renderMenuEntry($document, $md5sum, $isRecentDoc = FALSE, $isFirstDoc = FALSE) {
135 $table = $document[3]['table'];
136 $uid = $document[3]['uid'];
137 $record = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordWSOL($table, $uid);
138 if (!is_array($record)) {
139 // Record seems to be deleted
140 return '';
141 }
142 $label = htmlspecialchars(strip_tags(htmlspecialchars_decode($document[0])));
143 $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord($table, $record);
144 $link = $GLOBALS['BACK_PATH'] . 'alt_doc.php?' . $document[2];
145 $pageId = (int)$document[3]['uid'];
146 if ($document[3]['table'] !== 'pages') {
147 $pageId = (int)$document[3]['pid'];
148 }
149 $firstRow = '';
150 if ($isFirstDoc) {
151 $firstRow = ' first-row';
152 }
153 if (!$isRecentDoc) {
154 $title = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE);
155 // Open document
156 $closeIcon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-close');
157 $entry = '
158 <tr class="opendoc' . $firstRow . '">
159 <td class="icon">' . $icon . '</td>
160 <td class="label"><a href="#" onclick="jump(unescape(\'' . htmlspecialchars($link) . '\'), \'web_list\', \'web\', ' . $pageId . '); TYPO3BackendOpenDocs.toggleMenu(); return false;" target="content">' . $label . '</a></td>
161 <td class="close" onclick="return TYPO3BackendOpenDocs.closeDocument(\'' . $md5sum . '\');">' . $closeIcon . '</td>
162 </tr>';
163 } else {
164 // Recently used document
165 $entry = '
166 <tr class="recentdoc' . $firstRow . '">
167 <td class="icon">' . $icon . '</td>
168 <td class="label" colspan="2"><a href="#" onclick="jump(unescape(\'' . htmlspecialchars($link) . '\'), \'web_list\', \'web\', ' . $pageId . '); TYPO3BackendOpenDocs.toggleMenu(); return false;" target="content">' . $label . '</a></td>
169 </tr>';
170 }
171 return $entry;
172 }
173
174 /**
175 * Returns additional attributes for the list item in the toolbar
176 *
177 * @return string List item HTML attibutes
178 */
179 public function getAdditionalAttributes() {
180 return 'id="tx-opendocs-menu"';
181 }
182
183 /**
184 * Adds the neccessary javascript to the backend
185 *
186 * @return void
187 */
188 protected function addJavascriptToBackend() {
189 $this->backendReference->addJavascriptFile(
190 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($this->EXTKEY) . 'Resources/Public/JavaScript/opendocs.js'
191 );
192 }
193
194 /**
195 * Adds the necessary CSS to the backend
196 *
197 * @return void
198 */
199 protected function addCssToBackend() {
200 $this->backendReference->addCssFile(
201 'opendocs',
202 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($this->EXTKEY) . '/Resources/Public/Css/opendocs.css'
203 );
204 }
205
206 /*******************
207 *** HOOKS ***
208 *******************/
209 /**
210 * Called as a hook in \TYPO3\CMS\Backend\Utility\BackendUtility::setUpdateSignal, calls a JS function to change
211 * the number of opened documents
212 *
213 * @param array $params
214 * @param unknown_type $ref
215 * @return string list item HTML attibutes
216 */
217 public function updateNumberOfOpenDocsHook(&$params, $ref) {
218 $params['JScode'] = '
219 if (top && top.TYPO3BackendOpenDocs) {
220 top.TYPO3BackendOpenDocs.updateNumberOfDocs(' . count($this->openDocs) . ', true);
221 }
222 ';
223 }
224
225 /******************
226 *** AJAX CALLS ***
227 ******************/
228 /**
229 * Closes a document in the session and
230 *
231 * @param array $params Array of parameters from the AJAX interface, currently unused
232 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
233 * @return string List item HTML attibutes
234 */
235 public function closeDocument($params = array(), \TYPO3\CMS\Core\Http\AjaxRequestHandler &$ajaxObj = NULL) {
236 $md5sum = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('md5sum');
237 if ($md5sum && isset($this->openDocs[$md5sum])) {
238 // Add the document to be closed to the recent documents
239 $this->recentDocs = array_merge(array($md5sum => $this->openDocs[$md5sum]), $this->recentDocs);
240 // Allow a maximum of 8 recent documents
241 if (count($this->recentDocs) > 8) {
242 $this->recentDocs = array_slice($this->recentDocs, 0, 8);
243 }
244 // Remove it from the list of the open documents, and store the status
245 unset($this->openDocs[$md5sum]);
246 list(, $docDat) = $GLOBALS['BE_USER']->getModuleData('alt_doc.php', 'ses');
247 $GLOBALS['BE_USER']->pushModuleData('alt_doc.php', array($this->openDocs, $docDat));
248 $GLOBALS['BE_USER']->pushModuleData('opendocs::recent', $this->recentDocs);
249 }
250 $this->renderAjax($params, $ajaxObj);
251 }
252
253 /**
254 * Renders the menu so that it can be returned as response to an AJAX call
255 *
256 * @param array $params Array of parameters from the AJAX interface, currently unused
257 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
258 * @return void
259 */
260 public function renderAjax($params = array(), \TYPO3\CMS\Core\Http\AjaxRequestHandler &$ajaxObj = NULL) {
261 $menuContent = $this->renderMenu();
262 $ajaxObj->addContent('opendocsMenu', $menuContent);
263 }
264
265 }