[TASK] Introduce getters for $GLOBALS in ext:taskcenter
[Packages/TYPO3.CMS.git] / typo3 / sysext / taskcenter / Classes / Controller / TaskModuleController.php
1 <?php
2 namespace TYPO3\CMS\Taskcenter\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 TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Backend\Utility\IconUtility;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * This class provides a taskcenter for BE users
23 *
24 * @author Georg Ringer <typo3@ringerge.org>
25 */
26 class TaskModuleController extends \TYPO3\CMS\Backend\Module\BaseScriptClass {
27
28 /**
29 * @var array
30 */
31 protected $pageinfo;
32
33 /**
34 * The name of the module
35 *
36 * @var string
37 */
38 protected $moduleName = 'user_task';
39
40 /**
41 * Initializes the Module
42 *
43 * @return void
44 */
45 public function __construct() {
46 $this->getLanguageService()->includeLLFile('EXT:taskcenter/task/locallang.xlf');
47 $this->MCONF = array(
48 'name' => $this->moduleName
49 );
50 parent::init();
51 // Initialize document
52 $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
53 $this->doc->setModuleTemplate(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('taskcenter') . 'Resources/Private/Templates/mod_template.html');
54 $this->doc->backPath = $GLOBALS['BACK_PATH'];
55 $this->doc->getPageRenderer()->loadJquery();
56 $this->doc->addStyleSheet('tx_taskcenter', '../' . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath('taskcenter') . 'Resources/Public/Styles/styles.css');
57 }
58
59 /**
60 * Adds items to the ->MOD_MENU array. Used for the function menu selector.
61 *
62 * @return void
63 */
64 public function menuConfig() {
65 $this->MOD_MENU = array('mode' => array());
66 $this->MOD_MENU['mode']['information'] = $this->getLanguageService()->sL('LLL:EXT:taskcenter/locallang.xlf:task_overview');
67 $this->MOD_MENU['mode']['tasks'] = 'Tasks';
68 parent::menuConfig();
69 }
70
71 /**
72 * Creates the module's content. In this case it rather acts as a kind of #
73 * dispatcher redirecting requests to specific tasks.
74 *
75 * @return void
76 */
77 public function main() {
78 $docHeaderButtons = $this->getButtons();
79 $markers = array();
80 $this->doc->postCode = $this->doc->wrapScriptTags('if (top.fsMod) { top.fsMod.recentIds["web"] = 0; }');
81
82 // Render content depending on the mode
83 $mode = (string)$this->MOD_SETTINGS['mode'];
84 if ($mode == 'information') {
85 $this->renderInformationContent();
86 } else {
87 $this->renderModuleContent();
88 }
89 // Compile document
90 $markers['FUNC_MENU'] = \TYPO3\CMS\Backend\Utility\BackendUtility::getFuncMenu(0, 'SET[mode]', $this->MOD_SETTINGS['mode'], $this->MOD_MENU['mode']);
91 $markers['CONTENT'] = $this->content;
92 // Build the <body> for the module
93 $this->content = $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
94 // Renders the module page
95 $this->content = $this->doc->render($this->getLanguageService()->getLL('title'), $this->content);
96 }
97
98 /**
99 * Prints out the module's HTML
100 *
101 * @return void
102 */
103 public function printContent() {
104 echo $this->content;
105 }
106
107 /**
108 * Generates the module content by calling the selected task
109 *
110 * @return void
111 */
112 protected function renderModuleContent() {
113 $title = ($content = ($actionContent = ''));
114 $chosenTask = (string)$this->MOD_SETTINGS['function'];
115 // Render the taskcenter task as default
116 if (empty($chosenTask) || $chosenTask == 'index') {
117 $chosenTask = 'taskcenter.tasks';
118 }
119 // Render the task
120 list($extKey, $taskClass) = explode('.', $chosenTask, 2);
121 $title = $this->getLanguageService()->sL($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter'][$extKey][$taskClass]['title']);
122 if (class_exists($taskClass)) {
123 $taskInstance = GeneralUtility::makeInstance($taskClass, $this);
124 if ($taskInstance instanceof \TYPO3\CMS\Taskcenter\TaskInterface) {
125 // Check if the task is restricted to admins only
126 if ($this->checkAccess($extKey, $taskClass)) {
127 $actionContent .= $taskInstance->getTask();
128 } else {
129 $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, $this->getLanguageService()->getLL('error-access', TRUE), $this->getLanguageService()->getLL('error_header'), \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
130 $actionContent .= $flashMessage->render();
131 }
132 } else {
133 // Error if the task is not an instance of \TYPO3\CMS\Taskcenter\TaskInterface
134 $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, sprintf($this->getLanguageService()->getLL('error_no-instance', TRUE), $taskClass, \TYPO3\CMS\Taskcenter\TaskInterface::class), $this->getLanguageService()->getLL('error_header'), \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
135 $actionContent .= $flashMessage->render();
136 }
137 } else {
138 $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, $this->getLanguageService()->sL('LLL:EXT:taskcenter/task/locallang_mod.xlf:mlang_labels_tabdescr'), $this->getLanguageService()->sL('LLL:EXT:taskcenter/task/locallang_mod.xlf:mlang_tabs_tab'), \TYPO3\CMS\Core\Messaging\FlashMessage::INFO);
139 $actionContent .= $flashMessage->render();
140 }
141 $content = '<div id="taskcenter-main">
142 <div id="taskcenter-menu">' . $this->indexAction() . '</div>
143 <div id="taskcenter-item" class="' . htmlspecialchars(($extKey . '-' . $taskClass)) . '">' . $actionContent . '
144 </div>
145 </div>';
146 $this->content .= $content;
147 }
148
149 /**
150 * Generates the information content
151 *
152 * @return void
153 */
154 protected function renderInformationContent() {
155 $content = $this->description($this->getLanguageService()->getLL('mlang_tabs_tab'), $this->getLanguageService()->sL('LLL:EXT:taskcenter/task/locallang_mod.xlf:mlang_labels_tabdescr'));
156 $content .= $this->getLanguageService()->getLL('taskcenter-about');
157 if ($this->getBackendUser()->isAdmin()) {
158 $content .= '<br /><br />' . $this->description($this->getLanguageService()->getLL('taskcenter-adminheader'), $this->getLanguageService()->getLL('taskcenter-admin'));
159 }
160 $this->content .= $content;
161 }
162
163 /**
164 * Render the headline of a task including a title and an optional description.
165 *
166 * @param string $title Title
167 * @param string $description Description
168 * @return string formatted title and description
169 */
170 public function description($title, $description = '') {
171 $content = '<h1>' . nl2br(htmlspecialchars($title)) . '</h1>';
172 if (!empty($description)) {
173 $content .= '<p class="description">' . nl2br(htmlspecialchars($description)) . '</p>';
174 }
175 return $content;
176 }
177
178 /**
179 * Render a list of items as a nicely formated definition list including a
180 * link, icon, title and description.
181 * The keys of a single item are:
182 * - title: Title of the item
183 * - link: Link to the task
184 * - icon: Path to the icon or Icon as HTML if it begins with <img
185 * - description: Description of the task, using htmlspecialchars()
186 * - descriptionHtml: Description allowing HTML tags which will override the
187 * description
188 *
189 * @param array $items List of items to be displayed in the definition list.
190 * @param bool $mainMenu Set it to TRUE to render the main menu
191 * @return string Fefinition list
192 */
193 public function renderListMenu($items, $mainMenu = FALSE) {
194 $content = ($section = '');
195 $count = 0;
196 // Change the sorting of items to the user's one
197 if ($mainMenu) {
198 $this->doc->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Taskcenter/Taskcenter');
199 $userSorting = unserialize($this->getBackendUser()->uc['taskcenter']['sorting']);
200 if (is_array($userSorting)) {
201 $newSorting = array();
202 foreach ($userSorting as $item) {
203 if (isset($items[$item])) {
204 $newSorting[] = $items[$item];
205 unset($items[$item]);
206 }
207 }
208 $items = $newSorting + $items;
209 }
210 }
211 if (is_array($items) && count($items) > 0) {
212 foreach ($items as $item) {
213 $title = htmlspecialchars($item['title']);
214 $icon = ($additionalClass = ($collapsedStyle = ''));
215 // Check for custom icon
216 if (!empty($item['icon'])) {
217 if (strpos($item['icon'], '<img ') === FALSE) {
218 $absIconPath = GeneralUtility::getFileAbsFilename($item['icon']);
219 // If the file indeed exists, assemble relative path to it
220 if (file_exists($absIconPath)) {
221 $icon = $GLOBALS['BACK_PATH'] . '../' . str_replace(PATH_site, '', $absIconPath);
222 $icon = '<img src="' . $icon . '" title="' . $title . '" alt="' . $title . '" />';
223 }
224 if (@is_file($icon)) {
225 $icon = '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], $icon, 'width="16" height="16"') . ' title="' . $title . '" alt="' . $title . '" />';
226 }
227 } else {
228 $icon = $item['icon'];
229 }
230 }
231 $description = $item['descriptionHtml'] ?: '<p>' . nl2br(htmlspecialchars($item['description'])) . '</p>';
232 $id = $this->getUniqueKey($item['uid']);
233 // Collapsed & expanded menu items
234 if ($mainMenu && isset($this->getBackendUser()->uc['taskcenter']['states'][$id]) && $this->getBackendUser()->uc['taskcenter']['states'][$id]) {
235 $collapsedStyle = 'style="display:none"';
236 $additionalClass = 'collapsed';
237 } else {
238 $additionalClass = 'expanded';
239 }
240 // First & last menu item
241 if ($count == 0) {
242 $additionalClass .= ' first-item';
243 } elseif ($count + 1 === count($items)) {
244 $additionalClass .= ' last-item';
245 }
246 // Active menu item
247 $active = (string)$this->MOD_SETTINGS['function'] == $item['uid'] ? ' active-task' : '';
248 // Main menu: Render additional syntax to sort tasks
249 if ($mainMenu) {
250 $dragIcon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-move', array('title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.move', TRUE)));
251 $section = '<div class="down">&nbsp;</div>
252 <div class="drag">' . $dragIcon . '</div>';
253 $backgroundClass = 't3-row-header ';
254 }
255 $content .= '<li class="' . $additionalClass . $active . '" id="el_' . $id . '">
256 ' . $section . '
257 <div class="image">' . $icon . '</div>
258 <div class="' . $backgroundClass . 'link"><a href="' . $item['link'] . '">' . $title . '</a></div>
259 <div class="content " ' . $collapsedStyle . '>' . $description . '</div>
260 </li>';
261 $count++;
262 }
263 $navigationId = $mainMenu ? 'id="task-list"' : '';
264 $content = '<ul ' . $navigationId . ' class="task-list">' . $content . '</ul>';
265 }
266 return $content;
267 }
268
269 /**
270 * Shows an overview list of available reports.
271 *
272 * @return string List of available reports
273 */
274 protected function indexAction() {
275 $content = '';
276 $tasks = array();
277 $icon = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('taskcenter') . 'Resources/Public/Icons/module-taskcenter.gif';
278 // Render the tasks only if there are any available
279 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter']) && count($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter']) > 0) {
280 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter'] as $extKey => $extensionReports) {
281 foreach ($extensionReports as $taskClass => $task) {
282 if (!$this->checkAccess($extKey, $taskClass)) {
283 continue;
284 }
285 $link = BackendUtility::getModuleUrl('user_task') . '&SET[function]=' . $extKey . '.' . $taskClass;
286 $taskTitle = $this->getLanguageService()->sL($task['title']);
287 $taskDescriptionHtml = '';
288 // Check for custom icon
289 if (!empty($task['icon'])) {
290 $icon = GeneralUtility::getFileAbsFilename($task['icon']);
291 }
292 if (class_exists($taskClass)) {
293 $taskInstance = GeneralUtility::makeInstance($taskClass, $this);
294 if ($taskInstance instanceof \TYPO3\CMS\Taskcenter\TaskInterface) {
295 $taskDescriptionHtml = $taskInstance->getOverview();
296 }
297 }
298 // Generate an array of all tasks
299 $uniqueKey = $this->getUniqueKey($extKey . '.' . $taskClass);
300 $tasks[$uniqueKey] = array(
301 'title' => $taskTitle,
302 'descriptionHtml' => $taskDescriptionHtml,
303 'description' => $this->getLanguageService()->sL($task['description']),
304 'icon' => $icon,
305 'link' => $link,
306 'uid' => $extKey . '.' . $taskClass
307 );
308 }
309 }
310 $content .= $this->renderListMenu($tasks, TRUE);
311 } else {
312 $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, $this->getLanguageService()->getLL('no-tasks', TRUE), '', \TYPO3\CMS\Core\Messaging\FlashMessage::INFO);
313 $this->content .= $flashMessage->render();
314 }
315 return $content;
316 }
317
318 /**
319 * Create the panel of buttons for submitting the form or otherwise
320 * perform operations.
321 *
322 * @return array All available buttons as an assoc. array
323 */
324 protected function getButtons() {
325 $buttons = array(
326 'csh' => \TYPO3\CMS\Backend\Utility\BackendUtility::cshItem('_MOD_web_func', ''),
327 'shortcut' => '',
328 'open_new_window' => $this->openInNewWindow()
329 );
330 // Shortcut
331 if ($this->getBackendUser()->mayMakeShortcut()) {
332 $buttons['shortcut'] = $this->doc->makeShortcutIcon('', 'function', $this->moduleName);
333 }
334 return $buttons;
335 }
336
337 /**
338 * Check the access to a task. Considered are:
339 * - Admins are always allowed
340 * - Tasks can be restriced to admins only
341 * - Tasks can be blinded for Users with TsConfig taskcenter.<extensionkey>.<taskName> = 0
342 *
343 * @param string $extKey Extension key
344 * @param string $taskClass Name of the task
345 * @return bool Access to the task allowed or not
346 */
347 protected function checkAccess($extKey, $taskClass) {
348 // Check if task is blinded with TsConfig (taskcenter.<extkey>.<taskName>
349 $tsConfig = $this->getBackendUser()->getTSConfig('taskcenter.' . $extKey . '.' . $taskClass);
350 if (isset($tsConfig['value']) && (int)$tsConfig['value'] === 0) {
351 return FALSE;
352 }
353 // Admins are always allowed
354 if ($this->getBackendUser()->isAdmin()) {
355 return TRUE;
356 }
357 // Check if task is restricted to admins
358 if ((int)$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter'][$extKey][$taskClass]['admin'] === 1) {
359 return FALSE;
360 }
361 return TRUE;
362 }
363
364 /**
365 * Returns HTML code to dislay an url in an iframe at the right side of the taskcenter
366 *
367 * @param string $url Url to display
368 * @param int $max
369 * @return string Code that inserts the iframe (HTML)
370 */
371 public function urlInIframe($url, $max = 0) {
372 return '<iframe scrolling="auto" width="100%" src="' . $url . '" name="list_frame" id="list_frame" frameborder="no"></iframe>';
373 }
374
375 /**
376 * Create a unique key from a string which can be used in Prototype's Sortable
377 * Therefore '_' are replaced
378 *
379 * @param string $string string which is used to generate the identifier
380 * @return string Modified string
381 */
382 protected function getUniqueKey($string) {
383 $search = array('.', '_');
384 $replace = array('-', '');
385 return str_replace($search, $replace, $string);
386 }
387
388 /**
389 * This method prepares the link for opening the devlog in a new window
390 *
391 * @return string Hyperlink with icon and appropriate JavaScript
392 */
393 protected function openInNewWindow() {
394 $url = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
395 $onClick = 'devlogWin=window.open(\'' . $url . '\',\'taskcenter\',\'width=790,status=0,menubar=1,resizable=1,location=0,scrollbars=1,toolbar=0\');return false;';
396 $content = '<a href="#" onclick="' . htmlspecialchars($onClick) . '">' .
397 IconUtility::getSpriteIcon('actions-window-open', array('title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.openInNewWindow', TRUE))) .
398 '</a>';
399 return $content;
400 }
401
402 /**
403 * Returns the current BE user.
404 *
405 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
406 */
407 protected function getBackendUser() {
408 return $GLOBALS['BE_USER'];
409 }
410
411 /**
412 * Returns LanguageService
413 *
414 * @return \TYPO3\CMS\Lang\LanguageService
415 */
416 protected function getLanguageService() {
417 return $GLOBALS['LANG'];
418 }
419
420 }