TYPO3  7.6
TaskModuleController.php
Go to the documentation of this file.
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 
29 
34 {
38  protected $pageinfo;
39 
45  protected $moduleTemplate;
46 
52  protected $moduleName = 'user_task';
53 
57  public function __construct()
58  {
59  $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
60  $this->moduleTemplate->getPageRenderer()->addCssFile(ExtensionManagementUtility::extRelPath('taskcenter') . 'Resources/Public/Css/styles.css');
61  $this->getLanguageService()->includeLLFile('EXT:taskcenter/Resources/Private/Language/locallang_task.xlf');
62  $this->MCONF = array(
63  'name' => $this->moduleName
64  );
65  parent::init();
66  }
67 
73  public function menuConfig()
74  {
75  $this->MOD_MENU = array('mode' => array());
76  $this->MOD_MENU['mode']['information'] = $this->getLanguageService()->sL('LLL:EXT:taskcenter/Resources/Private/Language/locallang.xlf:task_overview');
77  $this->MOD_MENU['mode']['tasks'] = $this->getLanguageService()->sL('LLL:EXT:taskcenter/Resources/Private/Language/locallang.xlf:task_tasks');
78  /* Copied from parent::menuConfig, because parent is hardcoded to menu.function,
79  * however menu.function is already used for the individual tasks.
80  * Therefore we use menu.mode here.
81  */
82  // Page/be_user TSconfig settings and blinding of menu-items
83  $this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->moduleName);
84  $this->MOD_MENU['mode'] = $this->mergeExternalItems($this->MCONF['name'], 'mode', $this->MOD_MENU['mode']);
85  $this->MOD_MENU['mode'] = BackendUtility::unsetMenuItems($this->modTSconfig['properties'], $this->MOD_MENU['mode'], 'menu.mode');
86  parent::menuConfig();
87  }
88 
94  protected function generateMenu()
95  {
96  $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
97  $menu->setIdentifier('WebFuncJumpMenu');
98  foreach ($this->MOD_MENU['mode'] as $controller => $title) {
99  $item = $menu
100  ->makeMenuItem()
101  ->setHref(
102  BackendUtility::getModuleUrl(
103  $this->moduleName,
104  [
105  'id' => $this->id,
106  'SET' => [
107  'mode' => $controller
108  ]
109  ]
110  )
111  )
112  ->setTitle($title);
113  if ($controller === $this->MOD_SETTINGS['mode']) {
114  $item->setActive(true);
115  }
116  $menu->addMenuItem($item);
117  }
118  $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
119  }
120 
130  {
131  $GLOBALS['SOBE'] = $this;
132  $this->main();
133 
134  $this->moduleTemplate->setContent($this->content);
135 
136  $response->getBody()->write($this->moduleTemplate->renderContent());
137  return $response;
138  }
139 
146  public function main()
147  {
148  $this->getButtons();
149  $this->generateMenu();
150  $this->moduleTemplate->addJavaScriptCode(
151  'TaskCenterInlineJavascript',
152  'if (top.fsMod) { top.fsMod.recentIds["web"] = 0; }'
153  );
154 
155  // Render content depending on the mode
156  $mode = (string)$this->MOD_SETTINGS['mode'];
157  if ($mode === 'information') {
158  $this->renderInformationContent();
159  } else {
160  $this->renderModuleContent();
161  }
162  // Renders the module page
163  $this->moduleTemplate->setTitle($this->getLanguageService()->getLL('title'));
164  }
165 
171  public function printContent()
172  {
173  echo $this->content;
174  }
175 
181  protected function renderModuleContent()
182  {
183  $chosenTask = (string)$this->MOD_SETTINGS['function'];
184  // Render the taskcenter task as default
185  if (empty($chosenTask) || $chosenTask == 'index') {
186  $chosenTask = 'taskcenter.tasks';
187  }
188  // Render the task
189  $actionContent = '';
190  list($extKey, $taskClass) = explode('.', $chosenTask, 2);
191  if (class_exists($taskClass)) {
192  $taskInstance = GeneralUtility::makeInstance($taskClass, $this);
193  if ($taskInstance instanceof TaskInterface) {
194  // Check if the task is restricted to admins only
195  if ($this->checkAccess($extKey, $taskClass)) {
196  $actionContent .= $taskInstance->getTask();
197  } else {
198  $flashMessage = GeneralUtility::makeInstance(
199  FlashMessage::class,
200  $this->getLanguageService()->getLL('error-access', true),
201  $this->getLanguageService()->getLL('error_header'),
203  );
204  $actionContent .= $flashMessage->render();
205  }
206  } else {
207  // Error if the task is not an instance of \TYPO3\CMS\Taskcenter\TaskInterface
208  $flashMessage = GeneralUtility::makeInstance(
209  FlashMessage::class,
210  sprintf($this->getLanguageService()->getLL('error_no-instance', true), $taskClass, TaskInterface::class),
211  $this->getLanguageService()->getLL('error_header'),
213  );
214  $actionContent .= $flashMessage->render();
215  }
216  } else {
217  $flashMessage = GeneralUtility::makeInstance(
218  FlashMessage::class,
219  $this->getLanguageService()->sL('LLL:EXT:taskcenter/Resources/Private/Language/locallang_mod.xlf:mlang_labels_tabdescr'),
220  $this->getLanguageService()->sL('LLL:EXT:taskcenter/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'),
222  );
223  $actionContent .= $flashMessage->render();
224  }
225  $content = '<div id="taskcenter-main">
226  <div id="taskcenter-menu">' . $this->indexAction() . '</div>
227  <div id="taskcenter-item" class="' . htmlspecialchars(($extKey . '-' . $taskClass)) . '">' . $actionContent . '
228  </div>
229  </div>';
230  $this->content .= $content;
231  }
232 
238  protected function renderInformationContent()
239  {
240  $content = $this->description($this->getLanguageService()->getLL('mlang_tabs_tab'), $this->getLanguageService()->sL('LLL:EXT:taskcenter/Resources/Private/Language/locallang_mod.xlf:mlang_labels_tabdescr'));
241  $content .= $this->getLanguageService()->getLL('taskcenter-about');
242  if ($this->getBackendUser()->isAdmin()) {
243  $content .= '<br /><br />' . $this->description($this->getLanguageService()->getLL('taskcenter-adminheader'), $this->getLanguageService()->getLL('taskcenter-admin'));
244  }
245  $this->content .= $content;
246  }
247 
255  public function description($title, $description = '')
256  {
257  $content = '<h1>' . nl2br(htmlspecialchars($title)) . '</h1>';
258  if (!empty($description)) {
259  $content .= '<p class="description">' . nl2br(htmlspecialchars($description)) . '</p>';
260  }
261  return $content;
262  }
263 
279  public function renderListMenu($items, $mainMenu = false)
280  {
281  $content = ($section = '');
282  $count = 0;
283  // Change the sorting of items to the user's one
284  if ($mainMenu) {
285  $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Taskcenter/Taskcenter');
286  $userSorting = unserialize($this->getBackendUser()->uc['taskcenter']['sorting']);
287  if (is_array($userSorting)) {
288  $newSorting = array();
289  foreach ($userSorting as $item) {
290  if (isset($items[$item])) {
291  $newSorting[] = $items[$item];
292  unset($items[$item]);
293  }
294  }
295  $items = $newSorting + $items;
296  }
297  }
298  if (is_array($items) && !empty($items)) {
299  foreach ($items as $item) {
300  $title = htmlspecialchars($item['title']);
301  $icon = ($additionalClass = ($collapsedStyle = ''));
302  // Check for custom icon
303  if (!empty($item['icon'])) {
304  if (strpos($item['icon'], '<img ') === false) {
305  $absIconPath = GeneralUtility::getFileAbsFileName($item['icon']);
306  // If the file indeed exists, assemble relative path to it
307  if (file_exists($absIconPath)) {
308  $icon = '../' . str_replace(PATH_site, '', $absIconPath);
309  $icon = '<img src="' . $icon . '" title="' . $title . '" alt="' . $title . '" />';
310  }
311  if (@is_file($icon)) {
312  $icon = '<img src="' . PathUtility::getAbsoluteWebPath($icon) . '" width="16" height="16" title="' . $title . '" alt="' . $title . '" />';
313  }
314  } else {
315  $icon = $item['icon'];
316  }
317  }
318  $description = $item['descriptionHtml'] ?: '<p>' . nl2br(htmlspecialchars($item['description'])) . '</p>';
319  $id = $this->getUniqueKey($item['uid']);
320  // Collapsed & expanded menu items
321  if ($mainMenu && isset($this->getBackendUser()->uc['taskcenter']['states'][$id]) && $this->getBackendUser()->uc['taskcenter']['states'][$id]) {
322  $collapsedStyle = 'style="display:none"';
323  $additionalClass = 'collapsed';
324  } else {
325  $additionalClass = 'expanded';
326  }
327  // First & last menu item
328  if ($count == 0) {
329  $additionalClass .= ' first-item';
330  } elseif ($count + 1 === count($items)) {
331  $additionalClass .= ' last-item';
332  }
333  // Active menu item
334  $active = (string)$this->MOD_SETTINGS['function'] == $item['uid'] ? ' active-task' : '';
335  // Main menu: Render additional syntax to sort tasks
336  if ($mainMenu) {
337  $section = '<div class="down"><i class="fa fa-caret-down fa-fw"></i></div>
338  <div class="drag"><i class="fa fa-arrows"></i></div>';
339  $backgroundClass = 't3-row-header ';
340  } else {
341  $backgroundClass = '';
342  }
343  $content .= '<li class="' . $additionalClass . $active . '" id="el_' . $id . '">
344  ' . $section . '
345  <div class="image">' . $icon . '</div>
346  <div class="' . $backgroundClass . 'link"><a href="' . $item['link'] . '">' . $title . '</a></div>
347  <div class="content " ' . $collapsedStyle . '>' . $description . '</div>
348  </li>';
349  $count++;
350  }
351  $navigationId = $mainMenu ? 'id="task-list"' : '';
352  $content = '<ul ' . $navigationId . ' class="task-list">' . $content . '</ul>';
353  }
354  return $content;
355  }
356 
362  protected function indexAction()
363  {
364  $content = '';
365  $tasks = array();
366  $icon = ExtensionManagementUtility::extRelPath('taskcenter') . 'Resources/Public/Icons/module-taskcenter.svg';
367  // Render the tasks only if there are any available
368  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter']) && !empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter'])) {
369  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter'] as $extKey => $extensionReports) {
370  foreach ($extensionReports as $taskClass => $task) {
371  if (!$this->checkAccess($extKey, $taskClass)) {
372  continue;
373  }
374  $link = BackendUtility::getModuleUrl('user_task') . '&SET[function]=' . $extKey . '.' . $taskClass;
375  $taskTitle = $this->getLanguageService()->sL($task['title']);
376  $taskDescriptionHtml = '';
377  // Check for custom icon
378  if (!empty($task['icon'])) {
379  $icon = GeneralUtility::getFileAbsFileName($task['icon']);
380  }
381  if (class_exists($taskClass)) {
382  $taskInstance = GeneralUtility::makeInstance($taskClass, $this);
383  if ($taskInstance instanceof TaskInterface) {
384  $taskDescriptionHtml = $taskInstance->getOverview();
385  }
386  }
387  // Generate an array of all tasks
388  $uniqueKey = $this->getUniqueKey($extKey . '.' . $taskClass);
389  $tasks[$uniqueKey] = array(
390  'title' => $taskTitle,
391  'descriptionHtml' => $taskDescriptionHtml,
392  'description' => $this->getLanguageService()->sL($task['description']),
393  'icon' => $icon,
394  'link' => $link,
395  'uid' => $extKey . '.' . $taskClass
396  );
397  }
398  }
399  $content .= $this->renderListMenu($tasks, true);
400  } else {
401  $flashMessage = GeneralUtility::makeInstance(
402  FlashMessage::class,
403  $this->getLanguageService()->getLL('no-tasks', true),
404  '',
406  );
407  $this->content .= $flashMessage->render();
408  }
409  return $content;
410  }
411 
418  protected function getButtons()
419  {
420  $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
421 
422  // Fullscreen Button
423  $url = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
424  $onClick = 'devlogWin=window.open(' . GeneralUtility::quoteJSvalue($url) . ',\'taskcenter\',\'width=790,status=0,menubar=1,resizable=1,location=0,scrollbars=1,toolbar=0\');return false;';
425  $fullscreenButton = $buttonBar->makeLinkButton()
426  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.openInNewWindow', true))
427  ->setOnClick($onClick)
428  ->setHref('#')
429  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-window-open', Icon::SIZE_SMALL))
430  ;
431  $buttonBar->addButton($fullscreenButton, ButtonBar::BUTTON_POSITION_RIGHT, 1);
432 
433  // Shortcut
434  $shortcutButton = $buttonBar->makeShortcutButton()
435  ->setModuleName($this->moduleName)
436  ->setSetVariables(['function']);
437  $buttonBar->addButton($shortcutButton);
438  }
439 
450  protected function checkAccess($extKey, $taskClass)
451  {
452  // Check if task is blinded with TsConfig (taskcenter.<extkey>.<taskName>
453  $tsConfig = $this->getBackendUser()->getTSConfig('taskcenter.' . $extKey . '.' . $taskClass);
454  if (isset($tsConfig['value']) && (int)$tsConfig['value'] === 0) {
455  return false;
456  }
457  // Admins are always allowed
458  if ($this->getBackendUser()->isAdmin()) {
459  return true;
460  }
461  // Check if task is restricted to admins
462  if ((int)$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['taskcenter'][$extKey][$taskClass]['admin'] === 1) {
463  return false;
464  }
465  return true;
466  }
467 
474  public function urlInIframe($url)
475  {
476  return '<iframe scrolling="auto" width="100%" src="' . $url . '" name="list_frame" id="list_frame" frameborder="no"></iframe>';
477  }
478 
486  protected function getUniqueKey($string)
487  {
488  $search = array('.', '_');
489  $replace = array('-', '');
490  return str_replace($search, $replace, $string);
491  }
492 
498  protected function openInNewWindow()
499  {
500  $url = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
501  $onClick = 'devlogWin=window.open(' . GeneralUtility::quoteJSvalue($url) . ',\'taskcenter\',\'width=790,status=0,menubar=1,resizable=1,location=0,scrollbars=1,toolbar=0\');return false;';
502  $content = '<a href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.openInNewWindow', true) . '">'
503  . $this->moduleTemplate->getIconFactory()->getIcon('actions-window-open', Icon::SIZE_SMALL)->render()
504  . '</a>';
505  return $content;
506  }
507 
513  protected function getBackendUser()
514  {
515  return $GLOBALS['BE_USER'];
516  }
517 
523  protected function getLanguageService()
524  {
525  return $GLOBALS['LANG'];
526  }
527 
531  public function getModuleTemplate()
532  {
533  return $this->moduleTemplate;
534  }
535 
536 
537 }