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