TYPO3  7.6
ModuleTemplate.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Backend\Template;
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 
27 use TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException;
31 
39 {
45  const STATUS_ICON_ERROR = 3;
46 
53 
60 
66  const STATUS_ICON_OK = -1;
67 
74 
81  protected $javascriptCodeArray = [];
82 
88  protected $pageRenderer;
89 
95  protected $templateRootPaths = ['EXT:backend/Resources/Private/Templates'];
96 
102  protected $partialRootPaths = ['EXT:backend/Resources/Private/Partials'];
103 
109  protected $layoutRootPaths = ['EXT:backend/Resources/Private/Layouts'];
110 
116  protected $templateFile = 'Module.html';
117 
123  protected $view;
124 
130  protected $content = '';
131 
137  protected $sectionFlag = 0;
138 
144  protected $iconFactory;
145 
151  protected $moduleId = '';
152 
158  protected $moduleName = '';
159 
165  protected $title = '';
166 
172  protected $bodyTag = '<body>';
173 
180 
186  public function getBodyTag()
187  {
188  return $this->bodyTag;
189  }
190 
196  public function setBodyTag($bodyTag)
197  {
198  $this->bodyTag = $bodyTag;
199  }
200 
206  public function getView()
207  {
208  return $this->view;
209  }
210 
217  public function setContent($content)
218  {
219  $this->view->assign('content', $content);
220  }
221 
227  public function setTitle($title)
228  {
229  $this->title = $title;
230  }
231 
237  public function getIconFactory()
238  {
239  return $this->iconFactory;
240  }
241 
248  public function __construct()
249  {
250  $this->view = GeneralUtility::makeInstance(StandaloneView::class);
251  $this->view->setPartialRootPaths($this->partialRootPaths);
252  $this->view->setTemplateRootPaths($this->templateRootPaths);
253  $this->view->setLayoutRootPaths($this->layoutRootPaths);
254  $this->view->setTemplate($this->templateFile);
255  $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
256  $this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
257  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
258  }
259 
265  protected function loadJavaScripts()
266  {
267  $this->pageRenderer->loadJquery();
268  $this->pageRenderer->loadRequireJsModule('bootstrap');
269  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextHelp');
270  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DocumentHeader');
271  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/SplitButtons');
272  }
273 
279  protected function loadStylesheets()
280  {
281  if ($GLOBALS['TBE_STYLES']['stylesheet']) {
282  $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet']);
283  }
284  if ($GLOBALS['TBE_STYLES']['stylesheet2']) {
285  $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet2']);
286  }
287  }
288 
294  protected function setupPage()
295  {
296  // Yes, hardcoded on purpose
297  $this->pageRenderer->setXmlPrologAndDocType('<!DOCTYPE html>');
298  $this->pageRenderer->setCharSet('utf-8');
299  $this->pageRenderer->setLanguage('default');
300  $this->pageRenderer->addMetaTag('<meta name="viewport" content="width=device-width, initial-scale=1">');
301  }
302 
308  protected function setJavaScriptCodeArray()
309  {
310  foreach ($this->javascriptCodeArray as $name => $code) {
311  $this->pageRenderer->addJsInlineCode($name, $code, false);
312  }
313  }
314 
323  public function addJavaScriptCode($name = '', $code = '')
324  {
325  $this->javascriptCodeArray[$name] = $code;
326  }
327 
333  public function getDocHeaderComponent()
334  {
336  }
337 
343  public function renderContent()
344  {
345  $this->setupPage();
346  $this->pageRenderer->setTitle($this->title);
347  $this->loadJavaScripts();
348  $this->setJavaScriptCodeArray();
349  $this->loadStylesheets();
350 
351  $this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
352  if ($this->moduleId) {
353  $this->view->assign('moduleId', $this->moduleId);
354  }
355  if ($this->moduleName) {
356  $this->view->assign('moduleName', $this->moduleName);
357  }
358  $this->view->assign('flashMessageQueueIdentifier', $this->getFlashMessageQueue()->getIdentifier());
359  $renderedPage = $this->pageRenderer->render(PageRenderer::PART_HEADER);
360  $renderedPage .= $this->bodyTag;
361  $renderedPage .= $this->view->render();
362  $this->pageRenderer->addJsFooterInlineCode('updateSignals', BackendUtility::getUpdateSignalCode());
363  $renderedPage .= $this->pageRenderer->render(PageRenderer::PART_FOOTER);
364 
365  return $renderedPage;
366  }
367 
373  public function getPageRenderer()
374  {
375  return $this->pageRenderer;
376  }
377 
385  public function setForm($formTag = '')
386  {
387  $this->view->assign('formTag', $formTag);
388  }
389 
397  public function setModuleId($moduleId)
398  {
399  $this->moduleId = $moduleId;
401  }
402 
410  public function setModuleName($moduleName)
411  {
412  $this->moduleName = $moduleName;
413  }
414 
420  public function registerModuleMenu($moduleMenuIdentifier)
421  {
422  if (isset($GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier])) {
423  $menuEntries =
424  $GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier]['MOD_MENU']['function'];
425  $menu = $this->getDocHeaderComponent()->getMenuRegistry()->makeMenu()->setIdentifier('MOD_FUNC');
426  foreach ($menuEntries as $menuEntry) {
427  $menuItem = $menu->makeMenuItem()
428  ->setTitle($menuEntry['title'])
429  ->setHref('#');
430  $menu->addMenuItem($menuItem);
431  }
432  $this->docHeaderComponent->getMenuRegistry()->addMenu($menu);
433  }
434  }
435 
453  public function getDynamicTabMenu(array $menuItems, $domId, $defaultTabIndex = 1, $collapsible = false, $wrapContent = true, $storeLastActiveTab = true)
454  {
455  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tabs');
456  $templatePathAndFileName = 'EXT:backend/Resources/Private/Templates/DocumentTemplate/' . ($collapsible ? 'Collapse.html' : 'Tabs.html');
457  $view = GeneralUtility::makeInstance(StandaloneView::class);
458  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templatePathAndFileName));
459  $view->assignMultiple(array(
460  'id' => 'DTM-' . GeneralUtility::shortMD5($domId),
461  'items' => $menuItems,
462  'defaultTabIndex' => $defaultTabIndex,
463  'wrapContent' => $wrapContent,
464  'storeLastActiveTab' => $storeLastActiveTab,
465  ));
466  return $view->render();
467  }
468 
469  /*******************************************
470  * THE FOLLOWING METHODS ARE SUBJECT TO BE DEPRECATED / DROPPED!
471  *
472  * These methods have been copied over from DocumentTemplate and enables
473  * core modules to drop the dependency to DocumentTemplate altogether without
474  * rewriting these modules now.
475  * The methods below are marked as internal and will be removed
476  * one-by-one with further refactoring of modules.
477  *
478  * Do not use these methods within own extensions if possible or
479  * be prepared to change this later again.
480  *******************************************/
481 
491  public function loadJavascriptLib($lib)
492  {
493  // @todo: maybe we can remove this one as well
494  $this->pageRenderer->addJsFile($lib);
495  }
496 
520  public function makeShortcutIcon($gvList, $setList, $modName, $motherModName = '', $displayName = '', $classes = 'btn btn-default btn-sm')
521  {
522  $gvList = 'route,' . $gvList;
523  $storeUrl = $this->makeShortcutUrl($gvList, $setList);
524  $pathInfo = parse_url(GeneralUtility::getIndpEnv('REQUEST_URI'));
525  // Fallback for alt_mod. We still pass in the old xMOD... stuff,
526  // but TBE_MODULES only knows about "record_edit".
527  // We still need to pass the xMOD name to createShortcut below,
528  // since this is used for icons.
529  $moduleName = $modName === 'xMOD_alt_doc.php' ? 'record_edit' : $modName;
530  // Add the module identifier automatically if typo3/index.php is used:
531  if (GeneralUtility::_GET('M') !== null && isset($GLOBALS['TBE_MODULES']['_PATHS'][$moduleName])) {
532  $storeUrl = '&M=' . $moduleName . $storeUrl;
533  }
534  if ((int)$motherModName === 1) {
535  $motherModule = 'top.currentModuleLoaded';
536  } elseif ($motherModName) {
537  $motherModule = GeneralUtility::quoteJSvalue($motherModName);
538  } else {
539  $motherModule = '\'\'';
540  }
541  $confirmationText = GeneralUtility::quoteJSvalue(
542  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.makeBookmark')
543  );
544 
545  $shortcutUrl = $pathInfo['path'] . '?' . $storeUrl;
546  $shortcutExist = BackendUtility::shortcutExists($shortcutUrl);
547 
548  if ($shortcutExist) {
549  return '<a class="active ' . htmlspecialchars($classes) . '" title="">' .
550  $this->iconFactory->getIcon('actions-system-shortcut-active', Icon::SIZE_SMALL)->render() . '</a>';
551  }
552 
553  $url = GeneralUtility::quoteJSvalue(rawurlencode($shortcutUrl));
554  $onClick = 'top.TYPO3.ShortcutMenu.createShortcut(' . GeneralUtility::quoteJSvalue(rawurlencode($modName)) .
555  ', ' . $url . ', ' . $confirmationText . ', ' . $motherModule . ', this, ' . GeneralUtility::quoteJSvalue($displayName) . ');return false;';
556 
557  return '<a href="#" class="' . htmlspecialchars($classes) . '" onclick="' . htmlspecialchars($onClick) . '" title="' .
558  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.makeBookmark', true) . '">' .
559  $this->iconFactory->getIcon('actions-system-shortcut-new', Icon::SIZE_SMALL)->render() . '</a>';
560  }
561 
574  public function makeShortcutUrl($gvList, $setList)
575  {
576  $getParams = GeneralUtility::_GET();
577  $storeArray = array_merge(
579  array('SET' => GeneralUtility::compileSelectedGetVarsFromArray($setList, (array)$GLOBALS['SOBE']->MOD_SETTINGS))
580  );
581  return GeneralUtility::implodeArrayForUrl('', $storeArray);
582  }
583 
594  public function getVersionSelector($id, $noAction = false)
595  {
597  && !ExtensionManagementUtility::isLoaded('workspaces')
598  ) {
604  $versionGuiObj = GeneralUtility::makeInstance(VersionView::class);
605  return $versionGuiObj->getVersionSelector($id, $noAction);
606  }
607  return '';
608  }
609 
627  public function section($label, $text, $noStrToUpper = false, $sH = false, $type = 0, $allowHtmlInHeader = false)
628  {
629  $str = '';
630  // Setting header
631  if ($label) {
632  if (!$allowHtmlInHeader) {
633  $label = htmlspecialchars($label);
634  }
635  $str .= $this->sectionHeader($this->icons($type) . $label, $sH, $noStrToUpper ? '' : ' class="uppercase"');
636  }
637  // Setting content
638  $str .= '
639 
640  <!-- Section content -->
641 ' . $text;
642  return $this->sectionBegin() . $str;
643  }
644 
654  public function divider($dist)
655  {
656  $dist = (int)$dist;
657  $str = '
658 
659  <!-- DIVIDER -->
660  <hr style="margin-top: ' . $dist . 'px; margin-bottom: ' . $dist . 'px;" />
661 ';
662  return $this->sectionEnd() . $str;
663  }
664 
676  public function sectionHeader($label, $sH = false, $addAttribute = '')
677  {
678  $tag = $sH ? 'h2' : 'h3';
679  if ($addAttribute && $addAttribute[0] !== ' ') {
680  $addAttribute = ' ' . $addAttribute;
681  }
682  $str = '
683 
684  <!-- Section header -->
685  <' . $tag . $addAttribute . '>' . $label . '</' . $tag . '>
686 ';
687  return $this->sectionBegin() . $str;
688  }
689 
701  public function sectionBegin()
702  {
703  if (!$this->sectionFlag) {
704  $this->sectionFlag = 1;
705  $str = '
706 
707  <!-- ***********************
708  Begin output section.
709  *********************** -->
710  <div>
711 ';
712  return $str;
713  }
714  return '';
715  }
716 
726  public function sectionEnd()
727  {
728  if ($this->sectionFlag) {
729  $this->sectionFlag = 0;
730  return '
731  </div>
732  <!-- *********************
733  End output section.
734  ********************* -->
735 ';
736  }
737  return '';
738  }
739 
740 
741 
747  protected function getBackendUserAuthentication()
748  {
749  return $GLOBALS['BE_USER'];
750  }
751 
757  protected function getLanguageService()
758  {
759  return $GLOBALS['LANG'];
760  }
761 
776  public function icons($type)
777  {
778  $icon = '';
779  switch ($type) {
780  case self::STATUS_ICON_ERROR:
781  $icon = 'status-dialog-error';
782  break;
783  case self::STATUS_ICON_WARNING:
784  $icon = 'status-dialog-warning';
785  break;
786  case self::STATUS_ICON_NOTIFICATION:
787  $icon = 'status-dialog-notification';
788  break;
789  case self::STATUS_ICON_OK:
790  $icon = 'status-dialog-ok';
791  break;
792  default:
793  // Do nothing
794  }
795  if ($icon != '') {
796  return $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render();
797  }
798  return '';
799  }
800 
810  public function redirectUrls($thisLocation = '')
811  {
812  $thisLocation = $thisLocation ? $thisLocation : GeneralUtility::linkThisScript(array(
813  'CB' => '',
814  'SET' => '',
815  'cmd' => '',
816  'popViewId' => ''
817  ));
818  $out = '
819  var T3_RETURN_URL = ' . GeneralUtility::quoteJSvalue(str_replace('%20', '', rawurlencode(GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'))))) . ';
820  var T3_THIS_LOCATION = ' . GeneralUtility::quoteJSvalue(str_replace('%20', '', rawurlencode($thisLocation))) . '
821  ';
822  return $out;
823  }
824 
833  public function header($text)
834  {
835  $str = '
836 
837  <!-- MAIN Header in page top -->
838  <h1 class="t3js-title-inlineedit">' . htmlspecialchars($text) . '</h1>
839 ';
840  return $this->sectionEnd() . $str;
841  }
842 
853  public function addFlashMessage($messageBody, $messageTitle = '', $severity = AbstractMessage::OK, $storeInSession = true)
854  {
855  if (!is_string($messageBody)) {
856  throw new \InvalidArgumentException('The message body must be of type string, "' . gettype($messageBody) . '" given.', 1446483133);
857  }
858  /* @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
859  $flashMessage = GeneralUtility::makeInstance(
860  \TYPO3\CMS\Core\Messaging\FlashMessage::class,
861  $messageBody,
862  $messageTitle,
863  $severity,
864  $storeInSession
865  );
866  $this->getFlashMessageQueue()->enqueue($flashMessage);
867  }
868 
873  {
874  $this->flashMessageQueue = $flashMessageQueue;
875  }
876 
880  protected function getFlashMessageQueue()
881  {
882  if (!isset($this->flashMessageQueue)) {
884  $service = GeneralUtility::makeInstance(FlashMessageService::class);
885  $this->flashMessageQueue = $service->getMessageQueueByIdentifier();
886  }
888  }
889 }