TYPO3 CMS  TYPO3_8-7
ModuleTemplate.php
Go to the documentation of this file.
1 <?php
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 
30 
38 {
44  const STATUS_ICON_ERROR = 3;
45 
52 
59 
65  const STATUS_ICON_OK = -1;
66 
73 
80  protected $javascriptCodeArray = [];
81 
87  protected $pageRenderer;
88 
92  protected $uiBlock = false;
93 
99  protected $templateRootPaths = ['EXT:backend/Resources/Private/Templates'];
100 
106  protected $partialRootPaths = ['EXT:backend/Resources/Private/Partials'];
107 
113  protected $layoutRootPaths = ['EXT:backend/Resources/Private/Layouts'];
114 
120  protected $templateFile = 'Module.html';
121 
127  protected $view;
128 
134  protected $content = '';
135 
141  protected $iconFactory;
142 
148  protected $moduleId = '';
149 
155  protected $moduleName = '';
156 
162  protected $title = '';
163 
169  protected $bodyTag = '<body>';
170 
177 
183  public function getBodyTag()
184  {
185  return $this->bodyTag;
186  }
187 
193  public function setBodyTag($bodyTag)
194  {
195  $this->bodyTag = $bodyTag;
196  }
197 
203  public function getView()
204  {
205  return $this->view;
206  }
207 
213  public function setContent($content)
214  {
215  $this->view->assign('content', $content);
216  }
217 
223  public function setTitle($title)
224  {
225  $this->title = $title;
226  }
227 
233  public function getIconFactory()
234  {
235  return $this->iconFactory;
236  }
237 
244  public function __construct()
245  {
246  $this->view = GeneralUtility::makeInstance(StandaloneView::class);
247  $this->view->setPartialRootPaths($this->partialRootPaths);
248  $this->view->setTemplateRootPaths($this->templateRootPaths);
249  $this->view->setLayoutRootPaths($this->layoutRootPaths);
250  $this->view->setTemplate($this->templateFile);
251  $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
252  $this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
253  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
254  }
255 
259  protected function loadJavaScripts()
260  {
261  $this->pageRenderer->loadJquery();
262  $this->pageRenderer->loadRequireJsModule('bootstrap');
263  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextHelp');
264  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DocumentHeader');
265  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/SplitButtons');
266  }
267 
271  protected function loadStylesheets()
272  {
273  if (!empty($GLOBALS['TBE_STYLES']['stylesheet'])) {
274  $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet']);
275  }
276  if (!empty($GLOBALS['TBE_STYLES']['stylesheet2'])) {
277  $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet2']);
278  }
279  }
280 
284  protected function setupPage()
285  {
286  // Yes, hardcoded on purpose
287  $this->pageRenderer->setXmlPrologAndDocType('<!DOCTYPE html>');
288  $this->pageRenderer->setCharSet('utf-8');
289  $this->pageRenderer->setLanguage($GLOBALS['LANG']->lang);
290  $this->pageRenderer->addMetaTag('<meta name="viewport" content="width=device-width, initial-scale=1">');
291  }
292 
296  protected function setJavaScriptCodeArray()
297  {
298  foreach ($this->javascriptCodeArray as $name => $code) {
299  $this->pageRenderer->addJsInlineCode($name, $code, false);
300  }
301  }
302 
309  public function addJavaScriptCode($name = '', $code = '')
310  {
311  $this->javascriptCodeArray[$name] = $code;
312  }
313 
319  public function getDocHeaderComponent()
320  {
322  }
323 
329  public function renderContent()
330  {
331  $this->setupPage();
332  $this->pageRenderer->setTitle($this->title);
333  $this->loadJavaScripts();
334  $this->setJavaScriptCodeArray();
335  $this->loadStylesheets();
336 
337  $this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
338  if ($this->moduleId) {
339  $this->view->assign('moduleId', $this->moduleId);
340  }
341  if ($this->moduleName) {
342  $this->view->assign('moduleName', $this->moduleName);
343  }
344  $this->view->assign('uiBlock', $this->uiBlock);
345  $this->view->assign('flashMessageQueueIdentifier', $this->getFlashMessageQueue()->getIdentifier());
346  $renderedPage = $this->pageRenderer->render(PageRenderer::PART_HEADER);
347  $renderedPage .= $this->bodyTag;
348  $renderedPage .= $this->view->render();
349  $this->pageRenderer->addJsFooterInlineCode('updateSignals', BackendUtility::getUpdateSignalCode());
350  $renderedPage .= $this->pageRenderer->render(PageRenderer::PART_FOOTER);
351 
352  return $renderedPage;
353  }
354 
360  public function getPageRenderer()
361  {
362  return $this->pageRenderer;
363  }
364 
370  public function setForm($formTag = '')
371  {
372  $this->view->assign('formTag', $formTag);
373  }
374 
380  public function setModuleId($moduleId)
381  {
382  $this->moduleId = $moduleId;
384  }
385 
391  public function setModuleName($moduleName)
392  {
393  $this->moduleName = $moduleName;
394  }
395 
401  public function registerModuleMenu($moduleMenuIdentifier)
402  {
403  if (isset($GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier])) {
404  $menuEntries =
405  $GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier]['MOD_MENU']['function'];
406  $menu = $this->getDocHeaderComponent()->getMenuRegistry()->makeMenu()->setIdentifier('MOD_FUNC');
407  foreach ($menuEntries as $menuEntry) {
408  $menuItem = $menu->makeMenuItem()
409  ->setTitle($menuEntry['title'])
410  ->setHref('#');
411  $menu->addMenuItem($menuItem);
412  }
413  $this->docHeaderComponent->getMenuRegistry()->addMenu($menu);
414  }
415  }
416 
434  public function getDynamicTabMenu(array $menuItems, $domId, $defaultTabIndex = 1, $collapsible = false, $wrapContent = true, $storeLastActiveTab = true)
435  {
436  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tabs');
437  $templatePath = ExtensionManagementUtility::extPath('backend')
438  . 'Resources/Private/Templates/DocumentTemplate/';
439  $view = GeneralUtility::makeInstance(StandaloneView::class);
440  $view->setTemplatePathAndFilename($templatePath . ($collapsible ? 'Collapse.html' : 'Tabs.html'));
441  $view->setPartialRootPaths([$templatePath . 'Partials']);
442  $view->assignMultiple([
443  'id' => 'DTM-' . GeneralUtility::shortMD5($domId),
444  'items' => $menuItems,
445  'defaultTabIndex' => $defaultTabIndex,
446  'wrapContent' => $wrapContent,
447  'storeLastActiveTab' => $storeLastActiveTab,
448  ]);
449  return $view->render();
450  }
451 
452  /*******************************************
453  * THE FOLLOWING METHODS ARE SUBJECT TO BE DEPRECATED / DROPPED!
454  *
455  * These methods have been copied over from DocumentTemplate and enables
456  * core modules to drop the dependency to DocumentTemplate altogether without
457  * rewriting these modules now.
458  * The methods below are marked as internal and will be removed
459  * one-by-one with further refactoring of modules.
460  *
461  * Do not use these methods within own extensions if possible or
462  * be prepared to change this later again.
463  *******************************************/
464 
473  public function loadJavascriptLib($lib)
474  {
475  // @todo: maybe we can remove this one as well
476  $this->pageRenderer->addJsFile($lib);
477  }
478 
502  public function makeShortcutIcon($gvList, $setList, $modName, $motherModName = '', $displayName = '', $classes = 'btn btn-default btn-sm')
503  {
504  $gvList = 'route,' . $gvList;
505  $storeUrl = $this->makeShortcutUrl($gvList, $setList);
506  $pathInfo = parse_url(GeneralUtility::getIndpEnv('REQUEST_URI'));
507  // Fallback for alt_mod. We still pass in the old xMOD... stuff,
508  // but TBE_MODULES only knows about "record_edit".
509  // We still need to pass the xMOD name to createShortcut below,
510  // since this is used for icons.
511  $moduleName = $modName === 'xMOD_alt_doc.php' ? 'record_edit' : $modName;
512  // Add the module identifier automatically if typo3/index.php is used:
513  if (GeneralUtility::_GET('M') !== null) {
514  $storeUrl = '&M=' . $moduleName . $storeUrl;
515  }
516  if ((int)$motherModName === 1) {
517  $motherModule = 'top.currentModuleLoaded';
518  } elseif ($motherModName) {
519  $motherModule = GeneralUtility::quoteJSvalue($motherModName);
520  } else {
521  $motherModule = '\'\'';
522  }
523  $confirmationText = GeneralUtility::quoteJSvalue(
524  $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.makeBookmark')
525  );
526 
527  $shortcutUrl = $pathInfo['path'] . '?' . $storeUrl;
528  $shortcutExist = BackendUtility::shortcutExists($shortcutUrl);
529 
530  if ($shortcutExist) {
531  return '<a class="active ' . htmlspecialchars($classes) . '" title="">' .
532  $this->iconFactory->getIcon('actions-system-shortcut-active', Icon::SIZE_SMALL)->render() . '</a>';
533  }
534 
535  $url = GeneralUtility::quoteJSvalue(rawurlencode($shortcutUrl));
536  $onClick = 'top.TYPO3.ShortcutMenu.createShortcut(' . GeneralUtility::quoteJSvalue(rawurlencode($modName)) .
537  ', ' . $url . ', ' . $confirmationText . ', ' . $motherModule . ', this, ' . GeneralUtility::quoteJSvalue($displayName) . ');return false;';
538 
539  return '<a href="#" class="' . htmlspecialchars($classes) . '" onclick="' . htmlspecialchars($onClick) . '" title="' .
540  htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.makeBookmark')) . '">' .
541  $this->iconFactory->getIcon('actions-system-shortcut-new', Icon::SIZE_SMALL)->render() . '</a>';
542  }
543 
556  public function makeShortcutUrl($gvList, $setList)
557  {
558  $getParams = GeneralUtility::_GET();
559  $storeArray = array_merge(
561  ['SET' => GeneralUtility::compileSelectedGetVarsFromArray($setList, (array)$GLOBALS['SOBE']->MOD_SETTINGS)]
562  );
563  return GeneralUtility::implodeArrayForUrl('', $storeArray);
564  }
565 
577  public function getVersionSelector($id, $noAction = false)
578  {
580  && ExtensionManagementUtility::isLoaded('compatibility7')
581  && !ExtensionManagementUtility::isLoaded('workspaces')
582  ) {
588  $versionGuiObj = GeneralUtility::makeInstance(\TYPO3\CMS\Compatibility7\View\VersionView::class);
589  return $versionGuiObj->getVersionSelector($id, $noAction);
590  }
591  return '';
592  }
593 
599  protected function getBackendUserAuthentication()
600  {
601  return $GLOBALS['BE_USER'];
602  }
603 
609  protected function getLanguageService()
610  {
611  return $GLOBALS['LANG'];
612  }
613 
628  public function icons($type)
629  {
630  $icon = '';
631  switch ($type) {
632  case self::STATUS_ICON_ERROR:
633  $icon = 'status-dialog-error';
634  break;
635  case self::STATUS_ICON_WARNING:
636  $icon = 'status-dialog-warning';
637  break;
638  case self::STATUS_ICON_NOTIFICATION:
639  $icon = 'status-dialog-notification';
640  break;
641  case self::STATUS_ICON_OK:
642  $icon = 'status-dialog-ok';
643  break;
644  default:
645  // Do nothing
646  }
647  if ($icon != '') {
648  return $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render();
649  }
650  return '';
651  }
652 
662  public function redirectUrls($thisLocation = '')
663  {
664  $thisLocation = $thisLocation ? $thisLocation : GeneralUtility::linkThisScript([
665  'CB' => '',
666  'SET' => '',
667  'cmd' => '',
668  'popViewId' => ''
669  ]);
670  $out = '
671  var T3_RETURN_URL = ' . GeneralUtility::quoteJSvalue(str_replace('%20', '', rawurlencode(GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'))))) . ';
672  var T3_THIS_LOCATION = ' . GeneralUtility::quoteJSvalue(str_replace('%20', '', rawurlencode($thisLocation))) . '
673  ';
674  return $out;
675  }
676 
685  public function header($text)
686  {
687  return '
688 
689  <!-- MAIN Header in page top -->
690  <h1 class="t3js-title-inlineedit">' . htmlspecialchars($text) . '</h1>
691 ';
692  }
693 
703  public function addFlashMessage($messageBody, $messageTitle = '', $severity = AbstractMessage::OK, $storeInSession = true)
704  {
705  if (!is_string($messageBody)) {
706  throw new \InvalidArgumentException('The message body must be of type string, "' . gettype($messageBody) . '" given.', 1446483133);
707  }
708  /* @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
709  $flashMessage = GeneralUtility::makeInstance(
710  \TYPO3\CMS\Core\Messaging\FlashMessage::class,
711  $messageBody,
712  $messageTitle,
713  $severity,
714  $storeInSession
715  );
716  $this->getFlashMessageQueue()->enqueue($flashMessage);
717  }
718 
723  {
724  $this->flashMessageQueue = $flashMessageQueue;
725  }
726 
730  protected function getFlashMessageQueue()
731  {
732  if (!isset($this->flashMessageQueue)) {
734  $service = GeneralUtility::makeInstance(FlashMessageService::class);
735  $this->flashMessageQueue = $service->getMessageQueueByIdentifier();
736  }
738  }
739 
743  public function isUiBlock(): bool
744  {
745  return $this->uiBlock;
746  }
747 
751  public function setUiBlock(bool $uiBlock)
752  {
753  $this->uiBlock = $uiBlock;
754  }
755 }
static compileSelectedGetVarsFromArray($varList, array $getArray, $GPvarAlt=true)
addFlashMessage($messageBody, $messageTitle='', $severity=AbstractMessage::OK, $storeInSession=true)
static linkThisScript(array $getParams=[])
static makeInstance($className,... $constructorArguments)
static implodeArrayForUrl($name, array $theArray, $str='', $skipBlank=false, $rawurlencodeParamName=false)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
makeShortcutIcon($gvList, $setList, $modName, $motherModName='', $displayName='', $classes='btn btn-default btn-sm')
getDynamicTabMenu(array $menuItems, $domId, $defaultTabIndex=1, $collapsible=false, $wrapContent=true, $storeLastActiveTab=true)