[TASK] Use real boolean value for sL second param
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / Wizard / TableController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller\Wizard;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 1999-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use TYPO3\CMS\Backend\Utility\BackendUtility;
31 use TYPO3\CMS\Backend\Utility\IconUtility;
32 use TYPO3\CMS\Core\Utility\GeneralUtility;
33 use TYPO3\CMS\Core\Utility\MathUtility;
34
35 /**
36 * Script Class for rendering the Table Wizard
37 *
38 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
39 */
40 class TableController {
41
42 // Internal, dynamic:
43 /**
44 * document template object
45 *
46 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
47 * @todo Define visibility
48 */
49 public $doc;
50
51 // Content accumulation for the module.
52 /**
53 * @todo Define visibility
54 */
55 public $content;
56
57 // TRUE, then <input> fields are shown, not textareas.
58 /**
59 * @todo Define visibility
60 */
61 public $inputStyle = 0;
62
63 // Internal, static:
64 // If set, the string version of the content is interpreted/written as XML
65 // instead of the original linebased kind. This variable still needs binding
66 // to the wizard parameters - but support is ready!
67 /**
68 * @todo Define visibility
69 */
70 public $xmlStorage = 0;
71
72 // Number of new rows to add in bottom of wizard
73 /**
74 * @todo Define visibility
75 */
76 public $numNewRows = 1;
77
78 // Name of field in parent record which MAY contain the number of columns for the table
79 // - here hardcoded to the value of tt_content. Should be set by TCEform parameters (from P)
80 /**
81 * @todo Define visibility
82 */
83 public $colsFieldName = 'cols';
84
85 // Internal, static: GPvars
86 // Wizard parameters, coming from TCEforms linking to the wizard.
87 /**
88 * @todo Define visibility
89 */
90 public $P;
91
92 // The array which is constantly submitted by the multidimensional form of this wizard.
93 /**
94 * @todo Define visibility
95 */
96 public $TABLECFG;
97
98 // Table parsing
99 // quoting of table cells
100 /**
101 * @todo Define visibility
102 */
103 public $tableParsing_quote;
104
105 // delimiter between table cells
106 /**
107 * @todo Define visibility
108 */
109 public $tableParsing_delimiter;
110
111 /**
112 * Constructor
113 */
114 public function __construct() {
115 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_wizards.xlf');
116 $GLOBALS['SOBE'] = $this;
117
118 $this->init();
119 }
120
121 /**
122 * Initialization of the class
123 *
124 * @return void
125 */
126 protected function init() {
127 // GPvars:
128 $this->P = GeneralUtility::_GP('P');
129 $this->TABLECFG = GeneralUtility::_GP('TABLE');
130 // Setting options:
131 $this->xmlStorage = $this->P['params']['xmlOutput'];
132 $this->numNewRows = MathUtility::forceIntegerInRange($this->P['params']['numNewRows'], 1, 50, 5);
133 // Textareas or input fields:
134 $this->inputStyle = isset($this->TABLECFG['textFields']) ? $this->TABLECFG['textFields'] : 1;
135 // Document template object:
136 $this->doc = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
137 $this->doc->backPath = $GLOBALS['BACK_PATH'];
138 $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/wizard_table.html');
139 $this->doc->JScode = $this->doc->wrapScriptTags('
140 function jumpToUrl(URL,formEl) { //
141 window.location.href = URL;
142 }
143 ');
144 // Setting form tag:
145 list($rUri) = explode('#', GeneralUtility::getIndpEnv('REQUEST_URI'));
146 $this->doc->form = '<form action="' . htmlspecialchars($rUri) . '" method="post" name="wizardForm">';
147 $this->tableParsing_delimiter = '|';
148 $this->tableParsing_quote = '';
149 }
150
151 /**
152 * Main function, rendering the table wizard
153 *
154 * @return void
155 */
156 public function main() {
157 if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
158 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('table_title'), $this->tableWizard(), 0, 1);
159 } else {
160 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('table_title'), '<span class="typo3-red">' . $GLOBALS['LANG']->getLL('table_noData', TRUE) . '</span>', 0, 1);
161 }
162 // Setting up the buttons and markers for docheader
163 $docHeaderButtons = $this->getButtons();
164 $markers['CSH'] = $docHeaderButtons['csh'];
165 $markers['CONTENT'] = $this->content;
166 // Build the <body> for the module
167 $this->content = $this->doc->startPage('Table');
168 $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
169 $this->content .= $this->doc->endPage();
170 $this->content = $this->doc->insertStylesAndJS($this->content);
171 }
172
173 /**
174 * Outputting the accumulated content to screen
175 *
176 * @return void
177 * @todo Define visibility
178 */
179 public function printContent() {
180 echo $this->content;
181 }
182
183 /**
184 * Create the panel of buttons for submitting the form or otherwise perform operations.
185 *
186 * @return array All available buttons as an assoc. array
187 */
188 protected function getButtons() {
189 $buttons = array(
190 'csh' => '',
191 'csh_buttons' => '',
192 'close' => '',
193 'save' => '',
194 'save_close' => '',
195 'reload' => ''
196 );
197 if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
198 // CSH
199 $buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_table_wiz', $GLOBALS['BACK_PATH'], '');
200 // CSH Buttons
201 $buttons['csh_buttons'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_table_wiz_buttons', $GLOBALS['BACK_PATH'], '');
202 // Close
203 $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars(('jumpToUrl(unescape(\'' . rawurlencode(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl'])) . '\')); return false;')) . '">' . IconUtility::getSpriteIcon('actions-document-close', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE))) . '</a>';
204 // Save
205 $buttons['save'] = '<input type="image" class="c-inputButton" name="savedok"' . IconUtility::skinImg($this->doc->backPath, 'gfx/savedok.gif') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', TRUE) . '" />';
206 // Save & Close
207 $buttons['save_close'] = '<input type="image" class="c-inputButton" name="saveandclosedok"' . IconUtility::skinImg($this->doc->backPath, 'gfx/saveandclosedok.gif') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />';
208 // Reload
209 $buttons['reload'] = '<input type="image" class="c-inputButton" name="_refresh"' . IconUtility::skinImg($this->doc->backPath, 'gfx/refresh_n.gif') . ' title="' . $GLOBALS['LANG']->getLL('forms_refresh', TRUE) . '" />';
210 }
211 return $buttons;
212 }
213
214 /**
215 * Draws the table wizard content
216 *
217 * @return string HTML content for the form.
218 * @todo Define visibility
219 */
220 public function tableWizard() {
221 // First, check the references by selecting the record:
222 $row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
223 if (!is_array($row)) {
224 throw new \RuntimeException('Wizard Error: No reference to record', 1294587125);
225 }
226 // This will get the content of the form configuration code field to us - possibly cleaned up,
227 // saved to database etc. if the form has been submitted in the meantime.
228 $tableCfgArray = $this->getConfigCode($row);
229 // Generation of the Table Wizards HTML code:
230 $content = $this->getTableHTML($tableCfgArray, $row);
231 // Return content:
232 return $content;
233 }
234
235 /***************************
236 *
237 * Helper functions
238 *
239 ***************************/
240 /**
241 * Will get and return the configuration code string
242 * Will also save (and possibly redirect/exit) the content if a save button has been pressed
243 *
244 * @param array $row Current parent record row
245 * @return array Table config code in an array
246 * @access private
247 * @todo Define visibility
248 */
249 public function getConfigCode($row) {
250 // Get delimiter settings
251 $flexForm = GeneralUtility::xml2array($row['pi_flexform']);
252 if (is_array($flexForm)) {
253 $this->tableParsing_quote = $flexForm['data']['s_parsing']['lDEF']['tableparsing_quote']['vDEF'] ? chr(intval($flexForm['data']['s_parsing']['lDEF']['tableparsing_quote']['vDEF'])) : '';
254 $this->tableParsing_delimiter = $flexForm['data']['s_parsing']['lDEF']['tableparsing_delimiter']['vDEF'] ? chr(intval($flexForm['data']['s_parsing']['lDEF']['tableparsing_delimiter']['vDEF'])) : '|';
255 }
256 // If some data has been submitted, then construct
257 if (isset($this->TABLECFG['c'])) {
258 // Process incoming:
259 $this->changeFunc();
260 // Convert to string (either line based or XML):
261 if ($this->xmlStorage) {
262 // Convert the input array to XML:
263 $bodyText = GeneralUtility::array2xml_cs($this->TABLECFG['c'], 'T3TableWizard');
264 // Setting cfgArr directly from the input:
265 $cfgArr = $this->TABLECFG['c'];
266 } else {
267 // Convert the input array to a string of configuration code:
268 $bodyText = $this->cfgArray2CfgString($this->TABLECFG['c']);
269 // Create cfgArr from the string based configuration - that way it is cleaned up and any incompatibilities will be removed!
270 $cfgArr = $this->cfgString2CfgArray($bodyText, $row[$this->colsFieldName]);
271 }
272 // If a save button has been pressed, then save the new field content:
273 if ($_POST['savedok_x'] || $_POST['saveandclosedok_x']) {
274 // Make TCEmain object:
275 $tce = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
276 $tce->stripslashes_values = 0;
277 // Put content into the data array:
278 $data = array();
279 $data[$this->P['table']][$this->P['uid']][$this->P['field']] = $bodyText;
280 // Perform the update:
281 $tce->start($data, array());
282 $tce->process_datamap();
283 // If the save/close button was pressed, then redirect the screen:
284 if ($_POST['saveandclosedok_x']) {
285 \TYPO3\CMS\Core\Utility\HttpUtility::redirect(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']));
286 }
287 }
288 } else {
289 // If nothing has been submitted, load the $bodyText variable from the selected database row:
290 if ($this->xmlStorage) {
291 $cfgArr = GeneralUtility::xml2array($row[$this->P['field']]);
292 } else {
293 // Regular linebased table configuration:
294 $cfgArr = $this->cfgString2CfgArray($row[$this->P['field']], $row[$this->colsFieldName]);
295 }
296 $cfgArr = is_array($cfgArr) ? $cfgArr : array();
297 }
298 return $cfgArr;
299 }
300
301 /**
302 * Creates the HTML for the Table Wizard:
303 *
304 * @param array $cfgArr Table config array
305 * @param array $row Current parent record array
306 * @return string HTML for the table wizard
307 * @access private
308 * @todo Define visibility
309 */
310 public function getTableHTML($cfgArr, $row) {
311 // Traverse the rows:
312 $tRows = array();
313 $k = 0;
314 $countLines = count($cfgArr);
315 foreach ($cfgArr as $cellArr) {
316 if (is_array($cellArr)) {
317 // Initialize:
318 $cells = array();
319 $a = 0;
320 // Traverse the columns:
321 foreach ($cellArr as $cellContent) {
322 if ($this->inputStyle) {
323 $cells[] = '<input type="text"' . $this->doc->formWidth(20) . ' name="TABLE[c][' . ($k + 1) * 2 . '][' . ($a + 1) * 2 . ']" value="' . htmlspecialchars($cellContent) . '" />';
324 } else {
325 $cellContent = preg_replace('/<br[ ]?[\\/]?>/i', LF, $cellContent);
326 $cells[] = '<textarea ' . $this->doc->formWidth(20) . ' rows="5" name="TABLE[c][' . ($k + 1) * 2 . '][' . ($a + 1) * 2 . ']">' . GeneralUtility::formatForTextarea($cellContent) . '</textarea>';
327 }
328 // Increment counter:
329 $a++;
330 }
331 // CTRL panel for a table row (move up/down/around):
332 $onClick = 'document.wizardForm.action+=\'#ANC_' . (($k + 1) * 2 - 2) . '\';';
333 $onClick = ' onclick="' . htmlspecialchars($onClick) . '"';
334 $ctrl = '';
335 $brTag = $this->inputStyle ? '' : '<br />';
336 if ($k != 0) {
337 $ctrl .= '<input type="image" name="TABLE[row_up][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2up.gif', '') . $onClick . ' title="' . $GLOBALS['LANG']->getLL('table_up', TRUE) . '" />' . $brTag;
338 } else {
339 $ctrl .= '<input type="image" name="TABLE[row_bottom][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_up.gif', '') . $onClick . ' title="' . $GLOBALS['LANG']->getLL('table_bottom', TRUE) . '" />' . $brTag;
340 }
341 $ctrl .= '<input type="image" name="TABLE[row_remove][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/garbage.gif', '') . $onClick . ' title="' . $GLOBALS['LANG']->getLL('table_removeRow', TRUE) . '" />' . $brTag;
342 if ($k + 1 != $countLines) {
343 $ctrl .= '<input type="image" name="TABLE[row_down][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2down.gif', '') . $onClick . ' title="' . $GLOBALS['LANG']->getLL('table_down', TRUE) . '" />' . $brTag;
344 } else {
345 $ctrl .= '<input type="image" name="TABLE[row_top][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_down.gif', '') . $onClick . ' title="' . $GLOBALS['LANG']->getLL('table_top', TRUE) . '" />' . $brTag;
346 }
347 $ctrl .= '<input type="image" name="TABLE[row_add][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/add.gif', '') . $onClick . ' title="' . $GLOBALS['LANG']->getLL('table_addRow', TRUE) . '" />' . $brTag;
348 $tRows[] = '
349 <tr class="bgColor4">
350 <td class="bgColor5"><a name="ANC_' . ($k + 1) * 2 . '"></a><span class="c-wizButtonsV">' . $ctrl . '</span></td>
351 <td>' . implode('</td>
352 <td>', $cells) . '</td>
353 </tr>';
354 // Increment counter:
355 $k++;
356 }
357 }
358 // CTRL panel for a table column (move left/right/around/delete)
359 $cells = array();
360 $cells[] = '';
361 // Finding first row:
362 $firstRow = reset($cfgArr);
363 if (is_array($firstRow)) {
364 // Init:
365 $a = 0;
366 $cols = count($firstRow);
367 // Traverse first row:
368 foreach ($firstRow as $temp) {
369 $ctrl = '';
370 if ($a != 0) {
371 $ctrl .= '<input type="image" name="TABLE[col_left][' . ($a + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2left.gif', '') . ' title="' . $GLOBALS['LANG']->getLL('table_left', TRUE) . '" />';
372 } else {
373 $ctrl .= '<input type="image" name="TABLE[col_end][' . ($a + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_left.gif', '') . ' title="' . $GLOBALS['LANG']->getLL('table_end', TRUE) . '" />';
374 }
375 $ctrl .= '<input type="image" name="TABLE[col_remove][' . ($a + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/garbage.gif', '') . ' title="' . $GLOBALS['LANG']->getLL('table_removeColumn', TRUE) . '" />';
376 if ($a + 1 != $cols) {
377 $ctrl .= '<input type="image" name="TABLE[col_right][' . ($a + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2right.gif', '') . ' title="' . $GLOBALS['LANG']->getLL('table_right', TRUE) . '" />';
378 } else {
379 $ctrl .= '<input type="image" name="TABLE[col_start][' . ($a + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_right.gif', '') . ' title="' . $GLOBALS['LANG']->getLL('table_start', TRUE) . '" />';
380 }
381 $ctrl .= '<input type="image" name="TABLE[col_add][' . ($a + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/add.gif', '') . ' title="' . $GLOBALS['LANG']->getLL('table_addColumn', TRUE) . '" />';
382 $cells[] = '<span class="c-wizButtonsH">' . $ctrl . '</span>';
383 // Incr. counter:
384 $a++;
385 }
386 $tRows[] = '
387 <tr class="bgColor5">
388 <td align="center">' . implode('</td>
389 <td align="center">', $cells) . '</td>
390 </tr>';
391 }
392 $content = '';
393 // Implode all table rows into a string, wrapped in table tags.
394 $content .= '
395
396
397 <!--
398 Table wizard
399 -->
400 <table border="0" cellpadding="0" cellspacing="1" id="typo3-tablewizard">
401 ' . implode('', $tRows) . '
402 </table>';
403 // Input type checkbox:
404 $content .= '
405
406 <!--
407 Input mode check box:
408 -->
409 <div id="c-inputMode">
410 ' . '<input type="hidden" name="TABLE[textFields]" value="0" />' . '<input type="checkbox" name="TABLE[textFields]" id="textFields" value="1"' . ($this->inputStyle ? ' checked="checked"' : '') . ' /> <label for="textFields">' . $GLOBALS['LANG']->getLL('table_smallFields') . '</label>
411 </div>
412
413 <br /><br />
414 ';
415 // Return content:
416 return $content;
417 }
418
419 /**
420 * Detects if a control button (up/down/around/delete) has been pressed for an item and accordingly it will manipulate the internal TABLECFG array
421 *
422 * @return void
423 * @access private
424 * @todo Define visibility
425 */
426 public function changeFunc() {
427 if ($this->TABLECFG['col_remove']) {
428 $kk = key($this->TABLECFG['col_remove']);
429 $cmd = 'col_remove';
430 } elseif ($this->TABLECFG['col_add']) {
431 $kk = key($this->TABLECFG['col_add']);
432 $cmd = 'col_add';
433 } elseif ($this->TABLECFG['col_start']) {
434 $kk = key($this->TABLECFG['col_start']);
435 $cmd = 'col_start';
436 } elseif ($this->TABLECFG['col_end']) {
437 $kk = key($this->TABLECFG['col_end']);
438 $cmd = 'col_end';
439 } elseif ($this->TABLECFG['col_left']) {
440 $kk = key($this->TABLECFG['col_left']);
441 $cmd = 'col_left';
442 } elseif ($this->TABLECFG['col_right']) {
443 $kk = key($this->TABLECFG['col_right']);
444 $cmd = 'col_right';
445 } elseif ($this->TABLECFG['row_remove']) {
446 $kk = key($this->TABLECFG['row_remove']);
447 $cmd = 'row_remove';
448 } elseif ($this->TABLECFG['row_add']) {
449 $kk = key($this->TABLECFG['row_add']);
450 $cmd = 'row_add';
451 } elseif ($this->TABLECFG['row_top']) {
452 $kk = key($this->TABLECFG['row_top']);
453 $cmd = 'row_top';
454 } elseif ($this->TABLECFG['row_bottom']) {
455 $kk = key($this->TABLECFG['row_bottom']);
456 $cmd = 'row_bottom';
457 } elseif ($this->TABLECFG['row_up']) {
458 $kk = key($this->TABLECFG['row_up']);
459 $cmd = 'row_up';
460 } elseif ($this->TABLECFG['row_down']) {
461 $kk = key($this->TABLECFG['row_down']);
462 $cmd = 'row_down';
463 }
464 if ($cmd && MathUtility::canBeInterpretedAsInteger($kk)) {
465 if (substr($cmd, 0, 4) == 'row_') {
466 switch ($cmd) {
467 case 'row_remove':
468 unset($this->TABLECFG['c'][$kk]);
469 break;
470 case 'row_add':
471 for ($a = 1; $a <= $this->numNewRows; $a++) {
472 // Checking if set: The point is that any new row inbetween existing rows
473 // will be TRUE after one row is added while if rows are added in the bottom
474 // of the table there will be no existing rows to stop the addition of new rows
475 // which means it will add up to $this->numNewRows rows then.
476 if (!isset($this->TABLECFG['c'][($kk + $a)])) {
477 $this->TABLECFG['c'][$kk + $a] = array();
478 } else {
479 break;
480 }
481 }
482 break;
483 case 'row_top':
484 $this->TABLECFG['c'][1] = $this->TABLECFG['c'][$kk];
485 unset($this->TABLECFG['c'][$kk]);
486 break;
487 case 'row_bottom':
488 $this->TABLECFG['c'][10000000] = $this->TABLECFG['c'][$kk];
489 unset($this->TABLECFG['c'][$kk]);
490 break;
491 case 'row_up':
492 $this->TABLECFG['c'][$kk - 3] = $this->TABLECFG['c'][$kk];
493 unset($this->TABLECFG['c'][$kk]);
494 break;
495 case 'row_down':
496 $this->TABLECFG['c'][$kk + 3] = $this->TABLECFG['c'][$kk];
497 unset($this->TABLECFG['c'][$kk]);
498 break;
499 }
500 ksort($this->TABLECFG['c']);
501 }
502 if (substr($cmd, 0, 4) == 'col_') {
503 foreach ($this->TABLECFG['c'] as $cAK => $value) {
504 switch ($cmd) {
505 case 'col_remove':
506 unset($this->TABLECFG['c'][$cAK][$kk]);
507 break;
508 case 'col_add':
509 $this->TABLECFG['c'][$cAK][$kk + 1] = '';
510 break;
511 case 'col_start':
512 $this->TABLECFG['c'][$cAK][1] = $this->TABLECFG['c'][$cAK][$kk];
513 unset($this->TABLECFG['c'][$cAK][$kk]);
514 break;
515 case 'col_end':
516 $this->TABLECFG['c'][$cAK][1000000] = $this->TABLECFG['c'][$cAK][$kk];
517 unset($this->TABLECFG['c'][$cAK][$kk]);
518 break;
519 case 'col_left':
520 $this->TABLECFG['c'][$cAK][$kk - 3] = $this->TABLECFG['c'][$cAK][$kk];
521 unset($this->TABLECFG['c'][$cAK][$kk]);
522 break;
523 case 'col_right':
524 $this->TABLECFG['c'][$cAK][$kk + 3] = $this->TABLECFG['c'][$cAK][$kk];
525 unset($this->TABLECFG['c'][$cAK][$kk]);
526 break;
527 }
528 ksort($this->TABLECFG['c'][$cAK]);
529 }
530 }
531 }
532 // Convert line breaks to <br /> tags:
533 foreach ($this->TABLECFG['c'] as $a => $value) {
534 foreach ($this->TABLECFG['c'][$a] as $b => $value2) {
535 $this->TABLECFG['c'][$a][$b] = str_replace(LF, '<br />', str_replace(CR, '', $this->TABLECFG['c'][$a][$b]));
536 }
537 }
538 }
539
540 /**
541 * Converts the input array to a configuration code string
542 *
543 * @param array $cfgArr Array of table configuration (follows the input structure from the table wizard POST form)
544 * @return string The array converted into a string with line-based configuration.
545 * @see cfgString2CfgArray()
546 * @todo Define visibility
547 */
548 public function cfgArray2CfgString($cfgArr) {
549 // Initialize:
550 $inLines = array();
551 // Traverse the elements of the table wizard and transform the settings into configuration code.
552 foreach ($this->TABLECFG['c'] as $a => $value) {
553 $thisLine = array();
554 foreach ($this->TABLECFG['c'][$a] as $b => $value) {
555 $thisLine[] = $this->tableParsing_quote . str_replace($this->tableParsing_delimiter, '', $this->TABLECFG['c'][$a][$b]) . $this->tableParsing_quote;
556 }
557 $inLines[] = implode($this->tableParsing_delimiter, $thisLine);
558 }
559 // Finally, implode the lines into a string:
560 $bodyText = implode(LF, $inLines);
561 // Return the configuration code:
562 return $bodyText;
563 }
564
565 /**
566 * Converts the input configuration code string into an array
567 *
568 * @param string $cfgStr Configuration code
569 * @param integer $cols Default number of columns
570 * @return array Configuration array
571 * @see cfgArray2CfgString()
572 * @todo Define visibility
573 */
574 public function cfgString2CfgArray($cfgStr, $cols) {
575 // Explode lines in the configuration code - each line is a table row.
576 $tLines = explode(LF, $cfgStr);
577 // Setting number of columns
578 // auto...
579 if (!$cols && trim($tLines[0])) {
580 $cols = count(explode($this->tableParsing_delimiter, $tLines[0]));
581 }
582 $cols = $cols ? $cols : 4;
583 // Traverse the number of table elements:
584 $cfgArr = array();
585 foreach ($tLines as $k => $v) {
586 // Initialize:
587 $vParts = explode($this->tableParsing_delimiter, $v);
588 // Traverse columns:
589 for ($a = 0; $a < $cols; $a++) {
590 if ($this->tableParsing_quote && substr($vParts[$a], 0, 1) == $this->tableParsing_quote && substr($vParts[$a], -1, 1) == $this->tableParsing_quote) {
591 $vParts[$a] = substr(trim($vParts[$a]), 1, -1);
592 }
593 $cfgArr[$k][$a] = $vParts[$a];
594 }
595 }
596 // Return configuration array:
597 return $cfgArr;
598 }
599
600 }
601
602 ?>