2 /***************************************************************
5 * (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
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.
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.
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.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
28 * Wizard to help make forms (fx. for tt_content elements) of type 'form'.
31 * Revised for TYPO3 3.6 November/2003 by Kasper Skaarhoj
34 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
37 * [CLASS/FUNCTION INDEX of SCRIPT]
41 * 175: class SC_wizard_forms
42 * 203: function init()
43 * 242: function main()
44 * 257: function printContent()
45 * 268: function formsWizard()
47 * SECTION: Helper functions
48 * 311: function getConfigCode(&$row)
49 * 382: function getFormHTML($formCfgArray,$row)
50 * 662: function changeFunc()
51 * 721: function cfgArray2CfgString($cfgArr)
52 * 803: function cfgString2CfgArray($cfgStr)
53 * 902: function cleanT($tArr)
54 * 920: function formatCells($fArr)
57 * (This index is automatically created/updated by the extension "extdeveval")
65 require ('template.php');
66 $LANG->includeLLFile('EXT:lang/locallang_wizards.xml');
82 * 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.
84 * The format for the resulting configuration code can be either a line-based configuration. That can look like this:
86 * Your name: | *name=input | (input your name here!)
87 * Your Email: | *email=input
88 * Your address: | address=textarea,40,10
89 * Your Haircolor: | hair=radio |
90 * upload | attachment=file
91 * | quoted_printable=hidden | 0
92 * | formtype_mail=submit | Send form
93 * | html_enabled=hidden
94 * | subject=hidden | This is the subject
97 * Alternatively it can be XML. The same configuration from above looks like this in XML:
102 * <label>Your name:</label>
103 * <required>1</required>
104 * <fieldname>name</fieldname>
107 * <default>(input your name here!)</default>
111 * <label>Your Email:</label>
112 * <required>1</required>
113 * <fieldname>email</fieldname>
116 * <default></default>
119 * <type>textarea</type>
120 * <label>Your address:</label>
121 * <fieldname>address</fieldname>
124 * <default></default>
128 * <label>Your Haircolor:</label>
129 * <fieldname>hair</fieldname>
130 * <options></options>
134 * <label>upload</label>
135 * <fieldname>attachment</fieldname>
139 * <type>hidden</type>
141 * <fieldname>quoted_printable</fieldname>
142 * <default>0</default>
145 * <fieldname>formtype_mail</fieldname>
146 * <type>submit</type>
147 * <default>Send form</default>
150 * <fieldname>html_enabled</fieldname>
151 * <type>hidden</type>
154 * <fieldname>subject</fieldname>
155 * <type>hidden</type>
156 * <default>This is the subject</default>
159 * <content></content>
164 * The XML/phpArray structure is the internal format of the wizard.
169 * Script Class for rendering the Form Wizard
171 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
175 class SC_wizard_forms
{
177 // Internal, dynamic:
179 * document template object
184 var $content; // Content accumulation for the module.
185 var $include_once=array(); // List of files to include.
186 var $attachmentCounter = 0; // Used to numerate attachments automatically.
190 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!
193 // Internal, static: GPvars
194 var $P; // Wizard parameters, coming from TCEforms linking to the wizard.
195 var $FORMCFG; // The array which is constantly submitted by the multidimensional form of this wizard.
196 var $special; // Indicates if the form is of a dedicated type, like "formtype_mail" (for tt_content element "Form")
204 * Initialization the class
210 $this->P
= t3lib_div
::_GP('P');
211 $this->special
= t3lib_div
::_GP('special');
212 $this->FORMCFG
= t3lib_div
::_GP('FORMCFG');
215 $this->xmlStorage
= $this->P
['params']['xmlOutput'];
217 // Document template object:
218 $this->doc
= t3lib_div
::makeInstance('template');
219 $this->doc
->backPath
= $GLOBALS['BACK_PATH'];
220 $this->doc
->setModuleTemplate('templates/wizard_forms.html');
221 $this->doc
->JScode
=$this->doc
->wrapScriptTags('
222 function jumpToUrl(URL,formEl) { //
223 window.location.href = URL;
228 list($rUri) = explode('#',t3lib_div
::getIndpEnv('REQUEST_URI'));
229 $this->doc
->form
='<form action="'.htmlspecialchars($rUri).'" method="post" name="wizardForm">';
231 // If save command found, include tcemain:
232 if ($_POST['savedok_x'] ||
$_POST['saveandclosedok_x']) {
233 $this->include_once[]=PATH_t3lib
.'class.t3lib_tcemain.php';
238 * Main function for rendering the form wizard HTML
243 if ($this->P
['table'] && $this->P
['field'] && $this->P
['uid']) {
244 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('forms_title'), $this->formsWizard(), 0, 1);
246 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('forms_title'), '<span class="typo3-red">' . $GLOBALS['LANG']->getLL('table_noData',1) . '</span>', 0, 1);
249 // Setting up the buttons and markers for docheader
250 $docHeaderButtons = $this->getButtons();
251 $markers['CSH'] = $docHeaderButtons['csh'];
252 $markers['CONTENT'] = $this->content
;
254 // Build the <body> for the module
255 $this->content
= $this->doc
->startPage('Form Wizard');
256 $this->content
.= $this->doc
->moduleBody($this->pageinfo
, $docHeaderButtons, $markers);
257 $this->content
.= $this->doc
->endPage();
258 $this->content
= $this->doc
->insertStylesAndJS($this->content
);
262 * Outputting the accumulated content to screen
266 function printContent() {
271 * Create the panel of buttons for submitting the form or otherwise perform operations.
273 * @return array all available buttons as an assoc. array
275 protected function getButtons() {
285 if ($this->P
['table'] && $this->P
['field'] && $this->P
['uid']) {
287 $buttons['csh'] = t3lib_BEfunc
::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz', $GLOBALS['BACK_PATH'], '');
290 $buttons['csh_buttons'] = t3lib_BEfunc
::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_buttons', $GLOBALS['BACK_PATH'], '');
293 $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(unescape(\'' . rawurlencode($this->P
['returnUrl']) . '\')); return false;') . '">' .
294 '<img' . t3lib_iconWorks
::skinImg($this->doc
->backPath
, 'gfx/closedok.gif') . ' class="c-inputButton" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc', 1) . '" alt="" />' .
298 $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) . '" />';
301 $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) . '" />';
304 $buttons['reload'] = '<input type="image" class="c-inputButton" name="_refresh"' . t3lib_iconWorks
::skinImg('', 'gfx/refresh_n.gif') . ' title="' . $GLOBALS['LANG']->getLL('forms_refresh', 1) . '" />';
311 * Draws the form wizard content
313 * @return string HTML content for the form.
315 function formsWizard() {
317 // First, check the references by selecting the record:
318 $row = t3lib_BEfunc
::getRecord($this->P
['table'],$this->P
['uid']);
319 if (!is_array($row)) {
320 t3lib_BEfunc
::typo3PrintError ('Wizard Error','No reference to record',0);
324 // 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.
325 $formCfgArray = $this->getConfigCode($row);
327 // Generation of the Form Wizards HTML code:
328 $content = $this->getFormHTML($formCfgArray,$row);
344 /****************************
348 ***************************/
351 * Will get and return the configuration code string
352 * Will also save (and possibly redirect/exit) the content if a save button has been pressed
354 * @param array Current parent record row (passed by value!)
355 * @return array Configuration Array
358 function getConfigCode(&$row) {
360 // If some data has been submitted, then construct
361 if (isset($this->FORMCFG
['c'])) {
366 // Convert to string (either line based or XML):
367 if ($this->xmlStorage
) {
368 // Convert the input array to XML:
369 $bodyText = t3lib_div
::array2xml_cs($this->FORMCFG
['c'],'T3FormWizard');
371 // Setting cfgArr directly from the input:
372 $cfgArr = $this->FORMCFG
['c'];
374 // Convert the input array to a string of configuration code:
375 $bodyText = $this->cfgArray2CfgString($this->FORMCFG
['c']);
377 // Create cfgArr from the string based configuration - that way it is cleaned up and any incompatibilities will be removed!
378 $cfgArr = $this->cfgString2CfgArray($bodyText);
381 // If a save button has been pressed, then save the new field content:
382 if ($_POST['savedok_x'] ||
$_POST['saveandclosedok_x']) {
384 // Make TCEmain object:
385 $tce = t3lib_div
::makeInstance('t3lib_TCEmain');
386 $tce->stripslashes_values
=0;
388 // Put content into the data array:
390 $data[$this->P
['table']][$this->P
['uid']][$this->P
['field']]=$bodyText;
391 if ($this->special
=='formtype_mail') {
392 $data[$this->P
['table']][$this->P
['uid']]['subheader']=$this->FORMCFG
['recipient'];
395 // Perform the update:
396 $tce->start($data,array());
397 $tce->process_datamap();
399 // Re-load the record content:
400 $row = t3lib_BEfunc
::getRecord($this->P
['table'],$this->P
['uid']);
402 // If the save/close button was pressed, then redirect the screen:
403 if ($_POST['saveandclosedok_x']) {
404 header('Location: '.t3lib_div
::locationHeaderUrl($this->P
['returnUrl']));
408 } else { // If nothing has been submitted, load the $bodyText variable from the selected database row:
409 if ($this->xmlStorage
) {
410 $cfgArr = t3lib_div
::xml2array($row[$this->P
['field']]);
411 } else { // Regular linebased form configuration:
412 $cfgArr = $this->cfgString2CfgArray($row[$this->P
['field']]);
414 $cfgArr = is_array($cfgArr) ?
$cfgArr : array();
417 // Return configuration code:
422 * Creates the HTML for the Form Wizard:
424 * @param string Form config array
425 * @param array Current parent record array
426 * @return string HTML for the form wizard
429 function getFormHTML($formCfgArray,$row) {
432 // Initialize variables:
434 $hiddenFields=array();
438 $cells=array($LANG->getLL('forms_preview',1).':',
439 $LANG->getLL('forms_element',1).':',
440 $LANG->getLL('forms_config',1).':',
443 <tr class="bgColor2" id="typo3-formWizardHeader">
449 // Traverse the number of form elements:
451 foreach($formCfgArray as $confData) {
456 // If there is a configuration line which is active, then render it:
457 if (!isset($confData['comment'])) {
460 if ($this->special
=='formtype_mail' && t3lib_div
::inList('formtype_mail,subject,html_enabled',$confData['fieldname'])) {
461 $specParts[$confData['fieldname']] = $confData['default'];
464 // Render title/field preview COLUMN
465 $cells[]=$confData['type']!='hidden' ?
'<strong>'.htmlspecialchars($confData['label']).'</strong>' : '';
468 // Render general type/title COLUMN:
471 // Field type selector:
473 $opt[]='<option value=""></option>';
474 $types = explode(',','input,textarea,select,check,radio,password,file,hidden,submit,property,label');
475 foreach($types as $t) {
477 <option value="'.$t.'"'.($confData['type']==$t?
' selected="selected"':'').'>'.$LANG->getLL('forms_type_'.$t,1).'</option>';
479 $temp_cells[$LANG->getLL('forms_type')]='
480 <select name="FORMCFG[c]['.(($k+
1)*2).'][type]">
486 if (!t3lib_div
::inList('hidden,submit',$confData['type'])) {
487 $temp_cells[$LANG->getLL('forms_label')]='<input type="text"'.$this->doc
->formWidth(15).' name="FORMCFG[c]['.(($k+
1)*2).'][label]" value="'.htmlspecialchars($confData['label']).'" />';
490 // Required checkbox:
491 if (!t3lib_div
::inList('check,hidden,submit,label',$confData['type'])) {
492 $temp_cells[$LANG->getLL('forms_required')]='<input type="checkbox" name="FORMCFG[c]['.(($k+
1)*2).'][required]" value="1"'.($confData['required']?
' checked="checked"':'').' title="'.$LANG->getLL('forms_required',1).'" />';
495 // Put sub-items together into table cell:
496 $cells[]=$this->formatCells($temp_cells);
499 // Render specific field configuration COLUMN:
503 if ($this->special
=='formtype_mail' && $confData['type']=='file') {
504 $confData['fieldname'] = 'attachment'.(++
$this->attachmentCounter
);
506 if (!t3lib_div
::inList('label',$confData['type'])) {
507 $temp_cells[$LANG->getLL('forms_fieldName')]='<input type="text"'.$this->doc
->formWidth(10).' name="FORMCFG[c]['.(($k+
1)*2).'][fieldname]" value="'.htmlspecialchars($confData['fieldname']).'" title="'.$LANG->getLL('forms_fieldName',1).'" />';
510 // Field configuration depending on the fields type:
511 switch((string)$confData['type']) {
513 $temp_cells[$LANG->getLL('forms_cols')]='<input type="text"'.$this->doc
->formWidth(5).' name="FORMCFG[c]['.(($k+
1)*2).'][cols]" value="'.htmlspecialchars($confData['cols']).'" title="'.$LANG->getLL('forms_cols',1).'" />';
514 $temp_cells[$LANG->getLL('forms_rows')]='<input type="text"'.$this->doc
->formWidth(5).' name="FORMCFG[c]['.(($k+
1)*2).'][rows]" value="'.htmlspecialchars($confData['rows']).'" title="'.$LANG->getLL('forms_rows',1).'" />';
515 $temp_cells[$LANG->getLL('forms_extra')]='<input type="checkbox" name="FORMCFG[c]['.(($k+
1)*2).'][extra]" value="OFF"'.($confData['extra']=='OFF'?
' checked="checked"':'').' title="'.$LANG->getLL('forms_extra',1).'" />';
519 $temp_cells[$LANG->getLL('forms_size')]='<input type="text"'.$this->doc
->formWidth(5).' name="FORMCFG[c]['.(($k+
1)*2).'][size]" value="'.htmlspecialchars($confData['size']).'" title="'.$LANG->getLL('forms_size',1).'" />';
520 $temp_cells[$LANG->getLL('forms_max')]='<input type="text"'.$this->doc
->formWidth(5).' name="FORMCFG[c]['.(($k+
1)*2).'][max]" value="'.htmlspecialchars($confData['max']).'" title="'.$LANG->getLL('forms_max',1).'" />';
523 $temp_cells[$LANG->getLL('forms_size')]='<input type="text"'.$this->doc
->formWidth(5).' name="FORMCFG[c]['.(($k+
1)*2).'][size]" value="'.htmlspecialchars($confData['size']).'" title="'.$LANG->getLL('forms_size',1).'" />';
526 $temp_cells[$LANG->getLL('forms_size')]='<input type="text"'.$this->doc
->formWidth(5).' name="FORMCFG[c]['.(($k+
1)*2).'][size]" value="'.htmlspecialchars($confData['size']).'" title="'.$LANG->getLL('forms_size',1).'" />';
527 $temp_cells[$LANG->getLL('forms_autosize')]='<input type="checkbox" name="FORMCFG[c]['.(($k+
1)*2).'][autosize]" value="1"'.($confData['autosize']?
' checked="checked"':'').' title="'.$LANG->getLL('forms_autosize',1).'" />';
528 $temp_cells[$LANG->getLL('forms_multiple')]='<input type="checkbox" name="FORMCFG[c]['.(($k+
1)*2).'][multiple]" value="1"'.($confData['multiple']?
' checked="checked"':'').' title="'.$LANG->getLL('forms_multiple',1).'" />';
532 // Field configuration depending on the fields type:
533 switch((string)$confData['type']) {
537 if (strlen(trim($confData['specialEval']))) {
538 $hiddenFields[] = '<input type="hidden" name="FORMCFG[c]['.(($k+
1)*2).'][specialEval]" value="'.htmlspecialchars($confData['specialEval']).'" />';
544 if ($confData['type']=='select' ||
$confData['type']=='radio') {
545 $temp_cells[$LANG->getLL('forms_options')]='<textarea '.$this->doc
->formWidthText(15).' rows="4" name="FORMCFG[c]['.(($k+
1)*2).'][options]" title="'.$LANG->getLL('forms_options',1).'">'.t3lib_div
::formatForTextarea($confData['default']).'</textarea>';
546 } elseif ($confData['type']=='check') {
547 $temp_cells[$LANG->getLL('forms_checked')]='<input type="checkbox" name="FORMCFG[c]['.(($k+
1)*2).'][default]" value="1"'.(trim($confData['default'])?
' checked="checked"':'').' title="'.$LANG->getLL('forms_checked',1).'" />';
548 } elseif ($confData['type'] && $confData['type']!='file') {
549 $temp_cells[$LANG->getLL('forms_default')]='<input type="text"'.$this->doc
->formWidth(15).' name="FORMCFG[c]['.(($k+
1)*2).'][default]" value="'.htmlspecialchars($confData['default']).'" title="'.$LANG->getLL('forms_default',1).'" />';
552 $cells[]=$confData['type']?
$this->formatCells($temp_cells):'';
554 // CTRL panel for an item (move up/down/around):
556 $onClick="document.wizardForm.action+='#ANC_".(($k+
1)*2-2)."';";
557 $onClick=' onclick="'.htmlspecialchars($onClick).'"';
558 // FIXME $inputStyle undefined
559 $brTag=$inputStyle?
'':'<br />';
561 $ctrl.='<input type="image" name="FORMCFG[row_up]['.(($k+
1)*2).']"'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/pil2up.gif','').$onClick.' title="'.$LANG->getLL('table_up',1).'" />'.$brTag;
563 $ctrl.='<input type="image" name="FORMCFG[row_bottom]['.(($k+
1)*2).']"'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/turn_up.gif','').$onClick.' title="'.$LANG->getLL('table_bottom',1).'" />'.$brTag;
565 $ctrl.='<input type="image" name="FORMCFG[row_remove]['.(($k+
1)*2).']"'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/garbage.gif','').$onClick.' title="'.$LANG->getLL('table_removeRow',1).'" />'.$brTag;
566 // FIXME $tLines undefined
567 if (($k+
1)!=count($tLines)) {
568 $ctrl.='<input type="image" name="FORMCFG[row_down]['.(($k+
1)*2).']"'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/pil2down.gif','').$onClick.' title="'.$LANG->getLL('table_down',1).'" />'.$brTag;
570 $ctrl.='<input type="image" name="FORMCFG[row_top]['.(($k+
1)*2).']"'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/turn_down.gif','').$onClick.' title="'.$LANG->getLL('table_top',1).'" />'.$brTag;
572 $ctrl.='<input type="image" name="FORMCFG[row_add]['.(($k+
1)*2).']"'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/add.gif','').$onClick.' title="'.$LANG->getLL('table_addRow',1).'" />'.$brTag;
574 $ctrl='<span class="c-wizButtonsV">'.$ctrl.'</span>';
576 // Finally, put together the full row from the generated content above:
577 $bgC = $confData['type']?
' class="bgColor5"':'';
580 <td><a name="ANC_'.(($k+
1)*2).'"></a>'.$ctrl.'</td>
581 <td class="bgColor4">'.implode('</td>
582 <td valign="top">',$cells).'</td>
586 $hiddenFields[]='<input type="hidden" name="FORMCFG[c]['.(($k+
1)*2).'][comment]" value="'.htmlspecialchars($confData['comment']).'" />';
589 // Increment counter:
593 // If the form is of the special type "formtype_mail" (used for tt_content elements):
594 if ($this->special
=='formtype_mail') {
599 <td colspan="4"> </td>
605 <td colspan="2" class="bgColor2"> </td>
606 <td colspan="2" class="bgColor2"><strong>'.$LANG->getLL('forms_special_eform',1).':</strong>'.
607 t3lib_BEfunc
::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_formmail_info', $GLOBALS['BACK_PATH'],'').
613 <tr class="bgColor5">
615 <td class="bgColor4"> </td>
616 <td>'.$LANG->getLL('forms_eform_formtype_mail',1).':</td>
618 <input type="hidden" name="FORMCFG[c]['.(1000*2).'][fieldname]" value="formtype_mail" />
619 <input type="hidden" name="FORMCFG[c]['.(1000*2).'][type]" value="submit" />
620 <input type="text"'.$this->doc
->formWidth(15).' name="FORMCFG[c]['.(1000*2).'][default]" value="'.htmlspecialchars($specParts['formtype_mail']).'" />
626 <tr class="bgColor5">
628 <td class="bgColor4"> </td>
629 <td>'.$LANG->getLL('forms_eform_html_enabled',1).':</td>
631 <input type="hidden" name="FORMCFG[c]['.(1001*2).'][fieldname]" value="html_enabled" />
632 <input type="hidden" name="FORMCFG[c]['.(1001*2).'][type]" value="hidden" />
633 <input type="checkbox" name="FORMCFG[c]['.(1001*2).'][default]" value="1"'.($specParts['html_enabled']?
' checked="checked"':'').' />
639 <tr class="bgColor5">
641 <td class="bgColor4"> </td>
642 <td>'.$LANG->getLL('forms_eform_subject',1).':</td>
644 <input type="hidden" name="FORMCFG[c]['.(1002*2).'][fieldname]" value="subject" />
645 <input type="hidden" name="FORMCFG[c]['.(1002*2).'][type]" value="hidden" />
646 <input type="text"'.$this->doc
->formWidth(15).' name="FORMCFG[c]['.(1002*2).'][default]" value="'.htmlspecialchars($specParts['subject']).'" />
652 <tr class="bgColor5">
654 <td class="bgColor4"> </td>
655 <td>'.$LANG->getLL('forms_eform_recipient',1).':</td>
657 <input type="text"'.$this->doc
->formWidth(15).' name="FORMCFG[recipient]" value="'.htmlspecialchars($row['subheader']).'" />
664 // Implode all table rows into a string, wrapped in table tags.
670 <table border="0" cellpadding="1" cellspacing="1" id="typo3-formwizard">
671 '.implode('',$tRows).'
674 // Add hidden fields:
675 $content.= implode('',$hiddenFields);
682 * Detects if a control button (up/down/around/delete) has been pressed for an item and accordingly it will manipulate the internal FORMCFG array
687 function changeFunc() {
688 if ($this->FORMCFG
['row_remove']) {
689 $kk = key($this->FORMCFG
['row_remove']);
691 } elseif ($this->FORMCFG
['row_add']) {
692 $kk = key($this->FORMCFG
['row_add']);
694 } elseif ($this->FORMCFG
['row_top']) {
695 $kk = key($this->FORMCFG
['row_top']);
697 } elseif ($this->FORMCFG
['row_bottom']) {
698 $kk = key($this->FORMCFG
['row_bottom']);
700 } elseif ($this->FORMCFG
['row_up']) {
701 $kk = key($this->FORMCFG
['row_up']);
703 } elseif ($this->FORMCFG
['row_down']) {
704 $kk = key($this->FORMCFG
['row_down']);
708 if ($cmd && t3lib_div
::testInt($kk)) {
709 if (substr($cmd,0,4)=='row_') {
712 unset($this->FORMCFG
['c'][$kk]);
715 $this->FORMCFG
['c'][$kk+
1]=array();
718 $this->FORMCFG
['c'][1]=$this->FORMCFG
['c'][$kk];
719 unset($this->FORMCFG
['c'][$kk]);
722 $this->FORMCFG
['c'][1000000]=$this->FORMCFG
['c'][$kk];
723 unset($this->FORMCFG
['c'][$kk]);
726 $this->FORMCFG
['c'][$kk-3]=$this->FORMCFG
['c'][$kk];
727 unset($this->FORMCFG
['c'][$kk]);
730 $this->FORMCFG
['c'][$kk+
3]=$this->FORMCFG
['c'][$kk];
731 unset($this->FORMCFG
['c'][$kk]);
734 ksort($this->FORMCFG
['c']);
740 * Converts the input array to a configuration code string
742 * @param array Array of form configuration (follows the input structure from the form wizard POST form)
743 * @return string The array converted into a string with line-based configuration.
744 * @see cfgString2CfgArray()
746 function cfgArray2CfgString($cfgArr) {
751 // Traverse the elements of the form wizard and transform the settings into configuration code.
752 foreach($cfgArr as $vv) {
753 if ($vv['comment']) { // If "content" is found, then just pass it over.
754 $inLines[]=trim($vv['comment']);
755 } else { // Begin to put together the single-line configuration code of this field:
761 $thisLine[0]=str_replace('|','',$vv['label']);
765 $thisLine[1]=($vv['required']?
'*':'').str_replace(',','',($vv['fieldname']?
$vv['fieldname'].'=':'').$vv['type']);
768 $tArr=array('','','','','','');
769 switch((string)$vv['type']) {
771 if (intval($vv['cols'])) $tArr[0]=intval($vv['cols']);
772 if (intval($vv['rows'])) $tArr[1]=intval($vv['rows']);
773 if (trim($vv['extra'])) $tArr[2]=trim($vv['extra']);
774 if (strlen($vv['specialEval'])) {
775 $thisLine[2] = ''; // Preset blank default value so position 3 can get a value...
776 $thisLine[3] = $vv['specialEval'];
781 if (intval($vv['size'])) $tArr[0]=intval($vv['size']);
782 if (intval($vv['max'])) $tArr[1]=intval($vv['max']);
783 if (strlen($vv['specialEval'])) {
784 $thisLine[2] = ''; // Preset blank default value so position 3 can get a value...
785 $thisLine[3] = $vv['specialEval'];
789 if (intval($vv['size'])) $tArr[0]=intval($vv['size']);
792 if (intval($vv['size'])) $tArr[0]=intval($vv['size']);
793 if ($vv['autosize']) $tArr[0]='auto';
794 if ($vv['multiple']) $tArr[1]='m';
797 $tArr = $this->cleanT($tArr);
798 if (count($tArr)) $thisLine[1].=','.implode(',',$tArr);
800 $thisLine[1]=str_replace('|','',$thisLine[1]);
803 if ($vv['type']=='select' ||
$vv['type']=='radio') {
804 $thisLine[2]=str_replace(chr(10),', ',str_replace(',','',$vv['options']));
805 } elseif ($vv['type']=='check') {
806 if ($vv['default']) $thisLine[2]=1;
807 } elseif (strcmp(trim($vv['default']),'')) {
808 $thisLine[2]=$vv['default'];
810 if (isset($thisLine[2])) $thisLine[2]=str_replace('|','',$thisLine[2]);
813 // Compile the final line:
814 $inLines[]=ereg_replace("[\n\r]*",'',implode(' | ',$thisLine));
817 // Finally, implode the lines into a string, and return it:
818 return implode(chr(10),$inLines);
822 * Converts the input configuration code string into an array
824 * @param string Configuration code
825 * @return array Configuration array
826 * @see cfgArray2CfgString()
828 function cfgString2CfgArray($cfgStr) {
830 // Traverse the number of form elements:
831 $tLines=explode(chr(10),$cfgStr);
832 foreach($tLines as $k => $v) {
838 // Accept a line as configuration if a) it is blank(! - because blank lines indicates new, unconfigured fields) or b) it is NOT a comment.
839 if (!$val ||
strcspn($val,'#/')) {
842 $parts = t3lib_div
::trimExplode('|',$val);
845 $confData['label'] = trim($parts[0]);
848 $fParts = t3lib_div
::trimExplode(',',$parts[1]);
849 $fParts[0]=trim($fParts[0]);
850 if (substr($fParts[0],0,1)=='*') {
851 $confData['required'] = 1;
852 $fParts[0] = substr($fParts[0],1);
855 $typeParts = t3lib_div
::trimExplode('=',$fParts[0]);
856 $confData['type'] = trim(strtolower(end($typeParts)));
858 if ($confData['type']) {
859 if (count($typeParts)==1) {
860 $confData['fieldname'] = substr(ereg_replace('[^a-zA-Z0-9_]','',str_replace(' ','_',trim($parts[0]))),0,30);
862 // Attachment names...
863 if ($confData['type']=='file') {
864 $confData['fieldname']='attachment'.$attachmentCounter;
865 $attachmentCounter=intval($attachmentCounter)+
1;
868 $confData['fieldname'] = str_replace(' ','_',trim($typeParts[0]));
871 switch((string)$confData['type']) {
874 $confData['default'] = implode(chr(10),t3lib_div
::trimExplode(',',$parts[2]));
877 $confData['default'] = trim($parts[2]);
881 // Field configuration depending on the fields type:
882 switch((string)$confData['type']) {
884 $confData['cols'] = $fParts[1];
885 $confData['rows'] = $fParts[2];
886 $confData['extra'] = strtoupper($fParts[3])=='OFF' ?
'OFF' : '';
887 $confData['specialEval'] = trim($parts[3]);
891 $confData['size'] = $fParts[1];
892 $confData['max'] = $fParts[2];
893 $confData['specialEval'] = trim($parts[3]);
896 $confData['size'] = $fParts[1];
899 $confData['size'] = intval($fParts[1])?
$fParts[1]:'';
900 $confData['autosize'] = strtolower(trim($fParts[1]))=='auto' ?
1 : 0;
901 $confData['multiple'] = strtolower(trim($fParts[2]))=='m' ?
1 : 0;
906 // No configuration, only a comment:
912 // Adding config array:
921 * Removes any "trailing elements" in the array which consists of whitespace (little like trim() does for strings, so this does for arrays)
923 * @param array Single dim array
924 * @return array Processed array
927 function cleanT($tArr) {
928 for($a=count($tArr);$a>0;$a--) {
929 if (strcmp($tArr[$a-1],'')) {
939 * Wraps items in $fArr in table cells/rows, displaying them vertically.
941 * @param array Array of label/HTML pairs.
942 * @return string HTML table
945 function formatCells($fArr) {
947 // Traverse the elements in $fArr and wrap them in table cells:
949 foreach($fArr as $l => $c) {
952 <td nowrap="nowrap">'.htmlspecialchars($l.':').' </td>
957 // Add a cell which will set a minimum width:
960 <td nowrap="nowrap"><img src="clear.gif" width="70" height="1" alt="" /></td>
964 // Wrap in table and return:
966 <table border="0" cellpadding="0" cellspacing="0">
967 '.implode('',$lines).'
972 // Include extension?
973 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['typo3/wizard_forms.php']) {
974 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['typo3/wizard_forms.php']);
989 $SOBE = t3lib_div
::makeInstance('SC_wizard_forms');
993 foreach($SOBE->include_once as $INC_FILE) include_once($INC_FILE);
996 $SOBE->printContent();