[TASK] Replace sprite icon "actions-document-open" with IconFactory
[Packages/TYPO3.CMS.git] / typo3 / sysext / tstemplate / Classes / Controller / TypoScriptTemplateInformationModuleFunctionController.php
1 <?php
2 namespace TYPO3\CMS\Tstemplate\Controller;
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
17 use TYPO3\CMS\Core\DataHandling\DataHandler;
18 use TYPO3\CMS\Core\Imaging\Icon;
19 use TYPO3\CMS\Core\Imaging\IconFactory;
20 use TYPO3\CMS\Core\TypoScript\ExtendedTemplateService;
21 use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Core\Utility\HttpUtility;
24 use TYPO3\CMS\Core\Utility\MathUtility;
25 use TYPO3\CMS\Backend\Module\AbstractFunctionModule;
26 use TYPO3\CMS\Backend\Utility\IconUtility;
27 use TYPO3\CMS\Backend\Utility\BackendUtility;
28 use TYPO3\CMS\Lang\LanguageService;
29
30 /**
31 * This class displays the Info/Modify screen of the Web > Template module
32 */
33 class TypoScriptTemplateInformationModuleFunctionController extends AbstractFunctionModule {
34
35 /**
36 * Indicator for t3editor, whether data is stored
37 *
38 * @var bool
39 */
40 public $tce_processed = FALSE;
41
42 /**
43 * @var TypoScriptTemplateModuleController
44 */
45 public $pObj;
46
47 /**
48 * @var IconFactory
49 */
50 protected $iconFactory;
51
52 /**
53 * Constructor
54 */
55 public function __construct() {
56 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
57 }
58
59 /**
60 * Creates a row for a HTML table
61 *
62 * @param string $label The label to be shown (e.g. 'Title:', 'Sitetitle:')
63 * @param string $data The data/information to be shown (e.g. 'Template for my site')
64 * @param string $field The field/variable to be sent on clicking the edit icon (e.g. 'title', 'sitetitle')
65 * @param int $id The field/variable to be sent on clicking the edit icon (e.g. 'title', 'sitetitle')
66 * @return string A row for a HTML table
67 */
68 public function tableRow($label, $data, $field, $id) {
69 $lang = $this->getLanguageService();
70 $ret = '<tr><td>';
71 $title = $lang->sL('LLL:EXT:lang/locallang_common.xlf:editField', TRUE);
72 if ($field === 'config' || $field === 'constants') {
73 $urlParameters = array(
74 'id' => $this->pObj->id
75 );
76 $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters);
77 $startAnchor = '<a href="' . htmlspecialchars(($aHref . '&e[' . $field . ']=1')) . '" title="' . $title . '">';
78 } else {
79 $params = '&columnsOnly=' . $field . '&createExtension=0' . '&edit[sys_template][' . $id . ']=edit';
80 $editOnClick = BackendUtility::editOnClick($params);
81 $startAnchor = '<a href="#" onclick="' . htmlspecialchars($editOnClick) . '" title="' . $title . '>';
82 }
83 $icon = $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL);
84 $ret .= $startAnchor . '<strong>' . $label . '</strong></a>';
85 $ret .= '</td><td width="80%">' . $data . '</td><td>' . $startAnchor . '<span class="btn btn-default">' . $icon . '</span></a></td></tr>';
86 return $ret;
87 }
88
89 /**
90 * Create an instance of \TYPO3\CMS\Core\TypoScript\ExtendedTemplateService in
91 * $GLOBALS['tmpl'] and looks for the first (visible) template
92 * record. If $template_uid was given and greater than zero, this record will be checked.
93 *
94 * Initializes the module. Done in this function because we may need to re-initialize if data is submitted!
95 *
96 * @param int $pageId The uid of the current page
97 * @param int $template_uid: The uid of the template record to be rendered (only if more than one template on the current page)
98 * @return bool Returns TRUE if a template record was found, otherwise FALSE
99 */
100 public function initialize_editor($pageId, $template_uid = 0) {
101 /** @var ExtendedTemplateService $tmpl */
102 $tmpl = GeneralUtility::makeInstance(ExtendedTemplateService::class);
103 $GLOBALS['tmpl'] = $tmpl;
104
105 // Do not log time-performance information
106 $tmpl->tt_track = FALSE;
107 $tmpl->init();
108
109 // Get the row of the first VISIBLE template of the page. where clause like the frontend.
110 $GLOBALS['tplRow'] = $tmpl->ext_getFirstTemplate($pageId, $template_uid);
111 if (is_array($GLOBALS['tplRow'])) {
112 $GLOBALS['tplRow'] = $this->processTemplateRowAfterLoading($GLOBALS['tplRow']);
113 return TRUE;
114 }
115 return FALSE;
116 }
117
118 /**
119 * Process template row after loading
120 *
121 * @param array $tplRow Template row
122 * @return array Preprocessed template row
123 */
124 public function processTemplateRowAfterLoading(array $tplRow) {
125 if ($this->pObj->MOD_SETTINGS['includeTypoScriptFileContent']) {
126 // Let the recursion detection counter start at 91, so that only 10 recursive calls will be resolved
127 // Otherwise the editor will be bloated with way to many lines making it hard the break the cyclic recursion.
128 $tplRow['config'] = TypoScriptParser::checkIncludeLines($tplRow['config'], 91);
129 $tplRow['constants'] = TypoScriptParser::checkIncludeLines($tplRow['constants'], 91);
130 }
131 return $tplRow;
132 }
133
134 /**
135 * Process template row before saving
136 *
137 * @param array $tplRow Template row
138 * @return array Preprocessed template row
139 */
140 public function processTemplateRowBeforeSaving(array $tplRow) {
141 if ($this->pObj->MOD_SETTINGS['includeTypoScriptFileContent']) {
142 $tplRow = TypoScriptParser::extractIncludes_array($tplRow);
143 }
144 return $tplRow;
145 }
146
147 /**
148 * @return LanguageService
149 */
150 protected function getLanguageService() {
151 return $GLOBALS['LANG'];
152 }
153
154 /**
155 * The main processing method if this class
156 *
157 * @return string Information of the template status or the taken actions as HTML string
158 */
159 public function main() {
160 $lang = $this->getLanguageService();
161 $lang->includeLLFile('EXT:tstemplate/Resources/Private/Language/locallang_info.xlf');
162 $this->pObj->MOD_MENU['includeTypoScriptFileContent'] = TRUE;
163 $e = $this->pObj->e;
164 // Checking for more than one template an if, set a menu...
165 $manyTemplatesMenu = $this->pObj->templateMenu();
166 $template_uid = 0;
167 if ($manyTemplatesMenu) {
168 $template_uid = $this->pObj->MOD_SETTINGS['templatesOnPage'];
169 }
170 // Initialize
171 $existTemplate = $this->initialize_editor($this->pObj->id, $template_uid);
172 $tplRow = $GLOBALS['tplRow'];
173 $saveId = 0;
174 if ($existTemplate) {
175 $saveId = $tplRow['_ORIG_uid'] ? $tplRow['_ORIG_uid'] : $tplRow['uid'];
176 }
177 // Create extension template
178 $newId = $this->pObj->createTemplate($this->pObj->id, $saveId);
179 if ($newId) {
180 // Switch to new template
181 $urlParameters = array(
182 'id' => $this->pObj->id,
183 'SET[templatesOnPage]' => $newId
184 );
185 $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters);
186 HttpUtility::redirect($aHref);
187 }
188 $tce = NULL;
189 $theOutput = '';
190 if ($existTemplate) {
191 // Update template ?
192 $POST = GeneralUtility::_POST();
193 if (
194 isset($POST['submit'])
195 || isset($POST['saveclose'])
196 ) {
197 // Set the data to be saved
198 $recData = array();
199 $alternativeFileName = array();
200 if (is_array($POST['data'])) {
201 foreach ($POST['data'] as $field => $val) {
202 switch ($field) {
203 case 'constants':
204 case 'config':
205 $recData['sys_template'][$saveId][$field] = $val;
206 break;
207 }
208 }
209 }
210 if (!empty($recData)) {
211 $recData['sys_template'][$saveId] = $this->processTemplateRowBeforeSaving($recData['sys_template'][$saveId]);
212 // Create new tce-object
213 $tce = GeneralUtility::makeInstance(DataHandler::class);
214 $tce->stripslashes_values = FALSE;
215 $tce->alternativeFileName = $alternativeFileName;
216 // Initialize
217 $tce->start($recData, array());
218 // Saved the stuff
219 $tce->process_datamap();
220 // Clear the cache (note: currently only admin-users can clear the cache in tce_main.php)
221 $tce->clear_cacheCmd('all');
222 // tce were processed successfully
223 $this->tce_processed = TRUE;
224 // re-read the template ...
225 $this->initialize_editor($this->pObj->id, $template_uid);
226 $tplRow = $GLOBALS['tplRow'];
227 // reload template menu
228 $manyTemplatesMenu = $this->pObj->templateMenu();
229 }
230 }
231 // Hook post updating template/TCE processing
232 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postTCEProcessingHook'])) {
233 $postTCEProcessingHook = &$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postTCEProcessingHook'];
234 if (is_array($postTCEProcessingHook)) {
235 $hookParameters = array(
236 'POST' => $POST,
237 'tce' => $tce
238 );
239 foreach ($postTCEProcessingHook as $hookFunction) {
240 GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
241 }
242 }
243 }
244 $content = '<a href="#" class="t3-js-clickmenutrigger" data-table="sys_template" data-uid="' . $tplRow['uid'] . '" data-listframe="1">' . IconUtility::getSpriteIconForRecord('sys_template', $tplRow) . '</a><strong>' . htmlspecialchars($tplRow['title']) . '</strong>' . htmlspecialchars((trim($tplRow['sitetitle']) ? ' (' . $tplRow['sitetitle'] . ')' : ''));
245 $theOutput .= $this->pObj->doc->section($lang->getLL('templateInformation'), $content, 0, 1);
246 if ($manyTemplatesMenu) {
247 $theOutput .= $this->pObj->doc->section('', $manyTemplatesMenu);
248 }
249 $theOutput .= $this->pObj->doc->spacer(10);
250 $numberOfRows = 35;
251 // If abort pressed, nothing should be edited:
252 if (isset($POST['saveclose'])) {
253 unset($e);
254 }
255 if (isset($e['constants'])) {
256 $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>';
257 $outCode .= '<input type="hidden" name="e[constants]" value="1">';
258 // Display "Include TypoScript file content?" checkbox
259 $outCode .= '<div class="checkbox"><label for="checkIncludeTypoScriptFileContent">' . BackendUtility::getFuncCheck($this->pObj->id, 'SET[includeTypoScriptFileContent]', $this->pObj->MOD_SETTINGS['includeTypoScriptFileContent'], '', '&e[constants]=1', 'id="checkIncludeTypoScriptFileContent"');
260 $outCode .= $lang->getLL('includeTypoScriptFileContent') . '</label></div><br />';
261 $theOutput .= $this->pObj->doc->spacer(15);
262 $theOutput .= $this->pObj->doc->section($lang->getLL('constants'), '', TRUE);
263 $theOutput .= $this->pObj->doc->sectionEnd() . $outCode;
264 }
265 if (isset($e['config'])) {
266 $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>';
267 $outCode .= '<input type="hidden" name="e[config]" value="1">';
268 // Display "Include TypoScript file content?" checkbox
269 $outCode .= '<div class="checkbox"><label for="checkIncludeTypoScriptFileContent">' . BackendUtility::getFuncCheck($this->pObj->id, 'SET[includeTypoScriptFileContent]', $this->pObj->MOD_SETTINGS['includeTypoScriptFileContent'], '', '&e[config]=1', 'id="checkIncludeTypoScriptFileContent"');
270 $outCode .= $lang->getLL('includeTypoScriptFileContent') . '</label></div><br />';
271 $theOutput .= $this->pObj->doc->spacer(15);
272 $theOutput .= $this->pObj->doc->section($lang->getLL('setup'), '', TRUE);
273 $theOutput .= $this->pObj->doc->sectionEnd() . $outCode;
274 }
275
276 // Processing:
277 $outCode = '';
278 $outCode .= $this->tableRow($lang->getLL('title'), htmlspecialchars($tplRow['title']), 'title', $tplRow['uid']);
279 $outCode .= $this->tableRow($lang->getLL('sitetitle'), htmlspecialchars($tplRow['sitetitle']), 'sitetitle', $tplRow['uid']);
280 $outCode .= $this->tableRow($lang->getLL('description'), nl2br(htmlspecialchars($tplRow['description'])), 'description', $tplRow['uid']);
281 $outCode .= $this->tableRow($lang->getLL('constants'), sprintf($lang->getLL('editToView'), trim($tplRow['constants']) ? count(explode(LF, $tplRow['constants'])) : 0), 'constants', $tplRow['uid']);
282 $outCode .= $this->tableRow($lang->getLL('setup'), sprintf($lang->getLL('editToView'), trim($tplRow['config']) ? count(explode(LF, $tplRow['config'])) : 0), 'config', $tplRow['uid']);
283 $outCode = '<div class="table-fit"><table class="table table-striped table-hover">' . $outCode . '</table></div>';
284
285 // Edit all icon:
286 $editOnClick = BackendUtility::editOnClick('&createExtension=0&edit[sys_template][' . $tplRow['uid'] . ']=edit');
287 $title = $lang->getLL('editTemplateRecord', TRUE);
288 $icon = $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL);
289 $outCode .= '<br /><a class="btn btn-default" href="#" onclick="' . htmlspecialchars($editOnClick)
290 . '"><strong>' . $icon . '&nbsp;' . $title . '</strong></a>';
291 $theOutput .= $this->pObj->doc->section('', $outCode);
292
293 // hook after compiling the output
294 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postOutputProcessingHook'])) {
295 $postOutputProcessingHook = &$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/tstemplate_info/class.tx_tstemplateinfo.php']['postOutputProcessingHook'];
296 if (is_array($postOutputProcessingHook)) {
297 $hookParameters = array(
298 'theOutput' => &$theOutput,
299 'POST' => $POST,
300 'e' => $e,
301 'tplRow' => $tplRow,
302 'numberOfRows' => $numberOfRows
303 );
304 foreach ($postOutputProcessingHook as $hookFunction) {
305 GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
306 }
307 }
308 }
309 } else {
310 $theOutput .= $this->pObj->noTemplate(1);
311 }
312 return $theOutput;
313 }
314
315 }