[TASK] Fix CGL errors
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / BackendLayoutWizardController.php
1 <?php
2 namespace TYPO3\CMS\Backend\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 Psr\Http\Message\ServerRequestInterface;
18 use Psr\Http\Message\ResponseInterface;
19 use TYPO3\CMS\Backend\Module\AbstractModule;
20 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
21 use TYPO3\CMS\Backend\Utility\BackendUtility;
22 use TYPO3\CMS\Core\Imaging\Icon;
23 use TYPO3\CMS\Core\Page\PageRenderer;
24 use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
27
28 /**
29 * Script Class for grid wizard
30 */
31 class BackendLayoutWizardController extends AbstractModule
32 {
33 // GET vars:
34 // Wizard parameters, coming from TCEforms linking to the wizard.
35 /**
36 * @var array
37 */
38 public $P;
39
40 // Accumulated content.
41 /**
42 * @var string
43 */
44 public $content;
45
46 /**
47 * @var string
48 */
49 public $formName;
50
51 /**
52 * @var string
53 */
54 public $fieldName;
55
56 /**
57 * Constructor
58 */
59 public function __construct()
60 {
61 parent::__construct();
62 $this->init();
63 }
64
65 /**
66 * Initialises the Class
67 *
68 * @return void
69 * @throws \InvalidArgumentException
70 */
71 public function init()
72 {
73 $lang = $this->getLanguageService();
74 $lang->includeLLFile('EXT:lang/locallang_wizards.xlf');
75
76 // Setting GET vars (used in frameset script):
77 $this->P = GeneralUtility::_GP('P');
78 $this->formName = $this->P['formName'];
79 $this->fieldName = $this->P['itemName'];
80 $hmac_validate = GeneralUtility::hmac($this->formName . $this->fieldName, 'wizard_js');
81 if (!$this->P['hmac'] || ($this->P['hmac'] !== $hmac_validate)) {
82 throw new \InvalidArgumentException('Hmac Validation failed for backend_layout wizard', 1385811397);
83 }
84 $uid = (int)$this->P['uid'];
85
86 /** @var \TYPO3\CMS\Core\Page\PageRenderer $pageRenderer */
87 $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
88 $pageRenderer->loadExtJS();
89 $pageRenderer->addJsFile(ExtensionManagementUtility::extRelPath('backend')
90 . 'Resources/Public/JavaScript/grideditor.js');
91 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip');
92 $pageRenderer->addInlineSetting(
93 'ContextHelp',
94 'moduleUrl',
95 BackendUtility::getModuleUrl(
96 'help_CshmanualCshmanual',
97 array(
98 'tx_cshmanual_help_cshmanualcshmanual' => array(
99 'controller' => 'Help',
100 'action' => 'detail'
101 )
102 )
103 )
104 );
105 $pageRenderer->addJsInlineCode('storeData', '
106 function storeData(data) {
107 if (parent.opener && parent.opener.document && parent.opener.document.' . $this->formName . ' && parent.opener.document.' . $this->formName . '[' . GeneralUtility::quoteJSvalue($this->fieldName) . ']) {
108 parent.opener.document.' . $this->formName . '[' . GeneralUtility::quoteJSvalue($this->fieldName) . '].value = data;
109 parent.opener.TBE_EDITOR.fieldChanged("backend_layout","' . $uid . '","config","data[backend_layout][' . $uid . '][config]");
110 }
111 }
112 ', false);
113 $languageLabels = array(
114 'save' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_labelSave', true),
115 'title' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_windowTitle', true),
116 'editCell' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_editCell', true),
117 'mergeCell' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_mergeCell', true),
118 'splitCell' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_splitCell', true),
119 'name' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_name', true),
120 'column' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_column', true),
121 'notSet' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_notSet', true),
122 'nameHelp' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_nameHelp', true),
123 'columnHelp' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_columnHelp', true)
124 );
125 $pageRenderer->addInlineLanguageLabelArray($languageLabels);
126 // Select record
127 $record = $this->getDatabaseConnection()->exec_SELECTgetRows(
128 $this->P['field'],
129 $this->P['table'],
130 'uid=' . (int)$this->P['uid']
131 );
132 if (trim($record[0][$this->P['field']]) == '') {
133 $rows = array(array(array('colspan' => 1, 'rowspan' => 1, 'spanned' => false, 'name' => '')));
134 $colCount = 1;
135 $rowCount = 1;
136 } else {
137 // load TS parser
138 $parser = GeneralUtility::makeInstance(TypoScriptParser::class);
139 $parser->parse($record[0][$this->P['field']]);
140 $data = $parser->setup['backend_layout.'];
141 $rows = array();
142 $colCount = $data['colCount'];
143 $rowCount = $data['rowCount'];
144 $dataRows = $data['rows.'];
145 $spannedMatrix = array();
146 for ($i = 1; $i <= $rowCount; $i++) {
147 $cells = array();
148 $row = array_shift($dataRows);
149 $columns = $row['columns.'];
150 for ($j = 1; $j <= $colCount; $j++) {
151 $cellData = array();
152 if (!$spannedMatrix[$i][$j]) {
153 if (is_array($columns) && !empty($columns)) {
154 $column = array_shift($columns);
155 if (isset($column['colspan'])) {
156 $cellData['colspan'] = (int)$column['colspan'];
157 $columnColSpan = (int)$column['colspan'];
158 if (isset($column['rowspan'])) {
159 $columnRowSpan = (int)$column['rowspan'];
160 for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
161 for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
162 $spannedMatrix[$i + $spanRow][$j + $spanColumn] = 1;
163 }
164 }
165 } else {
166 for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
167 $spannedMatrix[$i][$j + $spanColumn] = 1;
168 }
169 }
170 } else {
171 $cellData['colspan'] = 1;
172 if (isset($column['rowspan'])) {
173 $columnRowSpan = (int)$column['rowspan'];
174 for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
175 $spannedMatrix[$i + $spanRow][$j] = 1;
176 }
177 }
178 }
179 if (isset($column['rowspan'])) {
180 $cellData['rowspan'] = (int)$column['rowspan'];
181 } else {
182 $cellData['rowspan'] = 1;
183 }
184 if (isset($column['name'])) {
185 $cellData['name'] = $column['name'];
186 }
187 if (isset($column['colPos'])) {
188 $cellData['column'] = (int)$column['colPos'];
189 }
190 }
191 } else {
192 $cellData = array('colspan' => 1, 'rowspan' => 1, 'spanned' => 1);
193 }
194 $cells[] = $cellData;
195 }
196 $rows[] = $cells;
197 if (!empty($spannedMatrix[$i]) && is_array($spannedMatrix[$i])) {
198 ksort($spannedMatrix[$i]);
199 }
200 }
201 }
202 $pageRenderer->addExtOnReadyCode('
203 t3Grid = new TYPO3.Backend.t3Grid({
204 data: ' . json_encode($rows, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS) . ',
205 colCount: ' . (int)$colCount . ',
206 rowCount: ' . (int)$rowCount . ',
207 targetElement: \'editor\'
208 });
209 t3Grid.drawTable();
210 ');
211
212 $this->moduleTemplate->getPageRenderer()->addCssFile(ExtensionManagementUtility::extRelPath('backend')
213 . 'Resources/Public/Css/grideditor.css');
214 }
215
216 /**
217 * Injects the request object for the current request or subrequest
218 * As this controller goes only through the main() method, it is rather simple for now
219 *
220 * @param ServerRequestInterface $request
221 * @param ResponseInterface $response
222 * @return ResponseInterface
223 */
224 public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
225 {
226 $this->main();
227
228 $this->setPagePath($this->P['table'], $this->P['uid']);
229
230
231 $this->moduleTemplate->setContent($this->content);
232 $response->getBody()->write($this->moduleTemplate->renderContent());
233 return $response;
234 }
235
236
237 /**
238 * Creates the correct path to the current record
239 *
240 * @param string $table
241 * @param int $uid
242 */
243 protected function setPagePath($table, $uid)
244 {
245 $uid = (int)$uid;
246
247 if ($table === 'pages') {
248 $pageId = $uid;
249 } else {
250 $record = BackendUtility::getRecord($table, $uid, '*', '', false);
251 $pageId = $record['pid'];
252 }
253
254 $pageAccess = BackendUtility::readPageAccess($pageId, $this->getBackendUser()->getPagePermsClause(1));
255 if (is_array($pageAccess)) {
256 $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pageAccess);
257 }
258 }
259
260 /**
261 * Main Method, rendering either colorpicker or frameset depending on ->showPicker
262 *
263 * @return void
264 */
265 public function main()
266 {
267 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
268 $lang = $this->getLanguageService();
269
270 $resourcePath = ExtensionManagementUtility::extRelPath('backend')
271 . 'Resources/Public/Images/BackendLayoutWizard/';
272
273 $saveButton = $buttonBar->makeInputButton()
274 ->setName('_savedok')
275 ->setValue('1')
276 ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', true))
277 ->setOnClick('storeData(t3Grid.export2LayoutRecord());return true;')
278 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL));
279
280 $saveAndCloseButton = $buttonBar->makeInputButton()
281 ->setName('_savedokandclose')
282 ->setValue('1')
283 ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', true))
284 ->setOnClick('storeData(t3Grid.export2LayoutRecord());window.close();return true;')
285 ->setIcon(
286 $this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL)
287 );
288
289 $splitButton = $buttonBar->makeSplitButton()
290 ->addItem($saveButton)
291 ->addItem($saveAndCloseButton);
292 $buttonBar->addButton($splitButton);
293
294 $closeButton = $buttonBar->makeLinkButton()
295 ->setHref('#')
296 ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', true))
297 ->setOnClick('window.close();return true;')
298 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL));
299 $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 30);
300
301
302 $this->content .= '
303 <table border="0" width="90%" height="90%" id="outer_container">
304 <tr>
305 <td class="editor_cell">
306 <div id="editor">
307 </div>
308 </td>
309 <td width="20" valign="center">
310 <a class="addCol" href="#" title="' . $lang->getLL('grid_addColumn') . '" onclick="t3Grid.addColumn(); t3Grid.drawTable(\'editor\');">
311 <img src="' . $resourcePath . 't3grid-tableright.png" border="0" />
312 </a><br />
313 <a class="removeCol" href="#" title="' . $lang->getLL('grid_removeColumn') . '" onclick="t3Grid.removeColumn(); t3Grid.drawTable(\'editor\');">
314 <img src="' . $resourcePath . 't3grid-tableleft.png" border="0" />
315 </a>
316 </td>
317 </tr>
318 <tr>
319 <td colspan="2" height="20" align="center">
320 <a class="addCol" href="#" title="' . $lang->getLL('grid_addRow') . '" onclick="t3Grid.addRow(); t3Grid.drawTable(\'editor\');">
321 <img src="' . $resourcePath . 't3grid-tabledown.png" border="0" />
322 </a>
323 <a class="removeCol" href="#" title="' . $lang->getLL('grid_removeRow') . '" onclick="t3Grid.removeRow(); t3Grid.drawTable(\'editor\');">
324 <img src="' . $resourcePath . 't3grid-tableup.png" border="0" />
325 </a>
326 </td>
327 </tr>
328 </table>
329 ';
330 }
331
332 /**
333 * Returns LanguageService
334 *
335 * @return \TYPO3\CMS\Lang\LanguageService
336 */
337 protected function getLanguageService()
338 {
339 return $GLOBALS['LANG'];
340 }
341
342 /**
343 * Returns the database connection
344 *
345 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
346 */
347 protected function getDatabaseConnection()
348 {
349 return $GLOBALS['TYPO3_DB'];
350 }
351
352 /**
353 * Gets the current backend user.
354 *
355 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
356 */
357 protected function getBackendUser()
358 {
359 return $GLOBALS['BE_USER'];
360 }
361 }