TYPO3 CMS  TYPO3_7-6
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 
32 
39 {
43  public $perms_clause;
44 
48  public $e;
49 
53  public $sObj;
54 
58  public $edit;
59 
63  public $textExtensions = 'html,htm,txt,css,tmpl,inc,js';
64 
68  public $modMenu_type = '';
69 
74 
79 
83  public $pageinfo = [];
84 
88  public $access = false;
89 
95  protected $moduleName = 'web_ts';
96 
102  protected $moduleTemplate;
103 
107  public function __construct()
108  {
109  $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
110  $this->getLanguageService()->includeLLFile('EXT:tstemplate/Resources/Private/Language/locallang.xlf');
111 
112  $this->MCONF = [
113  'name' => $this->moduleName
114  ];
115  $this->moduleTemplate->addJavaScriptCode(
116  'jumpToUrl',
117  '
118  function jumpToUrl(URL) {
119  window.location.href = URL;
120  return false;
121  }
122  '
123  );
124  }
125 
131  public function init()
132  {
133  parent::init();
134  $this->id = (int)GeneralUtility::_GP('id');
135  $this->e = GeneralUtility::_GP('e');
136  $this->sObj = GeneralUtility::_GP('sObj');
137  $this->edit = GeneralUtility::_GP('edit');
138  $this->perms_clause = $this->getBackendUser()->getPagePermsClause(1);
139  }
140 
146  public function clearCache()
147  {
148  if (GeneralUtility::_GP('clear_all_cache')) {
150  $tce = GeneralUtility::makeInstance(DataHandler::class);
151  $tce->stripslashes_values = false;
152  $tce->start([], []);
153  $tce->clear_cacheCmd('all');
154  }
155  }
156 
162  public function main()
163  {
164  // Template markers
165  $markers = [
166  'CSH' => '',
167  'FUNC_MENU' => '',
168  'CONTENT' => ''
169  ];
170 
171  // Access check...
172  // The page will show only if there is a valid page and if this page may be viewed by the user
173  $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
174  $this->access = is_array($this->pageinfo);
175 
177  $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
178  $this->moduleTemplate->getPageRenderer()->addCssFile(ExtensionManagementUtility::extRelPath('tstemplate') . 'Resources/Public/Css/styles.css');
179 
180  $lang = $this->getLanguageService();
181 
182  if ($this->id && $this->access) {
183  $urlParameters = [
184  'id' => $this->id,
185  'template' => 'all'
186  ];
187  $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters);
188 
189  // JavaScript
190  $this->moduleTemplate->addJavaScriptCode(
191  'TSTemplateInlineJS', '
192  function uFormUrl(aname) {
193  document.forms[0].action = ' . GeneralUtility::quoteJSvalue(($aHref . '#')) . '+aname;
194  }
195  function brPoint(lnumber,t) {
196  window.location.href = ' . GeneralUtility::quoteJSvalue(($aHref . '&SET[function]=TYPO3\\CMS\\Tstemplate\\Controller\\TypoScriptTemplateObjectBrowserModuleFunctionController&SET[ts_browser_type]=')) . '+(t?"setup":"const")+"&breakPointLN="+lnumber;
197  return false;
198  }
199  if (top.fsMod) top.fsMod.recentIds["web"] = ' . $this->id . ';
200  ');
201  $this->moduleTemplate->getPageRenderer()->addCssInlineBlock(
202  'TSTemplateInlineStyle', '
203  TABLE#typo3-objectBrowser { width: 100%; margin-bottom: 24px; }
204  TABLE#typo3-objectBrowser A { text-decoration: none; }
205  TABLE#typo3-objectBrowser .comment { color: maroon; font-weight: bold; }
206  .ts-typoscript { width: 100%; }
207  .tsob-search-submit {margin-left: 3px; margin-right: 3px;}
208  .tst-analyzer-options { margin:5px 0; }
209  ');
210  // Setting up the context sensitive menu:
211  $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ClickMenu');
212  // Build the module content
213  $this->content = '<form action="' . htmlspecialchars($aHref) . '" method="post" enctype="multipart/form-data" id="TypoScriptTemplateModuleController" name="editForm" class="form">';
214  $this->content .= $this->doc->header($lang->getLL('moduleTitle'));
215  $this->extObjContent();
216  // Setting up the buttons and markers for docheader
217  $this->getButtons();
218  $this->generateMenu();
219  $this->content .= '</form>';
220  } else {
221  // Template pages:
222  $records = $this->getDatabaseConnection()->exec_SELECTgetRows(
223  'pages.uid, count(*) AS count, max(sys_template.root) AS root_max_val, min(sys_template.root) AS root_min_val',
224  'pages,sys_template',
225  'pages.uid=sys_template.pid'
228  . BackendUtility::deleteClause('sys_template')
230  'pages.uid',
231  'pages.pid, pages.sorting'
232  );
233  $pArray = [];
234  foreach ($records as $record) {
235  $this->setInPageArray($pArray, BackendUtility::BEgetRootLine($record['uid'], 'AND 1=1'), $record);
236  }
237 
238  $table = '<div class="table-fit"><table class="table table-striped table-hover" id="ts-overview">' .
239  '<thead>' .
240  '<tr>' .
241  '<th>' . $lang->getLL('pageName') . '</th>' .
242  '<th>' . $lang->getLL('templates') . '</th>' .
243  '<th>' . $lang->getLL('isRoot') . '</th>' .
244  '<th>' . $lang->getLL('isExt') . '</th>' .
245  '</tr>' .
246  '</thead>' .
247  '<tbody>' . implode('', $this->renderList($pArray)) . '</tbody>' .
248  '</table></div>';
249 
250  $this->content = $this->doc->header($lang->getLL('moduleTitle'));
251  $this->content .= '<div><p class="lead">' . $lang->getLL('overview') . '</p>' . $table . '</div>';
252 
253  // RENDER LIST of pages with templates, END
254  // Setting up the buttons and markers for docheader
255  $this->getButtons();
256  }
257  }
258 
265  protected function generateMenu()
266  {
267  $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
268  $menu->setIdentifier('WebFuncJumpMenu');
269  foreach ($this->MOD_MENU['function'] as $controller => $title) {
270  $item = $menu
271  ->makeMenuItem()
272  ->setHref(
273  BackendUtility::getModuleUrl(
274  $this->moduleName,
275  [
276  'id' => $this->id,
277  'SET' => [
278  'function' => $controller
279  ]
280  ]
281  )
282  )
283  ->setTitle($title);
284  if ($controller === $this->MOD_SETTINGS['function']) {
285  $item->setActive(true);
286  }
287  $menu->addMenuItem($item);
288  }
289  $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
290  }
291 
300  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
301  {
302  $GLOBALS['SOBE'] = $this;
303  $this->init();
304 
305  // Checking for first level external objects
306  $this->checkExtObj();
307 
308  $this->clearCache();
309  $this->main();
310 
311  $this->moduleTemplate->setContent($this->content);
312  $response->getBody()->write($this->moduleTemplate->renderContent());
313  return $response;
314  }
315 
322  public function printContent()
323  {
325  echo $this->content;
326  }
327 
333  protected function getButtons()
334  {
335  $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
336  $lang = $this->getLanguageService();
337 
338  if ($this->id && $this->access) {
339  // View page
340  $viewButton = $buttonBar->makeLinkButton()
341  ->setHref('#')
342  ->setOnClick(BackendUtility::viewOnClick($this->pageinfo['uid'], '', BackendUtility::BEgetRootLine($this->pageinfo['uid'])))
343  ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage'))
344  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-view', Icon::SIZE_SMALL));
345  $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 99);
346  if ($this->extClassConf['name'] === TypoScriptTemplateInformationModuleFunctionController::class) {
347  // NEW button
348  $urlParameters = [
349  'id' => $this->id,
350  'template' => 'all',
351  'createExtension' => 'new'
352  ];
353 
354  if (!empty($this->e) && !GeneralUtility::_POST('_saveandclosedok')) {
355  $saveButton = $buttonBar->makeInputButton()
356  ->setName('_savedok')
357  ->setValue('1')
358  ->setForm('TypoScriptTemplateModuleController')
359  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL))
360  ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc'));
361 
362  $saveAndCloseButton = $buttonBar->makeInputButton()
363  ->setName('_saveandclosedok')
364  ->setValue('1')
365  ->setForm('TypoScriptTemplateModuleController')
366  ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc'))
367  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL));
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/locallang_core.xlf:rm.closeDoc'))
379  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL));
380  $buttonBar->addButton($closeButton);
381  } else {
382  $newButton = $buttonBar->makeLinkButton()
383  ->setHref(BackendUtility::getModuleUrl('web_ts', $urlParameters))
384  ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:db_new.php.pagetitle'))
385  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-new', Icon::SIZE_SMALL));
386  $buttonBar->addButton($newButton);
387  }
388  } elseif ($this->extClassConf['name'] === TypoScriptTemplateConstantEditorModuleFunctionController::class && !empty($this->MOD_MENU['constant_editor_cat'])) {
389  // SAVE button
390  $saveButton = $buttonBar->makeInputButton()
391  ->setName('_savedok')
392  ->setValue('1')
393  ->setForm('TypoScriptTemplateModuleController')
394  ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc'))
395  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL))
396  ->setShowLabelText(true);
397  $buttonBar->addButton($saveButton);
398  } elseif ($this->extClassConf['name'] === TypoScriptTemplateObjectBrowserModuleFunctionController::class) {
399  if (!empty($this->sObj)) {
400  // BACK
401  $urlParameters = [
402  'id' => $this->id
403  ];
404  $backButton = $buttonBar->makeLinkButton()
405  ->setHref(BackendUtility::getModuleUrl('web_ts', $urlParameters))
406  ->setClasses('typo3-goBack')
407  ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.goBack'))
408  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
409  $buttonBar->addButton($backButton);
410  }
411  }
412  }
413  // Shortcut
414  $shortcutButton = $buttonBar->makeShortcutButton()
415  ->setModuleName($this->MCONF['name'])
416  ->setGetVariables(['id', 'M']);
417  $buttonBar->addButton($shortcutButton);
418  }
419 
420  // OTHER FUNCTIONS:
428  public function linkWrapTemplateTitle($title, $onlyKey = '')
429  {
430  $urlParameters = [
431  'id' => $this->id
432  ];
433  $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters);
434  if ($onlyKey) {
435  $title = '<a href="' . htmlspecialchars(($aHref . '&e[' . $onlyKey . ']=1&SET[function]=TYPO3\\CMS\\Tstemplate\\Controller\\TypoScriptTemplateInformationModuleFunctionController')) . '">' . htmlspecialchars($title) . '</a>';
436  } else {
437  $title = '<a href="' . htmlspecialchars(($aHref . '&e[constants]=1&e[config]=1&SET[function]=TYPO3\\CMS\\Tstemplate\\Controller\\TypoScriptTemplateInformationModuleFunctionController')) . '">' . htmlspecialchars($title) . '</a>';
438  }
439  return $title;
440  }
441 
448  public function noTemplate($newStandardTemplate = 0)
449  {
450  // Defined global here!
452  $tmpl = GeneralUtility::makeInstance(ExtendedTemplateService::class);
453  $GLOBALS['tmpl'] = $tmpl;
454 
455  // Do not log time-performance information
456  $tmpl->tt_track = false;
457  $tmpl->init();
458 
459  $lang = $this->getLanguageService();
460 
461  $title = $lang->getLL('noTemplate');
462  $message = '<p>' . $lang->getLL('noTemplateDescription') . '<br />' . $lang->getLL('createTemplateToEditConfiguration') . '</p>';
463 
464  $view = GeneralUtility::makeInstance(StandaloneView::class);
465  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:tstemplate/Resources/Private/Templates/InfoBox.html'));
466  $view->assignMultiple([
467  'title' => $title,
468  'message' => $message,
470  ]);
471  $theOutput = $view->render();
472 
473  // New standard?
474  if ($newStandardTemplate) {
475  // Hook to change output, implemented for statictemplates
476  if (isset(
477  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class]['newStandardTemplateView']
478  )) {
479  $selector = '';
480  $staticsText = '';
481  $reference = [
482  'selectorHtml' => &$selector,
483  'staticsText' => &$staticsText
484  ];
486  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class]['newStandardTemplateView'],
487  $reference,
488  $this
489  );
490  $selector = $reference['selectorHtml'];
491  $staticsText = $reference['staticsText'];
492  } else {
493  $selector = '<input type="hidden" name="createStandard" value="" />';
494  $staticsText = '';
495  }
496  // Extension?
497  $theOutput .= '<h2>' . $lang->getLL('newWebsite', true) . $staticsText . '</h2>';
498  $theOutput .= '<div><p>' . $lang->getLL('newWebsiteDescription') . '</p>' . $selector
499  . '<input class="btn btn-primary" type="submit" form="TypoScriptTemplateModuleController" name="newWebsite" value="'
500  . $lang->getLL('newWebsiteAction') . '" /></div>';
501  }
502  // Extension?
503  $theOutput .= '<h2>' . $lang->getLL('extTemplate') . '</h2>';
504  $theOutput .= '<div><p>' . $lang->getLL('extTemplateDescription') . '</p>' . '<input class="btn btn-default" type="submit" form="TypoScriptTemplateModuleController" name="createExtension" value="' . $lang->getLL('extTemplateAction') . '" /></div>';
505 
506  // Go to first appearing...
507  $first = $tmpl->ext_prevPageWithTemplate($this->id, $this->perms_clause);
508  if ($first) {
509  $urlParameters = [
510  'id' => $first['uid']
511  ];
512  $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters);
513  $theOutput .= '<h3>' . $lang->getLL('goToClosest') . '</h3>';
514  $theOutput .= '<div>' . sprintf('<p>' . $lang->getLL('goToClosestDescription') . '</p>%s' . $lang->getLL('goToClosestAction') . '%s', htmlspecialchars($first['title']), $first['uid'], '<a class="btn btn-default" href="' . htmlspecialchars($aHref) . '">', '</a>') . '</div>';
515  }
516  return $theOutput;
517  }
518 
524  public function templateMenu()
525  {
527  $tmpl = GeneralUtility::makeInstance(ExtendedTemplateService::class);
528  $GLOBALS['tmpl'] = $tmpl;
529 
530  // Do not log time-performance information
531  $tmpl->tt_track = false;
532  $tmpl->init();
533 
534  $all = $tmpl->ext_getAllTemplates($this->id, $this->perms_clause);
535  if (count($all) > 1) {
536  $this->MOD_MENU['templatesOnPage'] = [];
537  foreach ($all as $d) {
538  $this->MOD_MENU['templatesOnPage'][$d['uid']] = $d['title'];
539  }
540  }
541  $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), $this->MCONF['name'], $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList);
542  return BackendUtility::getFuncMenu($this->id, 'SET[templatesOnPage]', $this->MOD_SETTINGS['templatesOnPage'], $this->MOD_MENU['templatesOnPage']);
543  }
544 
552  public function createTemplate($id, $actTemplateId = 0)
553  {
554  $recData = [];
556  $tce = GeneralUtility::makeInstance(DataHandler::class);
557  $tce->stripslashes_values = false;
558 
559  if (GeneralUtility::_GP('createExtension')) {
560  $recData['sys_template']['NEW'] = [
561  'pid' => $actTemplateId ? -1 * $actTemplateId : $id,
562  'title' => '+ext'
563  ];
564  $tce->start($recData, []);
565  $tce->process_datamap();
566  } elseif (GeneralUtility::_GP('newWebsite')) {
567  // Hook to handle row data, implemented for statictemplates
568  if (isset(
569  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class]['newStandardTemplateHandler']
570  )) {
571  $reference = [
572  'recData' => &$recData,
573  'id' => $id,
574  ];
576  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class]['newStandardTemplateHandler'],
577  $reference,
578  $this
579  );
580  $recData = $reference['recData'];
581  } else {
582  $recData['sys_template']['NEW'] = [
583  'pid' => $id,
584  'title' => $this->getLanguageService()->getLL('titleNewSite'),
585  'sorting' => 0,
586  'root' => 1,
587  'clear' => 3,
588  'config' => '
589 # Default PAGE object:
590 page = PAGE
591 page.10 = TEXT
592 page.10.value = HELLO WORLD!
593 '
594  ];
595  }
596  $tce->start($recData, []);
597  $tce->process_datamap();
598  $tce->clear_cacheCmd('all');
599  }
600  return $tce->substNEWwithIDs['NEW'];
601  }
602 
603  // RENDER LIST of pages with templates, BEGIN
612  public function setInPageArray(&$pArray, $rlArr, $row)
613  {
614  ksort($rlArr);
615  reset($rlArr);
616  if (!$rlArr[0]['uid']) {
617  array_shift($rlArr);
618  }
619  $cEl = current($rlArr);
620  $pArray[$cEl['uid']] = htmlspecialchars($cEl['title']);
621  array_shift($rlArr);
622  if (!empty($rlArr)) {
623  if (!isset($pArray[$cEl['uid'] . '.'])) {
624  $pArray[$cEl['uid'] . '.'] = [];
625  }
626  $this->setInPageArray($pArray[$cEl['uid'] . '.'], $rlArr, $row);
627  } else {
628  $pArray[$cEl['uid'] . '_'] = $row;
629  }
630  }
631 
640  public function renderList($pArray, $lines = [], $c = 0)
641  {
642  static $i;
643 
644  if (!is_array($pArray)) {
645  return $lines;
646  }
647 
648  $statusCheckedIcon = $this->moduleTemplate->getIconFactory()->getIcon('status-status-checked', Icon::SIZE_SMALL)->render();
649  foreach ($pArray as $k => $v) {
651  if (isset($pArray[$k . '_'])) {
652  $lines[] = '<tr class="' . ($i++ % 2 == 0 ? 'bgColor4' : 'bgColor6') . '">
653  <td nowrap><span style="width: 1px; height: 1px; display:inline-block; margin-left: ' . $c * 20 . 'px"></span>' . '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(['id' => $k])) . '" title="' . htmlspecialchars('ID: ' . $k) . '">' . $this->moduleTemplate->getIconFactory()->getIconForRecord('pages', BackendUtility::getRecordWSOL('pages', $k), Icon::SIZE_SMALL)->render() . GeneralUtility::fixed_lgd_cs($pArray[$k], 30) . '</a></td>
654  <td>' . $pArray[$k . '_']['count'] . '</td>
655  <td>' . ($pArray[$k . '_']['root_max_val'] > 0 ? $statusCheckedIcon : '&nbsp;') . '</td>
656  <td>' . ($pArray[$k . '_']['root_min_val'] == 0 ? $statusCheckedIcon : '&nbsp;') . '</td>
657  </tr>';
658  } else {
659  $lines[] = '<tr class="' . ($i++ % 2 == 0 ? 'bgColor4' : 'bgColor6') . '">
660  <td nowrap><span style="width: 1px; height: 1px; display:inline-block; margin-left: ' . $c * 20 . 'px"></span>' . $this->moduleTemplate->getIconFactory()->getIconForRecord('pages', BackendUtility::getRecordWSOL('pages', $k), Icon::SIZE_SMALL)->render() . GeneralUtility::fixed_lgd_cs($pArray[$k], 30) . '</td>
661  <td></td>
662  <td></td>
663  <td></td>
664  </tr>';
665  }
666  $lines = $this->renderList($pArray[$k . '.'], $lines, $c + 1);
667  }
668  }
669  return $lines;
670  }
671 }
static readPageAccess($id, $perms_clause)
mainAction(ServerRequestInterface $request, ResponseInterface $response)
static BEgetRootLine($uid, $clause='', $workspaceOL=false)
static linkThisScript(array $getParams=[])
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
static getModuleData($MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')
static getFuncMenu($mainParams, $elementName, $currentValue, $menuItems, $script='', $addParams='')
static viewOnClick($pageUid, $backPath='', $rootLine=null, $anchorSection='', $alternativeUrl='', $additionalGetVars='', $switchFocus=true)
static fixed_lgd_cs($string, $chars, $appendString='...')
static getFileAbsFileName($filename, $onlyRelative=true, $relToTYPO3_mainDir=false)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static getRecordWSOL($table, $uid, $fields=' *', $where='', $useDeleteClause=true, $unsetMovePointers=false)
static deleteClause($table, $tableAlias='')