[TASK] Remove global declarations inside methods
[Packages/TYPO3.CMS.git] / typo3 / wizard_forms.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Wizard to help make forms (fx. for tt_content elements) of type 'form'.
29 *
30 * Revised for TYPO3 3.6 November/2003 by Kasper Skårhøj
31 * XHTML compliant
32 *
33 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 175: class SC_wizard_forms
41 * 203: function init()
42 * 242: function main()
43 * 257: function printContent()
44 * 268: function formsWizard()
45 *
46 * SECTION: Helper functions
47 * 311: function getConfigCode(&$row)
48 * 382: function getFormHTML($formCfgArray,$row)
49 * 662: function changeFunc()
50 * 721: function cfgArray2CfgString($cfgArr)
51 * 803: function cfgString2CfgArray($cfgStr)
52 * 902: function cleanT($tArr)
53 * 920: function formatCells($fArr)
54 *
55 * TOTAL FUNCTIONS: 11
56 * (This index is automatically created/updated by the extension "extdeveval")
57 *
58 */
59
60
61
62 $BACK_PATH='';
63 require ('init.php');
64 require ('template.php');
65 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_wizards.xml');
66
67
68
69
70
71
72
73
74
75
76
77
78 /**
79 * API comments:
80 *
81 * The form wizard can help you to create forms - it allows you to create almost any kind of HTML form elements and in any order and amount.
82 *
83 * The format for the resulting configuration code can be either a line-based configuration. That can look like this:
84 *
85 * Your name: | *name=input | (input your name here!)
86 * Your Email: | *email=input
87 * Your address: | address=textarea,40,10
88 * Your Haircolor: | hair=radio |
89 * upload | attachment=file
90 * | quoted_printable=hidden | 0
91 * | formtype_mail=submit | Send form
92 * | html_enabled=hidden
93 * | subject=hidden | This is the subject
94 *
95 *
96 * Alternatively it can be XML. The same configuration from above looks like this in XML:
97 *
98 * <T3FormWizard>
99 * <n2>
100 * <type>input</type>
101 * <label>Your name:</label>
102 * <required>1</required>
103 * <fieldname>name</fieldname>
104 * <size></size>
105 * <max></max>
106 * <default>(input your name here!)</default>
107 * </n2>
108 * <n4>
109 * <type>input</type>
110 * <label>Your Email:</label>
111 * <required>1</required>
112 * <fieldname>email</fieldname>
113 * <size></size>
114 * <max></max>
115 * <default></default>
116 * </n4>
117 * <n6>
118 * <type>textarea</type>
119 * <label>Your address:</label>
120 * <fieldname>address</fieldname>
121 * <cols>40</cols>
122 * <rows>10</rows>
123 * <default></default>
124 * </n6>
125 * <n8>
126 * <type>radio</type>
127 * <label>Your Haircolor:</label>
128 * <fieldname>hair</fieldname>
129 * <options></options>
130 * </n8>
131 * <n10>
132 * <type>file</type>
133 * <label>upload</label>
134 * <fieldname>attachment</fieldname>
135 * <size></size>
136 * </n10>
137 * <n12>
138 * <type>hidden</type>
139 * <label></label>
140 * <fieldname>quoted_printable</fieldname>
141 * <default>0</default>
142 * </n12>
143 * <n2000>
144 * <fieldname>formtype_mail</fieldname>
145 * <type>submit</type>
146 * <default>Send form</default>
147 * </n2000>
148 * <n2002>
149 * <fieldname>html_enabled</fieldname>
150 * <type>hidden</type>
151 * </n2002>
152 * <n2004>
153 * <fieldname>subject</fieldname>
154 * <type>hidden</type>
155 * <default>This is the subject</default>
156 * </n2004>
157 * <n20>
158 * <content></content>
159 * </n20>
160 * </T3FormWizard>
161 *
162 *
163 * The XML/phpArray structure is the internal format of the wizard.
164 */
165
166
167 /**
168 * Script Class for rendering the Form Wizard
169 *
170 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
171 * @package TYPO3
172 * @subpackage core
173 */
174 class SC_wizard_forms {
175
176 // Internal, dynamic:
177 /**
178 * document template object
179 *
180 * @var mediumDoc
181 */
182 var $doc;
183 var $content; // Content accumulation for the module.
184 var $include_once=array(); // List of files to include.
185 var $attachmentCounter = 0; // Used to numerate attachments automatically.
186
187
188 // Internal, static:
189 var $xmlStorage=0; // If set, the string version of the content is interpreted/written as XML instead of the original linebased kind. This variable still needs binding to the wizard parameters - but support is ready!
190
191
192 // Internal, static: GPvars
193 var $P; // Wizard parameters, coming from TCEforms linking to the wizard.
194 var $FORMCFG; // The array which is constantly submitted by the multidimensional form of this wizard.
195 var $special; // Indicates if the form is of a dedicated type, like "formtype_mail" (for tt_content element "Form")
196
197
198
199
200
201
202 /**
203 * Initialization the class
204 *
205 * @return void
206 */
207 function init() {
208 // GPvars:
209 $this->P = t3lib_div::_GP('P');
210 $this->special = t3lib_div::_GP('special');
211 $this->FORMCFG = t3lib_div::_GP('FORMCFG');
212
213 // Setting options:
214 $this->xmlStorage = $this->P['params']['xmlOutput'];
215
216 // Document template object:
217 $this->doc = t3lib_div::makeInstance('template');
218 $this->doc->backPath = $GLOBALS['BACK_PATH'];
219 $this->doc->setModuleTemplate('templates/wizard_forms.html');
220 $this->doc->JScode=$this->doc->wrapScriptTags('
221 function jumpToUrl(URL,formEl) { //
222 window.location.href = URL;
223 }
224 ');
225
226 // Setting form tag:
227 list($rUri) = explode('#',t3lib_div::getIndpEnv('REQUEST_URI'));
228 $this->doc->form ='<form action="'.htmlspecialchars($rUri).'" method="post" name="wizardForm">';
229
230 // If save command found, include tcemain:
231 if ($_POST['savedok_x'] || $_POST['saveandclosedok_x']) {
232 $this->include_once[]=PATH_t3lib.'class.t3lib_tcemain.php';
233 }
234 }
235
236 /**
237 * Main function for rendering the form wizard HTML
238 *
239 * @return void
240 */
241 function main() {
242 if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
243 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('forms_title'), $this->formsWizard(), 0, 1);
244 } else {
245 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('forms_title'), '<span class="typo3-red">' . $GLOBALS['LANG']->getLL('table_noData',1) . '</span>', 0, 1);
246 }
247
248 // Setting up the buttons and markers for docheader
249 $docHeaderButtons = $this->getButtons();
250 $markers['CSH'] = $docHeaderButtons['csh'];
251 $markers['CONTENT'] = $this->content;
252
253 // Build the <body> for the module
254 $this->content = $this->doc->startPage('Form Wizard');
255 $this->content.= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
256 $this->content.= $this->doc->endPage();
257 $this->content = $this->doc->insertStylesAndJS($this->content);
258 }
259
260 /**
261 * Outputting the accumulated content to screen
262 *
263 * @return void
264 */
265 function printContent() {
266 echo $this->content;
267 }
268
269 /**
270 * Create the panel of buttons for submitting the form or otherwise perform operations.
271 *
272 * @return array all available buttons as an assoc. array
273 */
274 protected function getButtons() {
275 $buttons = array(
276 'csh' => '',
277 'csh_buttons' => '',
278 'close' => '',
279 'save' => '',
280 'save_close' => '',
281 'reload' => '',
282 );
283
284 if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
285 // CSH
286 $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz', $GLOBALS['BACK_PATH'], '');
287
288 // CSH Buttons
289 $buttons['csh_buttons'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_buttons', $GLOBALS['BACK_PATH'], '');
290
291 // Close
292 $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(unescape(\'' . rawurlencode(t3lib_div::sanitizeLocalUrl($this->P['returnUrl'])) . '\')); return false;') . '">' .
293 t3lib_iconWorks::getSpriteIcon('actions-document-close', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc', TRUE))) .
294 '</a>';
295
296 // Save
297 $buttons['save'] = '<input type="image" class="c-inputButton" name="savedok"' . t3lib_iconWorks::skinImg($this->doc->backPath, 'gfx/savedok.gif') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc', 1) . '" />';
298
299 // Save & Close
300 $buttons['save_close'] = '<input type="image" class="c-inputButton" name="saveandclosedok"' . t3lib_iconWorks::skinImg($this->doc->backPath, 'gfx/saveandclosedok.gif') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc', 1) . '" />';
301
302 // Reload
303 $buttons['reload'] = '<input type="image" class="c-inputButton" name="_refresh"' . t3lib_iconWorks::skinImg('', 'gfx/refresh_n.gif') . ' title="' . $GLOBALS['LANG']->getLL('forms_refresh', 1) . '" />';
304 }
305
306 return $buttons;
307 }
308
309 /**
310 * Draws the form wizard content
311 *
312 * @return string HTML content for the form.
313 */
314 function formsWizard() {
315
316 // First, check the references by selecting the record:
317 $row = t3lib_BEfunc::getRecord($this->P['table'],$this->P['uid']);
318 if (!is_array($row)) {
319 throw new RuntimeException('Wizard Error: No reference to record', 1294587124);
320 }
321
322 // This will get the content of the form configuration code field to us - possibly cleaned up, saved to database etc. if the form has been submitted in the meantime.
323 $formCfgArray = $this->getConfigCode($row);
324
325 // Generation of the Form Wizards HTML code:
326 $content = $this->getFormHTML($formCfgArray,$row);
327
328 // Return content:
329 return $content;
330 }
331
332
333
334
335
336
337
338
339
340
341
342 /****************************
343 *
344 * Helper functions
345 *
346 ***************************/
347
348 /**
349 * Will get and return the configuration code string
350 * Will also save (and possibly redirect/exit) the content if a save button has been pressed
351 *
352 * @param array Current parent record row (passed by value!)
353 * @return array Configuration Array
354 * @access private
355 */
356 function getConfigCode(&$row) {
357
358 // If some data has been submitted, then construct
359 if (isset($this->FORMCFG['c'])) {
360
361 // Process incoming:
362 $this->changeFunc();
363
364 // Convert to string (either line based or XML):
365 if ($this->xmlStorage) {
366 // Convert the input array to XML:
367 $bodyText = t3lib_div::array2xml_cs($this->FORMCFG['c'],'T3FormWizard');
368
369 // Setting cfgArr directly from the input:
370 $cfgArr = $this->FORMCFG['c'];
371 } else {
372 // Convert the input array to a string of configuration code:
373 $bodyText = $this->cfgArray2CfgString($this->FORMCFG['c']);
374
375 // Create cfgArr from the string based configuration - that way it is cleaned up and any incompatibilities will be removed!
376 $cfgArr = $this->cfgString2CfgArray($bodyText);
377 }
378
379 // If a save button has been pressed, then save the new field content:
380 if ($_POST['savedok_x'] || $_POST['saveandclosedok_x']) {
381
382 // Make TCEmain object:
383 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
384 $tce->stripslashes_values=0;
385
386 // Put content into the data array:
387 $data=array();
388 $data[$this->P['table']][$this->P['uid']][$this->P['field']]=$bodyText;
389 if ($this->special=='formtype_mail') {
390 $data[$this->P['table']][$this->P['uid']]['subheader']=$this->FORMCFG['recipient'];
391 }
392
393 // Perform the update:
394 $tce->start($data,array());
395 $tce->process_datamap();
396
397 // Re-load the record content:
398 $row = t3lib_BEfunc::getRecord($this->P['table'],$this->P['uid']);
399
400 // If the save/close button was pressed, then redirect the screen:
401 if ($_POST['saveandclosedok_x']) {
402 t3lib_utility_Http::redirect(t3lib_div::sanitizeLocalUrl($this->P['returnUrl']));
403 }
404 }
405 } else { // If nothing has been submitted, load the $bodyText variable from the selected database row:
406 if ($this->xmlStorage) {
407 $cfgArr = t3lib_div::xml2array($row[$this->P['field']]);
408 } else { // Regular linebased form configuration:
409 $cfgArr = $this->cfgString2CfgArray($row[$this->P['field']]);
410 }
411 $cfgArr = is_array($cfgArr) ? $cfgArr : array();
412 }
413
414 // Return configuration code:
415 return $cfgArr;
416 }
417
418 /**
419 * Creates the HTML for the Form Wizard:
420 *
421 * @param string Form config array
422 * @param array Current parent record array
423 * @return string HTML for the form wizard
424 * @access private
425 */
426 function getFormHTML($formCfgArray,$row) {
427 // Initialize variables:
428 $specParts=array();
429 $hiddenFields=array();
430 $tRows=array();
431
432 // Set header row:
433 $cells=array($GLOBALS['LANG']->getLL('forms_preview',1).':',
434 $GLOBALS['LANG']->getLL('forms_element',1).':',
435 $GLOBALS['LANG']->getLL('forms_config',1).':',
436 );
437 $tRows[]='
438 <tr class="bgColor2" id="typo3-formWizardHeader">
439 <td>&nbsp;</td>
440 <td>'.implode('</td>
441 <td>',$cells).'</td>
442 </tr>';
443
444 // Traverse the number of form elements:
445 $k=0;
446 foreach($formCfgArray as $confData) {
447
448 // Initialize:
449 $cells=array();
450
451 // If there is a configuration line which is active, then render it:
452 if (!isset($confData['comment'])) {
453
454 // Special parts:
455 if ($this->special=='formtype_mail' && t3lib_div::inList('formtype_mail,subject,html_enabled',$confData['fieldname'])) {
456 $specParts[$confData['fieldname']] = $confData['default'];
457 } else {
458
459 // Render title/field preview COLUMN
460 $cells[]=$confData['type']!='hidden' ? '<strong>'.htmlspecialchars($confData['label']).'</strong>' : '';
461
462
463 // Render general type/title COLUMN:
464 $temp_cells=array();
465
466 // Field type selector:
467 $opt=array();
468 $opt[]='<option value=""></option>';
469 $types = explode(',','input,textarea,select,check,radio,password,file,hidden,submit,property,label');
470 foreach($types as $t) {
471 $opt[]='
472 <option value="'.$t.'"'.($confData['type']==$t?' selected="selected"':'').'>'.$GLOBALS['LANG']->getLL('forms_type_'.$t,1).'</option>';
473 }
474 $temp_cells[$GLOBALS['LANG']->getLL('forms_type')]='
475 <select name="FORMCFG[c]['.(($k+1)*2).'][type]">
476 '.implode('
477 ',$opt).'
478 </select>';
479
480 // Title field:
481 if (!t3lib_div::inList('hidden,submit',$confData['type'])) {
482 $temp_cells[$GLOBALS['LANG']->getLL('forms_label')]='<input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[c]['.(($k+1)*2).'][label]" value="'.htmlspecialchars($confData['label']).'" />';
483 }
484
485 // Required checkbox:
486 if (!t3lib_div::inList('check,hidden,submit,label',$confData['type'])) {
487 $temp_cells[$GLOBALS['LANG']->getLL('forms_required')]='<input type="checkbox" name="FORMCFG[c]['.(($k+1)*2).'][required]" value="1"'.($confData['required']?' checked="checked"':'').' title="'.$GLOBALS['LANG']->getLL('forms_required',1).'" />';
488 }
489
490 // Put sub-items together into table cell:
491 $cells[]=$this->formatCells($temp_cells);
492
493
494 // Render specific field configuration COLUMN:
495 $temp_cells=array();
496
497 // Fieldname
498 if ($this->special=='formtype_mail' && $confData['type']=='file') {
499 $confData['fieldname'] = 'attachment'.(++$this->attachmentCounter);
500 }
501 if (!t3lib_div::inList('label',$confData['type'])) {
502 $temp_cells[$GLOBALS['LANG']->getLL('forms_fieldName')]='<input type="text"'.$this->doc->formWidth(10).' name="FORMCFG[c]['.(($k+1)*2).'][fieldname]" value="'.htmlspecialchars($confData['fieldname']).'" title="'.$GLOBALS['LANG']->getLL('forms_fieldName',1).'" />';
503 }
504
505 // Field configuration depending on the fields type:
506 switch((string)$confData['type']) {
507 case 'textarea':
508 $temp_cells[$GLOBALS['LANG']->getLL('forms_cols')]='<input type="text"'.$this->doc->formWidth(5).' name="FORMCFG[c]['.(($k+1)*2).'][cols]" value="'.htmlspecialchars($confData['cols']).'" title="'.$GLOBALS['LANG']->getLL('forms_cols',1).'" />';
509 $temp_cells[$GLOBALS['LANG']->getLL('forms_rows')]='<input type="text"'.$this->doc->formWidth(5).' name="FORMCFG[c]['.(($k+1)*2).'][rows]" value="'.htmlspecialchars($confData['rows']).'" title="'.$GLOBALS['LANG']->getLL('forms_rows',1).'" />';
510 $temp_cells[$GLOBALS['LANG']->getLL('forms_extra')]='<input type="checkbox" name="FORMCFG[c]['.(($k+1)*2).'][extra]" value="OFF"'.($confData['extra']=='OFF'?' checked="checked"':'').' title="'.$GLOBALS['LANG']->getLL('forms_extra',1).'" />';
511 break;
512 case 'input':
513 case 'password':
514 $temp_cells[$GLOBALS['LANG']->getLL('forms_size')]='<input type="text"'.$this->doc->formWidth(5).' name="FORMCFG[c]['.(($k+1)*2).'][size]" value="'.htmlspecialchars($confData['size']).'" title="'.$GLOBALS['LANG']->getLL('forms_size',1).'" />';
515 $temp_cells[$GLOBALS['LANG']->getLL('forms_max')]='<input type="text"'.$this->doc->formWidth(5).' name="FORMCFG[c]['.(($k+1)*2).'][max]" value="'.htmlspecialchars($confData['max']).'" title="'.$GLOBALS['LANG']->getLL('forms_max',1).'" />';
516 break;
517 case 'file':
518 $temp_cells[$GLOBALS['LANG']->getLL('forms_size')]='<input type="text"'.$this->doc->formWidth(5).' name="FORMCFG[c]['.(($k+1)*2).'][size]" value="'.htmlspecialchars($confData['size']).'" title="'.$GLOBALS['LANG']->getLL('forms_size',1).'" />';
519 break;
520 case 'select':
521 $temp_cells[$GLOBALS['LANG']->getLL('forms_size')]='<input type="text"'.$this->doc->formWidth(5).' name="FORMCFG[c]['.(($k+1)*2).'][size]" value="'.htmlspecialchars($confData['size']).'" title="'.$GLOBALS['LANG']->getLL('forms_size',1).'" />';
522 $temp_cells[$GLOBALS['LANG']->getLL('forms_autosize')]='<input type="checkbox" name="FORMCFG[c]['.(($k+1)*2).'][autosize]" value="1"'.($confData['autosize']?' checked="checked"':'').' title="'.$GLOBALS['LANG']->getLL('forms_autosize',1).'" />';
523 $temp_cells[$GLOBALS['LANG']->getLL('forms_multiple')]='<input type="checkbox" name="FORMCFG[c]['.(($k+1)*2).'][multiple]" value="1"'.($confData['multiple']?' checked="checked"':'').' title="'.$GLOBALS['LANG']->getLL('forms_multiple',1).'" />';
524 break;
525 }
526
527 // Field configuration depending on the fields type:
528 switch((string)$confData['type']) {
529 case 'textarea':
530 case 'input':
531 case 'password':
532 if (strlen(trim($confData['specialEval']))) {
533 $hiddenFields[] = '<input type="hidden" name="FORMCFG[c]['.(($k+1)*2).'][specialEval]" value="'.htmlspecialchars($confData['specialEval']).'" />';
534 }
535 break;
536 }
537
538 // Default data
539 if ($confData['type']=='select' || $confData['type']=='radio') {
540 $temp_cells[$GLOBALS['LANG']->getLL('forms_options')]='<textarea '.$this->doc->formWidthText(15).' rows="4" name="FORMCFG[c]['.(($k+1)*2).'][options]" title="'.$GLOBALS['LANG']->getLL('forms_options',1).'">'.t3lib_div::formatForTextarea($confData['default']).'</textarea>';
541 } elseif ($confData['type']=='check') {
542 $temp_cells[$GLOBALS['LANG']->getLL('forms_checked')]='<input type="checkbox" name="FORMCFG[c]['.(($k+1)*2).'][default]" value="1"'.(trim($confData['default'])?' checked="checked"':'').' title="'.$GLOBALS['LANG']->getLL('forms_checked',1).'" />';
543 } elseif ($confData['type'] && $confData['type']!='file') {
544 $temp_cells[$GLOBALS['LANG']->getLL('forms_default')]='<input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[c]['.(($k+1)*2).'][default]" value="'.htmlspecialchars($confData['default']).'" title="'.$GLOBALS['LANG']->getLL('forms_default',1).'" />';
545 }
546
547 $cells[]=$confData['type']?$this->formatCells($temp_cells):'';
548
549 // CTRL panel for an item (move up/down/around):
550 $ctrl='';
551 $onClick="document.wizardForm.action+='#ANC_".(($k+1)*2-2)."';";
552 $onClick=' onclick="'.htmlspecialchars($onClick).'"';
553 // FIXME $inputStyle undefined
554 $brTag=$inputStyle?'':'<br />';
555 if ($k!=0) {
556 $ctrl.='<input type="image" name="FORMCFG[row_up]['.(($k+1)*2).']"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/pil2up.gif','').$onClick.' title="'.$GLOBALS['LANG']->getLL('table_up',1).'" />'.$brTag;
557 } else {
558 $ctrl.='<input type="image" name="FORMCFG[row_bottom]['.(($k+1)*2).']"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/turn_up.gif','').$onClick.' title="'.$GLOBALS['LANG']->getLL('table_bottom',1).'" />'.$brTag;
559 }
560 $ctrl.='<input type="image" name="FORMCFG[row_remove]['.(($k+1)*2).']"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/garbage.gif','').$onClick.' title="'.$GLOBALS['LANG']->getLL('table_removeRow',1).'" />'.$brTag;
561 // FIXME $tLines undefined
562 if (($k+1)!=count($tLines)) {
563 $ctrl.='<input type="image" name="FORMCFG[row_down]['.(($k+1)*2).']"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/pil2down.gif','').$onClick.' title="'.$GLOBALS['LANG']->getLL('table_down',1).'" />'.$brTag;
564 } else {
565 $ctrl.='<input type="image" name="FORMCFG[row_top]['.(($k+1)*2).']"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/turn_down.gif','').$onClick.' title="'.$GLOBALS['LANG']->getLL('table_top',1).'" />'.$brTag;
566 }
567 $ctrl.='<input type="image" name="FORMCFG[row_add]['.(($k+1)*2).']"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/add.gif','').$onClick.' title="'.$GLOBALS['LANG']->getLL('table_addRow',1).'" />'.$brTag;
568
569 $ctrl='<span class="c-wizButtonsV">'.$ctrl.'</span>';
570
571 // Finally, put together the full row from the generated content above:
572 $bgC = $confData['type']?' class="bgColor5"':'';
573 $tRows[]='
574 <tr'.$bgC.'>
575 <td><a name="ANC_'.(($k+1)*2).'"></a>'.$ctrl.'</td>
576 <td class="bgColor4">'.implode('</td>
577 <td valign="top">',$cells).'</td>
578 </tr>';
579 }
580 } else {
581 $hiddenFields[]='<input type="hidden" name="FORMCFG[c]['.(($k+1)*2).'][comment]" value="'.htmlspecialchars($confData['comment']).'" />';
582 }
583
584 // Increment counter:
585 $k++;
586 }
587
588 // If the form is of the special type "formtype_mail" (used for tt_content elements):
589 if ($this->special=='formtype_mail') {
590
591 // Blank spacer:
592 $tRows[]='
593 <tr>
594 <td colspan="4">&nbsp;</td>
595 </tr>';
596
597 // Header:
598 $tRows[]='
599 <tr>
600 <td colspan="2" class="bgColor2">&nbsp;</td>
601 <td colspan="2" class="bgColor2"><strong>'.$GLOBALS['LANG']->getLL('forms_special_eform',1).':</strong>'.
602 t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_formmail_info', $GLOBALS['BACK_PATH'],'').
603 '</td>
604 </tr>';
605
606 // "FORM type":
607 $tRows[]='
608 <tr class="bgColor5">
609 <td>&nbsp;</td>
610 <td class="bgColor4">&nbsp;</td>
611 <td>'.$GLOBALS['LANG']->getLL('forms_eform_formtype_mail',1).':</td>
612 <td>
613 <input type="hidden" name="FORMCFG[c]['.(1000*2).'][fieldname]" value="formtype_mail" />
614 <input type="hidden" name="FORMCFG[c]['.(1000*2).'][type]" value="submit" />
615 <input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[c]['.(1000*2).'][default]" value="'.htmlspecialchars($specParts['formtype_mail']).'" />
616 </td>
617 </tr>';
618
619 // "Send HTML mail":
620 $tRows[]='
621 <tr class="bgColor5">
622 <td>&nbsp;</td>
623 <td class="bgColor4">&nbsp;</td>
624 <td>'.$GLOBALS['LANG']->getLL('forms_eform_html_enabled',1).':</td>
625 <td>
626 <input type="hidden" name="FORMCFG[c]['.(1001*2).'][fieldname]" value="html_enabled" />
627 <input type="hidden" name="FORMCFG[c]['.(1001*2).'][type]" value="hidden" />
628 <input type="checkbox" name="FORMCFG[c]['.(1001*2).'][default]" value="1"'.($specParts['html_enabled']?' checked="checked"':'').' />
629 </td>
630 </tr>';
631
632 // "Subject":
633 $tRows[]='
634 <tr class="bgColor5">
635 <td>&nbsp;</td>
636 <td class="bgColor4">&nbsp;</td>
637 <td>'.$GLOBALS['LANG']->getLL('forms_eform_subject',1).':</td>
638 <td>
639 <input type="hidden" name="FORMCFG[c]['.(1002*2).'][fieldname]" value="subject" />
640 <input type="hidden" name="FORMCFG[c]['.(1002*2).'][type]" value="hidden" />
641 <input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[c]['.(1002*2).'][default]" value="'.htmlspecialchars($specParts['subject']).'" />
642 </td>
643 </tr>';
644
645 // Recipient:
646 $tRows[]='
647 <tr class="bgColor5">
648 <td>&nbsp;</td>
649 <td class="bgColor4">&nbsp;</td>
650 <td>'.$GLOBALS['LANG']->getLL('forms_eform_recipient',1).':</td>
651 <td>
652 <input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[recipient]" value="'.htmlspecialchars($row['subheader']).'" />
653 </td>
654 </tr>';
655 }
656
657 $content = '';
658
659 // Implode all table rows into a string, wrapped in table tags.
660 $content.= '
661
662 <!--
663 Form wizard
664 -->
665 <table border="0" cellpadding="1" cellspacing="1" id="typo3-formwizard">
666 '.implode('',$tRows).'
667 </table>';
668
669 // Add hidden fields:
670 $content.= implode('',$hiddenFields);
671
672 // Return content:
673 return $content;
674 }
675
676 /**
677 * Detects if a control button (up/down/around/delete) has been pressed for an item and accordingly it will manipulate the internal FORMCFG array
678 *
679 * @return void
680 * @access private
681 */
682 function changeFunc() {
683 if ($this->FORMCFG['row_remove']) {
684 $kk = key($this->FORMCFG['row_remove']);
685 $cmd='row_remove';
686 } elseif ($this->FORMCFG['row_add']) {
687 $kk = key($this->FORMCFG['row_add']);
688 $cmd='row_add';
689 } elseif ($this->FORMCFG['row_top']) {
690 $kk = key($this->FORMCFG['row_top']);
691 $cmd='row_top';
692 } elseif ($this->FORMCFG['row_bottom']) {
693 $kk = key($this->FORMCFG['row_bottom']);
694 $cmd='row_bottom';
695 } elseif ($this->FORMCFG['row_up']) {
696 $kk = key($this->FORMCFG['row_up']);
697 $cmd='row_up';
698 } elseif ($this->FORMCFG['row_down']) {
699 $kk = key($this->FORMCFG['row_down']);
700 $cmd='row_down';
701 }
702
703 if ($cmd && t3lib_div::testInt($kk)) {
704 if (substr($cmd,0,4)=='row_') {
705 switch($cmd) {
706 case 'row_remove':
707 unset($this->FORMCFG['c'][$kk]);
708 break;
709 case 'row_add':
710 $this->FORMCFG['c'][$kk+1]=array();
711 break;
712 case 'row_top':
713 $this->FORMCFG['c'][1]=$this->FORMCFG['c'][$kk];
714 unset($this->FORMCFG['c'][$kk]);
715 break;
716 case 'row_bottom':
717 $this->FORMCFG['c'][1000000]=$this->FORMCFG['c'][$kk];
718 unset($this->FORMCFG['c'][$kk]);
719 break;
720 case 'row_up':
721 $this->FORMCFG['c'][$kk-3]=$this->FORMCFG['c'][$kk];
722 unset($this->FORMCFG['c'][$kk]);
723 break;
724 case 'row_down':
725 $this->FORMCFG['c'][$kk+3]=$this->FORMCFG['c'][$kk];
726 unset($this->FORMCFG['c'][$kk]);
727 break;
728 }
729 ksort($this->FORMCFG['c']);
730 }
731 }
732 }
733
734 /**
735 * Converts the input array to a configuration code string
736 *
737 * @param array Array of form configuration (follows the input structure from the form wizard POST form)
738 * @return string The array converted into a string with line-based configuration.
739 * @see cfgString2CfgArray()
740 */
741 function cfgArray2CfgString($cfgArr) {
742
743 // Initialize:
744 $inLines=array();
745
746 // Traverse the elements of the form wizard and transform the settings into configuration code.
747 foreach($cfgArr as $vv) {
748 if ($vv['comment']) { // If "content" is found, then just pass it over.
749 $inLines[]=trim($vv['comment']);
750 } else { // Begin to put together the single-line configuration code of this field:
751
752 // Reset:
753 $thisLine=array();
754
755 // Set Label:
756 $thisLine[0]=str_replace('|','',$vv['label']);
757
758 // Set Type:
759 if ($vv['type']) {
760 $thisLine[1]=($vv['required']?'*':'').str_replace(',','',($vv['fieldname']?$vv['fieldname'].'=':'').$vv['type']);
761
762 // Default:
763 $tArr=array('','','','','','');
764 switch((string)$vv['type']) {
765 case 'textarea':
766 if (intval($vv['cols'])) $tArr[0]=intval($vv['cols']);
767 if (intval($vv['rows'])) $tArr[1]=intval($vv['rows']);
768 if (trim($vv['extra'])) $tArr[2]=trim($vv['extra']);
769 if (strlen($vv['specialEval'])) {
770 $thisLine[2] = ''; // Preset blank default value so position 3 can get a value...
771 $thisLine[3] = $vv['specialEval'];
772 }
773 break;
774 case 'input':
775 case 'password':
776 if (intval($vv['size'])) $tArr[0]=intval($vv['size']);
777 if (intval($vv['max'])) $tArr[1]=intval($vv['max']);
778 if (strlen($vv['specialEval'])) {
779 $thisLine[2] = ''; // Preset blank default value so position 3 can get a value...
780 $thisLine[3] = $vv['specialEval'];
781 }
782 break;
783 case 'file':
784 if (intval($vv['size'])) $tArr[0]=intval($vv['size']);
785 break;
786 case 'select':
787 if (intval($vv['size'])) $tArr[0]=intval($vv['size']);
788 if ($vv['autosize']) $tArr[0]='auto';
789 if ($vv['multiple']) $tArr[1]='m';
790 break;
791 }
792 $tArr = $this->cleanT($tArr);
793 if (count($tArr)) $thisLine[1].=','.implode(',',$tArr);
794
795 $thisLine[1]=str_replace('|','',$thisLine[1]);
796
797 // Default:
798 if ($vv['type']=='select' || $vv['type']=='radio') {
799 $thisLine[2]=str_replace(LF,', ',str_replace(',','',$vv['options']));
800 } elseif ($vv['type']=='check') {
801 if ($vv['default']) $thisLine[2]=1;
802 } elseif (strcmp(trim($vv['default']),'')) {
803 $thisLine[2]=$vv['default'];
804 }
805 if (isset($thisLine[2])) $thisLine[2]=str_replace('|','',$thisLine[2]);
806 }
807
808 // Compile the final line:
809 $inLines[]=preg_replace("/[\n\r]*/",'',implode(' | ',$thisLine));
810 }
811 }
812 // Finally, implode the lines into a string, and return it:
813 return implode(LF,$inLines);
814 }
815
816 /**
817 * Converts the input configuration code string into an array
818 *
819 * @param string Configuration code
820 * @return array Configuration array
821 * @see cfgArray2CfgString()
822 */
823 function cfgString2CfgArray($cfgStr) {
824
825 // Traverse the number of form elements:
826 $tLines=explode(LF,$cfgStr);
827 foreach($tLines as $k => $v) {
828
829 // Initialize:
830 $confData=array();
831 $val=trim($v);
832
833 // Accept a line as configuration if a) it is blank(! - because blank lines indicates new, unconfigured fields) or b) it is NOT a comment.
834 if (!$val || strcspn($val,'#/')) {
835
836 // Split:
837 $parts = t3lib_div::trimExplode('|',$val);
838
839 // Label:
840 $confData['label'] = trim($parts[0]);
841
842 // Field:
843 $fParts = t3lib_div::trimExplode(',',$parts[1]);
844 $fParts[0]=trim($fParts[0]);
845 if (substr($fParts[0],0,1)=='*') {
846 $confData['required'] = 1;
847 $fParts[0] = substr($fParts[0],1);
848 }
849
850 $typeParts = t3lib_div::trimExplode('=',$fParts[0]);
851 $confData['type'] = trim(strtolower(end($typeParts)));
852
853 if ($confData['type']) {
854 if (count($typeParts)==1) {
855 $confData['fieldname'] = substr(preg_replace('/[^a-zA-Z0-9_]/','',str_replace(' ','_',trim($parts[0]))),0,30);
856
857 // Attachment names...
858 if ($confData['type']=='file') {
859 $confData['fieldname']='attachment'.$attachmentCounter;
860 $attachmentCounter=intval($attachmentCounter)+1;
861 }
862 } else {
863 $confData['fieldname'] = str_replace(' ','_',trim($typeParts[0]));
864 }
865
866 switch((string)$confData['type']) {
867 case 'select':
868 case 'radio':
869 $confData['default'] = implode(LF,t3lib_div::trimExplode(',',$parts[2]));
870 break;
871 default:
872 $confData['default'] = trim($parts[2]);
873 break;
874 }
875
876 // Field configuration depending on the fields type:
877 switch((string)$confData['type']) {
878 case 'textarea':
879 $confData['cols'] = $fParts[1];
880 $confData['rows'] = $fParts[2];
881 $confData['extra'] = strtoupper($fParts[3])=='OFF' ? 'OFF' : '';
882 $confData['specialEval'] = trim($parts[3]);
883 break;
884 case 'input':
885 case 'password':
886 $confData['size'] = $fParts[1];
887 $confData['max'] = $fParts[2];
888 $confData['specialEval'] = trim($parts[3]);
889 break;
890 case 'file':
891 $confData['size'] = $fParts[1];
892 break;
893 case 'select':
894 $confData['size'] = intval($fParts[1])?$fParts[1]:'';
895 $confData['autosize'] = strtolower(trim($fParts[1]))=='auto' ? 1 : 0;
896 $confData['multiple'] = strtolower(trim($fParts[2]))=='m' ? 1 : 0;
897 break;
898 }
899 }
900 } else {
901 // No configuration, only a comment:
902 $confData=array(
903 'comment' => $val
904 );
905 }
906
907 // Adding config array:
908 $cfgArr[]=$confData;
909 }
910
911 // Return cfgArr
912 return $cfgArr;
913 }
914
915 /**
916 * Removes any "trailing elements" in the array which consists of whitespace (little like trim() does for strings, so this does for arrays)
917 *
918 * @param array Single dim array
919 * @return array Processed array
920 * @access private
921 */
922 function cleanT($tArr) {
923 for($a=count($tArr);$a>0;$a--) {
924 if (strcmp($tArr[$a-1],'')) {
925 break;
926 } else {
927 unset($tArr[$a-1]);
928 }
929 }
930 return $tArr;
931 }
932
933 /**
934 * Wraps items in $fArr in table cells/rows, displaying them vertically.
935 *
936 * @param array Array of label/HTML pairs.
937 * @return string HTML table
938 * @access private
939 */
940 function formatCells($fArr) {
941
942 // Traverse the elements in $fArr and wrap them in table cells:
943 $lines=array();
944 foreach($fArr as $l => $c) {
945 $lines[]='
946 <tr>
947 <td nowrap="nowrap">'.htmlspecialchars($l.':').'&nbsp;</td>
948 <td>'.$c.'</td>
949 </tr>';
950 }
951
952 // Add a cell which will set a minimum width:
953 $lines[]='
954 <tr>
955 <td nowrap="nowrap"><img src="clear.gif" width="70" height="1" alt="" /></td>
956 <td></td>
957 </tr>';
958
959 // Wrap in table and return:
960 return '
961 <table border="0" cellpadding="0" cellspacing="0">
962 '.implode('',$lines).'
963 </table>';
964 }
965 }
966
967
968 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/wizard_forms.php'])) {
969 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/wizard_forms.php']);
970 }
971
972
973
974 // Make instance:
975 $SOBE = t3lib_div::makeInstance('SC_wizard_forms');
976 $SOBE->init();
977
978 // Include files?
979 foreach($SOBE->include_once as $INC_FILE) include_once($INC_FILE);
980
981 $SOBE->main();
982 $SOBE->printContent();
983
984 ?>