TYPO3 CMS  TYPO3_7-6
TypoScriptTemplateInformationModuleFunctionController.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 
27 
32 {
38  public $tce_processed = false;
39 
43  public $pObj;
44 
48  protected $iconFactory;
49 
53  public function __construct()
54  {
55  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
56  }
57 
67  public function tableRow($label, $data, $field, $id)
68  {
69  $lang = $this->getLanguageService();
70  if ($field === 'config' || $field === 'constants') {
71  $urlParameters = [
72  'id' => $this->pObj->id,
73  'e' => [
74  $field => 1
75  ]
76  ];
77  $url = BackendUtility::getModuleUrl('web_ts', $urlParameters);
78  } else {
79  $urlParameters = [
80  'edit' => [
81  'sys_template' => [
82  $id => 'edit'
83  ]
84  ],
85  'columnsOnly' => $field,
86  'createExtension' => 0,
87  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
88  ];
89  $url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
90  }
91  $title = $lang->sL('LLL:EXT:lang/locallang_common.xlf:editField', true);
92  $startAnchor = '<a href="' . htmlspecialchars($url) . '" title="' . $title . '">';
93  $icon = $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render();
94  $ret = '<tr><td>';
95  $ret .= $startAnchor . '<strong>' . $label . '</strong></a>';
96  $ret .= '</td><td width="80%">' . $data . '</td><td>' . $startAnchor . '<span class="btn btn-default">' . $icon . '</span></a></td></tr>';
97  return $ret;
98  }
99 
111  public function initialize_editor($pageId, $template_uid = 0)
112  {
114  $tmpl = GeneralUtility::makeInstance(ExtendedTemplateService::class);
115  $GLOBALS['tmpl'] = $tmpl;
116 
117  // Do not log time-performance information
118  $tmpl->tt_track = false;
119  $tmpl->init();
120 
121  // Get the row of the first VISIBLE template of the page. where clause like the frontend.
122  $GLOBALS['tplRow'] = $tmpl->ext_getFirstTemplate($pageId, $template_uid);
123  if (is_array($GLOBALS['tplRow'])) {
124  $GLOBALS['tplRow'] = $this->processTemplateRowAfterLoading($GLOBALS['tplRow']);
125  return true;
126  }
127  return false;
128  }
129 
136  public function processTemplateRowAfterLoading(array $tplRow)
137  {
138  if ($this->pObj->MOD_SETTINGS['includeTypoScriptFileContent']) {
139  // Let the recursion detection counter start at 91, so that only 10 recursive calls will be resolved
140  // Otherwise the editor will be bloated with way to many lines making it hard the break the cyclic recursion.
141  $tplRow['config'] = TypoScriptParser::checkIncludeLines($tplRow['config'], 91);
142  $tplRow['constants'] = TypoScriptParser::checkIncludeLines($tplRow['constants'], 91);
143  }
144  return $tplRow;
145  }
146 
153  public function processTemplateRowBeforeSaving(array $tplRow)
154  {
155  if ($this->pObj->MOD_SETTINGS['includeTypoScriptFileContent']) {
156  $tplRow = TypoScriptParser::extractIncludes_array($tplRow);
157  }
158  return $tplRow;
159  }
160 
164  protected function getLanguageService()
165  {
166  return $GLOBALS['LANG'];
167  }
168 
174  public function main()
175  {
176  $lang = $this->getLanguageService();
177  $lang->includeLLFile('EXT:tstemplate/Resources/Private/Language/locallang_info.xlf');
178  $this->pObj->MOD_MENU['includeTypoScriptFileContent'] = true;
179  $e = $this->pObj->e;
180  // Checking for more than one template an if, set a menu...
181  $manyTemplatesMenu = $this->pObj->templateMenu();
182  $template_uid = 0;
183  if ($manyTemplatesMenu) {
184  $template_uid = $this->pObj->MOD_SETTINGS['templatesOnPage'];
185  }
186  // Initialize
187  $existTemplate = $this->initialize_editor($this->pObj->id, $template_uid);
188  $tplRow = $GLOBALS['tplRow'];
189  $saveId = 0;
190  if ($existTemplate) {
191  $saveId = $tplRow['_ORIG_uid'] ? $tplRow['_ORIG_uid'] : $tplRow['uid'];
192  }
193  // Create extension template
194  $newId = $this->pObj->createTemplate($this->pObj->id, $saveId);
195  if ($newId) {
196  // Switch to new template
197  $urlParameters = [
198  'id' => $this->pObj->id,
199  'SET[templatesOnPage]' => $newId
200  ];
201  $url = BackendUtility::getModuleUrl('web_ts', $urlParameters);
202  HttpUtility::redirect($url);
203  }
204  $tce = null;
205  $theOutput = '';
206  if ($existTemplate) {
207  // Update template ?
208  $POST = GeneralUtility::_POST();
209  if (
210  isset($POST['_savedok'])
211  || isset($POST['_saveandclosedok'])
212  ) {
213  // Set the data to be saved
214  $recData = [];
215  $alternativeFileName = [];
216  if (is_array($POST['data'])) {
217  foreach ($POST['data'] as $field => $val) {
218  switch ($field) {
219  case 'constants':
220  case 'config':
221  $recData['sys_template'][$saveId][$field] = $val;
222  break;
223  }
224  }
225  }
226  if (!empty($recData)) {
227  $recData['sys_template'][$saveId] = $this->processTemplateRowBeforeSaving($recData['sys_template'][$saveId]);
228  // Create new tce-object
229  $tce = GeneralUtility::makeInstance(DataHandler::class);
230  $tce->stripslashes_values = false;
231  $tce->alternativeFileName = $alternativeFileName;
232  // Initialize
233  $tce->start($recData, []);
234  // Saved the stuff
235  $tce->process_datamap();
236  // Clear the cache (note: currently only admin-users can clear the cache in tce_main.php)
237  $tce->clear_cacheCmd('all');
238  // tce were processed successfully
239  $this->tce_processed = true;
240  // re-read the template ...
241  $this->initialize_editor($this->pObj->id, $template_uid);
242  $tplRow = $GLOBALS['tplRow'];
243  // reload template menu
244  $manyTemplatesMenu = $this->pObj->templateMenu();
245  }
246  }
247  // Hook post updating template/TCE processing
248  if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postTCEProcessingHook'])) {
249  $postTCEProcessingHook = &$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postTCEProcessingHook'];
250  if (is_array($postTCEProcessingHook)) {
251  $hookParameters = [
252  'POST' => $POST,
253  'tce' => $tce
254  ];
255  foreach ($postTCEProcessingHook as $hookFunction) {
256  GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
257  }
258  }
259  }
260  $content = '<a href="#" class="t3-js-clickmenutrigger" data-table="sys_template" data-uid="' . $tplRow['uid'] . '" data-listframe="1">' . $this->iconFactory->getIconForRecord('sys_template', $tplRow, Icon::SIZE_SMALL)->render() . '</a><strong>' . htmlspecialchars($tplRow['title']) . '</strong>' . (trim($tplRow['sitetitle']) ? htmlspecialchars(' (' . $tplRow['sitetitle'] . ')') : '');
261  $theOutput .= '<h2>' . $lang->getLL('templateInformation', true) . '</h2><div>' . $content . '</div>';
262  if ($manyTemplatesMenu) {
263  $theOutput .= '<div>' . $manyTemplatesMenu . '</div>';
264  }
265  $theOutput .= '<div style="padding-top: 10px;"></div>';
266  $numberOfRows = 35;
267  // If abort pressed, nothing should be edited:
268  if (isset($POST['_saveandclosedok'])) {
269  unset($e);
270  }
271  if (isset($e['constants'])) {
272  $outCode = '<textarea name="data[constants]" rows="' . $numberOfRows . '" wrap="off" class="text-monospace enable-tab"' . $this->pObj->doc->formWidth(48, true, 'width:98%;height:70%') . ' class="text-monospace">' . htmlspecialchars($tplRow['constants']) . '</textarea>';
273  $outCode .= '<input type="hidden" name="e[constants]" value="1">';
274  // Display "Include TypoScript file content?" checkbox
275  $outCode .= '<div class="checkbox"><label for="checkIncludeTypoScriptFileContent">' . BackendUtility::getFuncCheck($this->pObj->id, 'SET[includeTypoScriptFileContent]', $this->pObj->MOD_SETTINGS['includeTypoScriptFileContent'], '', '&e[constants]=1', 'id="checkIncludeTypoScriptFileContent"');
276  $outCode .= $lang->getLL('includeTypoScriptFileContent') . '</label></div><br />';
277  $theOutput .= '<div style="padding-top: 15px;"></div>';
278  $theOutput .= '<h3>' . $lang->getLL('constants', true) . '</h3>';
279  $theOutput .= $outCode;
280  }
281  if (isset($e['config'])) {
282  $outCode = '<textarea name="data[config]" rows="' . $numberOfRows . '" wrap="off" class="text-monospace enable-tab"' . $this->pObj->doc->formWidth(48, true, 'width:98%;height:70%') . ' class="text-monospace">' . htmlspecialchars($tplRow['config']) . '</textarea>';
283  $outCode .= '<input type="hidden" name="e[config]" value="1">';
284  // Display "Include TypoScript file content?" checkbox
285  $outCode .= '<div class="checkbox"><label for="checkIncludeTypoScriptFileContent">' . BackendUtility::getFuncCheck($this->pObj->id, 'SET[includeTypoScriptFileContent]', $this->pObj->MOD_SETTINGS['includeTypoScriptFileContent'], '', '&e[config]=1', 'id="checkIncludeTypoScriptFileContent"');
286  $outCode .= $lang->getLL('includeTypoScriptFileContent') . '</label></div><br />';
287  $theOutput .= '<div style="padding-top: 15px;"></div>';
288  $theOutput .= '<h3>' . $lang->getLL('setup', true) . '</h3>';
289  $theOutput .= $outCode;
290  }
291 
292  // Processing:
293  $outCode = '';
294  $outCode .= $this->tableRow($lang->getLL('title'), htmlspecialchars($tplRow['title']), 'title', $tplRow['uid']);
295  $outCode .= $this->tableRow($lang->getLL('sitetitle'), htmlspecialchars($tplRow['sitetitle']), 'sitetitle', $tplRow['uid']);
296  $outCode .= $this->tableRow($lang->getLL('description'), nl2br(htmlspecialchars($tplRow['description'])), 'description', $tplRow['uid']);
297  $outCode .= $this->tableRow($lang->getLL('constants'), sprintf($lang->getLL('editToView'), trim($tplRow['constants']) ? count(explode(LF, $tplRow['constants'])) : 0), 'constants', $tplRow['uid']);
298  $outCode .= $this->tableRow($lang->getLL('setup'), sprintf($lang->getLL('editToView'), trim($tplRow['config']) ? count(explode(LF, $tplRow['config'])) : 0), 'config', $tplRow['uid']);
299  $outCode = '<div class="table-fit"><table class="table table-striped table-hover">' . $outCode . '</table></div>';
300 
301  // Edit all icon:
302  $urlParameters = [
303  'edit' => [
304  'sys_template' => [
305  $tplRow['uid'] => 'edit'
306  ]
307  ],
308  'createExtension' => 0,
309  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
310  ];
311  $url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
312  $title = $lang->getLL('editTemplateRecord', true);
313  $icon = $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render();
314  $outCode .= '<br /><a class="btn btn-default" href="' . htmlspecialchars($url)
315  . '"><strong>' . $icon . '&nbsp;' . $title . '</strong></a>';
316  $theOutput .= '<div>' . $outCode . '</div>';
317 
318  // hook after compiling the output
319  if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postOutputProcessingHook'])) {
320  $postOutputProcessingHook = &$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postOutputProcessingHook'];
321  if (is_array($postOutputProcessingHook)) {
322  $hookParameters = [
323  'theOutput' => &$theOutput,
324  'POST' => $POST,
325  'e' => $e,
326  'tplRow' => $tplRow,
327  'numberOfRows' => $numberOfRows
328  ];
329  foreach ($postOutputProcessingHook as $hookFunction) {
330  GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
331  }
332  }
333  }
334  } else {
335  $theOutput .= $this->pObj->noTemplate(1);
336  }
337  return $theOutput;
338  }
339 }
static getFuncCheck($mainParams, $elementName, $currentValue, $script='', $addParams='', $tagParams='')
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:76
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']