TYPO3 CMS  TYPO3_8-7
TypoScriptTemplateModuleController.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 
35 
40 {
44  public $perms_clause;
45 
49  public $e;
50 
54  public $sObj;
55 
59  public $edit;
60 
64  public $textExtensions = 'html,htm,txt,css,tmpl,inc,js';
65 
69  public $modMenu_type = '';
70 
75 
80 
84  public $pageinfo = [];
85 
89  public $access = false;
90 
96  protected $moduleName = 'web_ts';
97 
103  protected $moduleTemplate;
104 
108  protected $templateService;
109 
113  public function __construct()
114  {
115  $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
116  $this->getLanguageService()->includeLLFile('EXT:tstemplate/Resources/Private/Language/locallang.xlf');
117 
118  $this->MCONF = [
119  'name' => $this->moduleName
120  ];
121  $this->moduleTemplate->addJavaScriptCode(
122  'jumpToUrl',
123  '
124  function jumpToUrl(URL) {
125  window.location.href = URL;
126  return false;
127  }
128  '
129  );
130  }
131 
135  public function init()
136  {
137  parent::init();
138  $this->id = (int)GeneralUtility::_GP('id');
139  $this->e = GeneralUtility::_GP('e');
140  $this->sObj = GeneralUtility::_GP('sObj');
141  $this->edit = GeneralUtility::_GP('edit');
142  $this->perms_clause = $this->getBackendUser()->getPagePermsClause(1);
143  }
144 
148  public function clearCache()
149  {
150  if (GeneralUtility::_GP('clear_all_cache')) {
152  $tce = GeneralUtility::makeInstance(DataHandler::class);
153  $tce->start([], []);
154  $tce->clear_cacheCmd('all');
155  }
156  }
157 
161  public function main()
162  {
163  // Access check...
164  // The page will show only if there is a valid page and if this page may be viewed by the user
165  $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
166  $this->access = is_array($this->pageinfo);
167  $view = $this->getFluidTemplateObject('tstemplate');
168 
169  if ($this->id && $this->access) {
170  $urlParameters = [
171  'id' => $this->id,
172  'template' => 'all'
173  ];
174  $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters);
175 
176  // JavaScript
177  $this->moduleTemplate->addJavaScriptCode(
178  'TSTemplateInlineJS',
179  'function uFormUrl(aname) {
180  document.forms[0].action = ' . GeneralUtility::quoteJSvalue($aHref . '#') . '+aname;
181  }
182  function brPoint(lnumber,t) {
183  window.location.href = '
185  $aHref . '&SET[function]=TYPO3\\CMS\\Tstemplate\\Controller\\'
186  . 'TypoScriptTemplateObjectBrowserModuleFunctionController&SET[ts_browser_type]='
187  ) . '+(t?"setup":"const")+"&breakPointLN="+lnumber;
188  return false;
189  }
190  if (top.fsMod) top.fsMod.recentIds["web"] = ' . $this->id . ';'
191  );
192  $this->moduleTemplate->getPageRenderer()->addCssInlineBlock(
193  'TSTemplateInlineStyle',
194  'TABLE#typo3-objectBrowser { width: 100%; margin-bottom: 24px; }
195  TABLE#typo3-objectBrowser A { text-decoration: none; }
196  TABLE#typo3-objectBrowser .comment { color: maroon; font-weight: bold; }
197  .ts-typoscript { width: 100%; }
198  .tsob-search-submit {margin-left: 3px; margin-right: 3px;}
199  .tst-analyzer-options { margin:5px 0; }'
200  );
201  // Setting up the context sensitive menu:
202  $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
203  // Build the module content
204  $view->assign('actionName', $aHref);
205  $view->assign('typoscriptTemplateModuleContent', $this->getExtObjContent());
206  // Setting up the buttons and markers for docheader
207  $this->getButtons();
208  $this->generateMenu();
209  } else {
210  $workspaceId = $this->getBackendUser()->workspace;
211  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
212  ->getQueryBuilderForTable('sys_template');
213  $queryBuilder->getRestrictions()
214  ->removeAll()
215  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
217  $queryBuilder,
218  'sys_template',
219  $workspaceId
220  );
221  $result = $queryBuilder
222  ->select(
223  'sys_template.uid',
224  'sys_template.pid',
225  'sys_template.title',
226  'sys_template.sitetitle',
227  'sys_template.root',
228  'sys_template.hidden',
229  'sys_template.starttime',
230  'sys_template.endtime',
231  'sys_template.t3ver_oid',
232  'sys_template.t3ver_wsid',
233  'sys_template.t3ver_state',
234  'sys_template.t3ver_move_id'
235  )
236  ->from('sys_template')
237  ->join('sys_template', 'pages', 'pages', $queryBuilder->expr()->eq('pages.uid', $queryBuilder->quoteIdentifier('sys_template.pid')))
238  ->orderBy('sys_template.pid')
239  ->addOrderBy('sys_template.sorting')
240  ->execute();
241  $pArray = [];
242  while ($record = $result->fetch()) {
243  BackendUtility::workspaceOL('sys_template', $record, $workspaceId, true);
244  if (empty($record) || VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
245  continue;
246  }
247  $additionalFieldsForRootline = ['sorting', 'hidden', 'fe_group', 'starttime', 'endtime', 'shortcut', 'nav_hide', 'module', 'content_from_pid'];
248  $rootline = BackendUtility::BEgetRootLine($record['pid'], '', true, $additionalFieldsForRootline);
249  $this->setInPageArray($pArray, $rootline, $record);
250  }
251 
252  $view->getRenderingContext()->setControllerAction('PageZero');
253  $view->assign('pageTree', $pArray);
254 
255  // RENDER LIST of pages with templates, END
256  // Setting up the buttons and markers for docheader
257  $this->getButtons();
258  }
259  $this->content = $view->render();
260  }
261 
267  protected function generateMenu()
268  {
269  $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
270  $menu->setIdentifier('WebFuncJumpMenu');
271  foreach ($this->MOD_MENU['function'] as $controller => $title) {
272  $item = $menu
273  ->makeMenuItem()
274  ->setHref(
275  BackendUtility::getModuleUrl(
276  $this->moduleName,
277  [
278  'id' => $this->id,
279  'SET' => [
280  'function' => $controller
281  ]
282  ]
283  )
284  )
285  ->setTitle($title);
286  if ($controller === $this->MOD_SETTINGS['function']) {
287  $item->setActive(true);
288  }
289  $menu->addMenuItem($item);
290  }
291  $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
292  }
293 
302  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
303  {
304  $GLOBALS['SOBE'] = $this;
305  $this->init();
306 
307  // Checking for first level external objects
308  $this->checkExtObj();
309 
310  $this->clearCache();
311  $this->main();
312 
313  $this->moduleTemplate->setContent($this->content);
314  $response->getBody()->write($this->moduleTemplate->renderContent());
315  return $response;
316  }
317 
323  protected function getButtons()
324  {
325  $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
326  $lang = $this->getLanguageService();
327 
328  if ($this->id && $this->access) {
329  // View page
330  $viewButton = $buttonBar->makeLinkButton()
331  ->setHref('#')
332  ->setOnClick(BackendUtility::viewOnClick(
333  $this->pageinfo['uid'],
334  '',
335  BackendUtility::BEgetRootLine($this->pageinfo['uid'])
336  ))
337  ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.showPage'))
338  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-view', Icon::SIZE_SMALL));
339  $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 99);
340  if ($this->extClassConf['name'] === TypoScriptTemplateInformationModuleFunctionController::class) {
341  // NEW button
342  $urlParameters = [
343  'id' => $this->id,
344  'template' => 'all',
345  'createExtension' => 'new'
346  ];
347 
348  if (!empty($this->e) && !GeneralUtility::_POST('_saveandclosedok')) {
349  $saveButton = $buttonBar->makeInputButton()
350  ->setName('_savedok')
351  ->setValue('1')
352  ->setForm('TypoScriptTemplateModuleController')
353  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
354  'actions-document-save',
356  ))
357  ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'));
358 
359  $saveAndCloseButton = $buttonBar->makeInputButton()
360  ->setName('_saveandclosedok')
361  ->setValue('1')
362  ->setForm('TypoScriptTemplateModuleController')
363  ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveCloseDoc'))
364  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
365  'actions-document-save-close',
367  ));
368 
369  $splitButtonElement = $buttonBar->makeSplitButton()
370  ->addItem($saveButton)
371  ->addItem($saveAndCloseButton);
372 
373  $buttonBar->addButton($splitButtonElement, ButtonBar::BUTTON_POSITION_LEFT, 3);
374 
375  // CLOSE button
376  $closeButton = $buttonBar->makeLinkButton()
377  ->setHref(BackendUtility::getModuleUrl('web_ts', ['id' => $this->id]))
378  ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
379  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
380  'actions-close',
382  ));
383  $buttonBar->addButton($closeButton);
384  } else {
385  $newButton = $buttonBar->makeLinkButton()
386  ->setHref(BackendUtility::getModuleUrl('web_ts', $urlParameters))
387  ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:db_new.php.pagetitle'))
388  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
389  'actions-document-new',
391  ));
392  $buttonBar->addButton($newButton);
393  }
394  } elseif ($this->extClassConf['name'] === TypoScriptTemplateConstantEditorModuleFunctionController::class
395  && !empty($this->MOD_MENU['constant_editor_cat'])) {
396  // SAVE button
397  $saveButton = $buttonBar->makeInputButton()
398  ->setName('_savedok')
399  ->setValue('1')
400  ->setForm('TypoScriptTemplateModuleController')
401  ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'))
402  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
403  'actions-document-save',
405  ))
406  ->setShowLabelText(true);
407  $buttonBar->addButton($saveButton);
408  } elseif ($this->extClassConf['name'] === TypoScriptTemplateObjectBrowserModuleFunctionController::class) {
409  if (!empty($this->sObj)) {
410  // BACK
411  $urlParameters = [
412  'id' => $this->id
413  ];
414  $backButton = $buttonBar->makeLinkButton()
415  ->setHref(BackendUtility::getModuleUrl('web_ts', $urlParameters))
416  ->setClasses('typo3-goBack')
417  ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
418  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
419  'actions-view-go-back',
421  ));
422  $buttonBar->addButton($backButton);
423  }
424  }
425  }
426  // Shortcut
427  $shortcutButton = $buttonBar->makeShortcutButton()
428  ->setModuleName($this->MCONF['name'])
429  ->setGetVariables(['id', 'M']);
430  $buttonBar->addButton($shortcutButton);
431  }
432 
433  // OTHER FUNCTIONS:
441  public function linkWrapTemplateTitle($title, $onlyKey = '')
442  {
443  $urlParameters = [
444  'id' => $this->id
445  ];
446  $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters);
447  if ($onlyKey) {
448  $title = '<a href="' . htmlspecialchars(($aHref . '&e[' . $onlyKey . ']=1&SET[function]=TYPO3\\CMS\\Tstemplate\\Controller\\TypoScriptTemplateInformationModuleFunctionController')) . '">' . htmlspecialchars($title) . '</a>';
449  } else {
450  $title = '<a href="' . htmlspecialchars(($aHref . '&e[constants]=1&e[config]=1&SET[function]=TYPO3\\CMS\\Tstemplate\\Controller\\TypoScriptTemplateInformationModuleFunctionController')) . '">' . htmlspecialchars($title) . '</a>';
451  }
452  return $title;
453  }
454 
461  public function noTemplate($newStandardTemplate = 0)
462  {
463  $this->templateService = GeneralUtility::makeInstance(ExtendedTemplateService::class);
464  $this->templateService->init();
465 
466  $moduleContent['state'] = InfoboxViewHelper::STATE_INFO;
467 
468  // New standard?
469  if ($newStandardTemplate) {
470  $selector = '';
471  $staticsText = '';
472  // Hook to change output, implemented for statictemplates
473  $hookObject = $this->getHookObjectForAction('newStandardTemplateView');
474  if (!empty($hookObject)) {
475  $reference = [
476  'selectorHtml' => &$selector,
477  'staticsText' => &$staticsText
478  ];
480  $hookObject,
481  $reference,
482  $this
483  );
484  $selector = $reference['selectorHtml'];
485  $staticsText = $reference['staticsText'];
486  }
487  // Extension?
488  $moduleContent['staticsText'] = $staticsText;
489  $moduleContent['selector'] = $selector;
490  }
491  // Go to previous Page with Template...
492  $previousPage = $this->templateService->ext_prevPageWithTemplate($this->id, $this->perms_clause);
493  if ($previousPage) {
494  $urlParameters = [
495  'id' => $previousPage['uid']
496  ];
497  $previousPage['aHref'] = BackendUtility::getModuleUrl('web_ts', $urlParameters);
498  $moduleContent['previousPage'] = $previousPage;
499  }
500  $view = $this->getFluidTemplateObject('tstemplate', 'NoTemplate');
501  $view->assign('content', $moduleContent);
502  return $view->render();
503  }
504 
510  public function templateMenu()
511  {
512  $this->templateService = GeneralUtility::makeInstance(ExtendedTemplateService::class);
513  $this->templateService->init();
514 
515  $all = $this->templateService->ext_getAllTemplates($this->id);
516  if (count($all) > 1) {
517  $this->MOD_MENU['templatesOnPage'] = [];
518  foreach ($all as $d) {
519  $this->MOD_MENU['templatesOnPage'][$d['uid']] = $d['title'];
520  }
521  }
522  $this->MOD_SETTINGS = BackendUtility::getModuleData(
523  $this->MOD_MENU,
524  GeneralUtility::_GP('SET'),
525  $this->MCONF['name'],
526  $this->modMenu_type,
527  $this->modMenu_dontValidateList,
528  $this->modMenu_setDefaultList
529  );
531  $this->id,
532  'SET[templatesOnPage]',
533  $this->MOD_SETTINGS['templatesOnPage'],
534  $this->MOD_MENU['templatesOnPage']
535  );
536  }
537 
545  public function createTemplate($id, $actTemplateId = 0)
546  {
547  $recData = [];
549  $tce = GeneralUtility::makeInstance(DataHandler::class);
550 
551  if (GeneralUtility::_GP('createExtension')) {
552  $recData['sys_template']['NEW'] = [
553  'pid' => $actTemplateId ? -1 * $actTemplateId : $id,
554  'title' => '+ext'
555  ];
556  $tce->start($recData, []);
557  $tce->process_datamap();
558  } elseif (GeneralUtility::_GP('newWebsite')) {
559  // Hook to handle row data, implemented for statictemplates
560  $hookObject = $this->getHookObjectForAction('newStandardTemplateHandler');
561  if (!empty($hookObject)) {
562  $reference = [
563  'recData' => &$recData,
564  'id' => $id,
565  ];
567  $hookObject,
568  $reference,
569  $this
570  );
571  $recData = $reference['recData'];
572  } else {
573  $recData['sys_template']['NEW'] = [
574  'pid' => $id,
575  'title' => $this->getLanguageService()->getLL('titleNewSite'),
576  'sorting' => 0,
577  'root' => 1,
578  'clear' => 3,
579  'config' => '
580 # Default PAGE object:
581 page = PAGE
582 page.10 = TEXT
583 page.10.value = HELLO WORLD!
584 '
585  ];
586  }
587  $tce->start($recData, []);
588  $tce->process_datamap();
589  $tce->clear_cacheCmd('all');
590  }
591  return $tce->substNEWwithIDs['NEW'];
592  }
593 
602  public function setInPageArray(&$pArray, $rlArr, $row)
603  {
604  ksort($rlArr);
605  reset($rlArr);
606  if (!$rlArr[0]['uid']) {
607  array_shift($rlArr);
608  }
609  $cEl = current($rlArr);
610  if (empty($pArray[$cEl['uid']])) {
611  $pArray[$cEl['uid']] = $cEl;
612  }
613  array_shift($rlArr);
614  $pArray[$cEl['uid']]['_linkModul'] = GeneralUtility::linkThisScript(['id' => (int)$cEl['uid']]);
615  $pArray[$cEl['uid']]['_icon'] = $this->moduleTemplate->getIconFactory()
616  ->getIconForRecord(
617  'pages',
618  BackendUtility::getRecordWSOL('pages', $cEl['uid']),
620  )->render();
621  if (!empty($rlArr)) {
622  if (empty($pArray[$cEl['uid']]['_nodes'])) {
623  $pArray[$cEl['uid']]['_nodes'] = [];
624  }
625  $this->setInPageArray($pArray[$cEl['uid']]['_nodes'], $rlArr, $row);
626  } else {
627  $row['_linkModul'] = GeneralUtility::linkThisScript(['id' => (int)$cEl['uid'], 'SET[templatesOnPage]' => $row['uid']]);
628  $pArray[$cEl['uid']]['_templates'][] = $row;
629  }
630  uasort($pArray, function ($a, $b) {
631  return $a['sorting'] - $b['sorting'];
632  });
633  }
634 
643  public function renderList($pArray, $lines = [], $c = 0)
644  {
645  if (!is_array($pArray)) {
646  return $lines;
647  }
648 
649  $statusCheckedIcon = $this->moduleTemplate->getIconFactory()
650  ->getIcon('status-status-checked', Icon::SIZE_SMALL)->render();
651  $i = 0;
652  foreach ($pArray as $k => $v) {
654  $line = [];
655  $key = $k . '_';
656  $line['marginLeft'] = $c * 20;
657  $line['class'] = ($i++ % 2 === 0 ? 'bgColor4' : 'bgColor6');
658  $line['pageTitle'] = GeneralUtility::fixed_lgd_cs($pArray[$k], 30);
659  $line['icon'] = $this->moduleTemplate->getIconFactory()
660  ->getIconForRecord(
661  'pages',
662  BackendUtility::getRecordWSOL('pages', $k),
664  )->render();
665  if (!empty($pArray[$key])) {
666  $line['href'] = GeneralUtility::linkThisScript(['id' => (int)$k]);
667  $line['title'] = 'ID: ' . (int)$k;
668  $line['count'] = $pArray[$k . '_']['count'];
669  $line['root_max_val'] = ($pArray[$key]['root_max_val'] > 0 ? $statusCheckedIcon : '&nbsp;');
670  $line['root_min_val'] = ($pArray[$key]['root_min_val'] === 0 ? $statusCheckedIcon : '&nbsp;');
671  } else {
672  $line['href'] = '';
673  $line['title'] = '';
674  $line['count'] = '';
675  $line['root_max_val'] = '';
676  $line['root_min_val'] = '';
677  }
678  $lines[] = $line;
679  $lines = $this->renderList($pArray[$k . '.'], $lines, $c + 1);
680  }
681  }
682  return $lines;
683  }
684 
692  protected function getFluidTemplateObject($extensionName, $templateName = 'Main')
693  {
695  $view = GeneralUtility::makeInstance(StandaloneView::class);
696  $view->getRenderingContext()->getTemplatePaths()->fillDefaultsByPackageName($extensionName);
697  $view->getRenderingContext()->setControllerAction($templateName);
698  $view->getRequest()->setControllerExtensionName('tstemplate');
699  return $view;
700  }
701 
707  protected function applyWorkspaceConstraint(
708  QueryBuilder $queryBuilder,
709  string $tableName,
710  int $workspaceId
711  ) {
712  if (empty($GLOBALS['TCA'][$tableName]['ctrl']['versioningWS'])) {
713  return;
714  }
715 
716  $workspaceIds = [0];
717  if ($workspaceId > 0) {
718  $workspaceIds[] = $workspaceId;
719  }
720  $queryBuilder->andWhere(
721  $queryBuilder->expr()->in(
722  $tableName . '.t3ver_wsid',
723  $queryBuilder->createNamedParameter($workspaceIds, Connection::PARAM_INT_ARRAY)
724  ),
725  $queryBuilder->expr()->neq(
726  $tableName . '.pid',
727  $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
728  )
729  );
730  }
731 
736  protected function getHookObjectForAction($action)
737  {
738  if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class][$action])) {
739  return $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class][$action];
740  }
741  return null;
742  }
743 }
static getRecordWSOL( $table, $uid, $fields=' *', $where='', $useDeleteClause=true, $unsetMovePointers=false)
static readPageAccess($id, $perms_clause)
applyWorkspaceConstraint(QueryBuilder $queryBuilder, string $tableName, int $workspaceId)
mainAction(ServerRequestInterface $request, ResponseInterface $response)
static callUserFunction($funcName, &$params, &$ref, $_='', $errorMode=0)
static getModuleData( $MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')
createNamedParameter($value, int $type=\PDO::PARAM_STR, string $placeHolder=null)
static viewOnClick( $pageUid, $backPath='', $rootLine=null, $anchorSection='', $alternativeUrl='', $additionalGetVars='', $switchFocus=true)
static BEgetRootLine($uid, $clause='', $workspaceOL=false)
static workspaceOL($table, &$row, $wsid=-99, $unsetMovePointers=false)
static linkThisScript(array $getParams=[])
static makeInstance($className,... $constructorArguments)
static fixed_lgd_cs($string, $chars, $appendString='...')
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static getFuncMenu( $mainParams, $elementName, $currentValue, $menuItems, $script='', $addParams='')