TYPO3 API  SVNRelease
wizard_forms.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 /**
00028  * Wizard to help make forms (fx. for tt_content elements) of type 'form'.
00029  *
00030  * $Id: wizard_forms.php 10121 2011-01-18 20:15:30Z ohader $
00031  * Revised for TYPO3 3.6 November/2003 by Kasper Skårhøj
00032  * XHTML compliant
00033  *
00034  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00035  */
00036 /**
00037  * [CLASS/FUNCTION INDEX of SCRIPT]
00038  *
00039  *
00040  *
00041  *  175: class SC_wizard_forms
00042  *  203:     function init()
00043  *  242:     function main()
00044  *  257:     function printContent()
00045  *  268:     function formsWizard()
00046  *
00047  *              SECTION: Helper functions
00048  *  311:     function getConfigCode(&$row)
00049  *  382:     function getFormHTML($formCfgArray,$row)
00050  *  662:     function changeFunc()
00051  *  721:     function cfgArray2CfgString($cfgArr)
00052  *  803:     function cfgString2CfgArray($cfgStr)
00053  *  902:     function cleanT($tArr)
00054  *  920:     function formatCells($fArr)
00055  *
00056  * TOTAL FUNCTIONS: 11
00057  * (This index is automatically created/updated by the extension "extdeveval")
00058  *
00059  */
00060 
00061 
00062 
00063 $BACK_PATH='';
00064 require ('init.php');
00065 require ('template.php');
00066 $LANG->includeLLFile('EXT:lang/locallang_wizards.xml');
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 /**
00080  * API comments:
00081  *
00082  * 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.
00083  *
00084  * The format for the resulting configuration code can be either a line-based configuration. That can look like this:
00085  *
00086  * Your name: | *name=input | (input your name here!)
00087  * Your Email: | *email=input
00088  * Your address: | address=textarea,40,10
00089  * Your Haircolor: | hair=radio |
00090  * upload | attachment=file
00091  *  | quoted_printable=hidden | 0
00092  *  | formtype_mail=submit | Send form
00093  *  | html_enabled=hidden
00094  *  | subject=hidden | This is the subject
00095  *
00096  *
00097  * Alternatively it can be XML. The same configuration from above looks like this in XML:
00098  *
00099  * <T3FormWizard>
00100  *  <n2>
00101  *      <type>input</type>
00102  *      <label>Your name:</label>
00103  *      <required>1</required>
00104  *      <fieldname>name</fieldname>
00105  *      <size></size>
00106  *      <max></max>
00107  *      <default>(input your name here!)</default>
00108  *  </n2>
00109  *  <n4>
00110  *      <type>input</type>
00111  *      <label>Your Email:</label>
00112  *      <required>1</required>
00113  *      <fieldname>email</fieldname>
00114  *      <size></size>
00115  *      <max></max>
00116  *      <default></default>
00117  *  </n4>
00118  *  <n6>
00119  *      <type>textarea</type>
00120  *      <label>Your address:</label>
00121  *      <fieldname>address</fieldname>
00122  *      <cols>40</cols>
00123  *      <rows>10</rows>
00124  *      <default></default>
00125  *  </n6>
00126  *  <n8>
00127  *      <type>radio</type>
00128  *      <label>Your Haircolor:</label>
00129  *      <fieldname>hair</fieldname>
00130  *      <options></options>
00131  *  </n8>
00132  *  <n10>
00133  *      <type>file</type>
00134  *      <label>upload</label>
00135  *      <fieldname>attachment</fieldname>
00136  *      <size></size>
00137  *  </n10>
00138  *  <n12>
00139  *      <type>hidden</type>
00140  *      <label></label>
00141  *      <fieldname>quoted_printable</fieldname>
00142  *      <default>0</default>
00143  *  </n12>
00144  *  <n2000>
00145  *      <fieldname>formtype_mail</fieldname>
00146  *      <type>submit</type>
00147  *      <default>Send form</default>
00148  *  </n2000>
00149  *  <n2002>
00150  *      <fieldname>html_enabled</fieldname>
00151  *      <type>hidden</type>
00152  *  </n2002>
00153  *  <n2004>
00154  *      <fieldname>subject</fieldname>
00155  *      <type>hidden</type>
00156  *      <default>This is the subject</default>
00157  *  </n2004>
00158  *  <n20>
00159  *      <content></content>
00160  *  </n20>
00161  * </T3FormWizard>
00162  *
00163  *
00164  * The XML/phpArray structure is the internal format of the wizard.
00165  */
00166 
00167 
00168 /**
00169  * Script Class for rendering the Form Wizard
00170  *
00171  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00172  * @package TYPO3
00173  * @subpackage core
00174  */
00175 class SC_wizard_forms {
00176 
00177         // Internal, dynamic:
00178     /**
00179      * document template object
00180      *
00181      * @var mediumDoc
00182      */
00183     var $doc;
00184     var $content;               // Content accumulation for the module.
00185     var $include_once=array();  // List of files to include.
00186     var $attachmentCounter = 0; // Used to numerate attachments automatically.
00187 
00188 
00189         // Internal, static:
00190     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!
00191 
00192 
00193         // Internal, static: GPvars
00194     var $P;                     // Wizard parameters, coming from TCEforms linking to the wizard.
00195     var $FORMCFG;               // The array which is constantly submitted by the multidimensional form of this wizard.
00196     var $special;               // Indicates if the form is of a dedicated type, like "formtype_mail" (for tt_content element "Form")
00197 
00198 
00199 
00200 
00201 
00202 
00203     /**
00204      * Initialization the class
00205      *
00206      * @return  void
00207      */
00208     function init() {
00209             // GPvars:
00210         $this->P = t3lib_div::_GP('P');
00211         $this->special = t3lib_div::_GP('special');
00212         $this->FORMCFG = t3lib_div::_GP('FORMCFG');
00213 
00214             // Setting options:
00215         $this->xmlStorage = $this->P['params']['xmlOutput'];
00216 
00217             // Document template object:
00218         $this->doc = t3lib_div::makeInstance('template');
00219         $this->doc->backPath = $GLOBALS['BACK_PATH'];
00220         $this->doc->setModuleTemplate('templates/wizard_forms.html');
00221         $this->doc->JScode=$this->doc->wrapScriptTags('
00222             function jumpToUrl(URL,formEl)  {   //
00223                 window.location.href = URL;
00224             }
00225         ');
00226 
00227             // Setting form tag:
00228         list($rUri) = explode('#',t3lib_div::getIndpEnv('REQUEST_URI'));
00229         $this->doc->form ='<form action="'.htmlspecialchars($rUri).'" method="post" name="wizardForm">';
00230 
00231             // If save command found, include tcemain:
00232         if ($_POST['savedok_x'] || $_POST['saveandclosedok_x']) {
00233             $this->include_once[]=PATH_t3lib.'class.t3lib_tcemain.php';
00234         }
00235     }
00236 
00237     /**
00238      * Main function for rendering the form wizard HTML
00239      *
00240      * @return  void
00241      */
00242     function main() {
00243         if ($this->P['table'] && $this->P['field'] && $this->P['uid'])  {
00244             $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('forms_title'), $this->formsWizard(), 0, 1);
00245         } else {
00246             $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('forms_title'), '<span class="typo3-red">' . $GLOBALS['LANG']->getLL('table_noData',1) . '</span>', 0, 1);
00247         }
00248 
00249         // Setting up the buttons and markers for docheader
00250         $docHeaderButtons = $this->getButtons();
00251         $markers['CSH'] = $docHeaderButtons['csh'];
00252         $markers['CONTENT'] = $this->content;
00253 
00254         // Build the <body> for the module
00255         $this->content = $this->doc->startPage('Form Wizard');
00256         $this->content.= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
00257         $this->content.= $this->doc->endPage();
00258         $this->content = $this->doc->insertStylesAndJS($this->content);
00259     }
00260 
00261     /**
00262      * Outputting the accumulated content to screen
00263      *
00264      * @return  void
00265      */
00266     function printContent() {
00267         echo $this->content;
00268     }
00269 
00270     /**
00271      * Create the panel of buttons for submitting the form or otherwise perform operations.
00272      *
00273      * @return array all available buttons as an assoc. array
00274      */
00275     protected function getButtons() {
00276         $buttons = array(
00277             'csh' => '',
00278             'csh_buttons' => '',
00279             'close' => '',
00280             'save' => '',
00281             'save_close' => '',
00282             'reload' => '',
00283         );
00284 
00285         if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
00286             // CSH
00287             $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz', $GLOBALS['BACK_PATH'], '');
00288 
00289             // CSH Buttons
00290             $buttons['csh_buttons'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_buttons', $GLOBALS['BACK_PATH'], '');
00291 
00292             // Close
00293             $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(unescape(\'' . rawurlencode(t3lib_div::sanitizeLocalUrl($this->P['returnUrl'])) . '\')); return false;') . '">' .
00294                 t3lib_iconWorks::getSpriteIcon('actions-document-close', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc', TRUE))) .
00295           '</a>';
00296 
00297             // Save
00298             $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) . '" />';
00299 
00300             // Save & Close
00301             $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) . '" />';
00302 
00303             // Reload
00304             $buttons['reload'] = '<input type="image" class="c-inputButton" name="_refresh"' . t3lib_iconWorks::skinImg('', 'gfx/refresh_n.gif') . ' title="' . $GLOBALS['LANG']->getLL('forms_refresh', 1) . '" />';
00305         }
00306 
00307         return $buttons;
00308     }
00309 
00310     /**
00311      * Draws the form wizard content
00312      *
00313      * @return  string      HTML content for the form.
00314      */
00315     function formsWizard()  {
00316 
00317             // First, check the references by selecting the record:
00318         $row = t3lib_BEfunc::getRecord($this->P['table'],$this->P['uid']);
00319         if (!is_array($row)) {
00320             throw new RuntimeException('Wizard Error: No reference to record');
00321         }
00322 
00323             // 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.
00324         $formCfgArray = $this->getConfigCode($row);
00325 
00326             // Generation of the Form Wizards HTML code:
00327         $content = $this->getFormHTML($formCfgArray,$row);
00328 
00329             // Return content:
00330         return $content;
00331     }
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343     /****************************
00344      *
00345      * Helper functions
00346      *
00347      ***************************/
00348 
00349     /**
00350      * Will get and return the configuration code string
00351      * Will also save (and possibly redirect/exit) the content if a save button has been pressed
00352      *
00353      * @param   array       Current parent record row (passed by value!)
00354      * @return  array       Configuration Array
00355      * @access private
00356      */
00357     function getConfigCode(&$row)   {
00358 
00359             // If some data has been submitted, then construct
00360         if (isset($this->FORMCFG['c'])) {
00361 
00362                 // Process incoming:
00363             $this->changeFunc();
00364 
00365                 // Convert to string (either line based or XML):
00366             if ($this->xmlStorage)  {
00367                     // Convert the input array to XML:
00368                 $bodyText = t3lib_div::array2xml_cs($this->FORMCFG['c'],'T3FormWizard');
00369 
00370                     // Setting cfgArr directly from the input:
00371                 $cfgArr = $this->FORMCFG['c'];
00372             } else {
00373                     // Convert the input array to a string of configuration code:
00374                 $bodyText = $this->cfgArray2CfgString($this->FORMCFG['c']);
00375 
00376                     // Create cfgArr from the string based configuration - that way it is cleaned up and any incompatibilities will be removed!
00377                 $cfgArr = $this->cfgString2CfgArray($bodyText);
00378             }
00379 
00380                 // If a save button has been pressed, then save the new field content:
00381             if ($_POST['savedok_x'] || $_POST['saveandclosedok_x']) {
00382 
00383                     // Make TCEmain object:
00384                 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
00385                 $tce->stripslashes_values=0;
00386 
00387                     // Put content into the data array:
00388                 $data=array();
00389                 $data[$this->P['table']][$this->P['uid']][$this->P['field']]=$bodyText;
00390                 if ($this->special=='formtype_mail')    {
00391                     $data[$this->P['table']][$this->P['uid']]['subheader']=$this->FORMCFG['recipient'];
00392                 }
00393 
00394                     // Perform the update:
00395                 $tce->start($data,array());
00396                 $tce->process_datamap();
00397 
00398                     // Re-load the record content:
00399                 $row = t3lib_BEfunc::getRecord($this->P['table'],$this->P['uid']);
00400 
00401                     // If the save/close button was pressed, then redirect the screen:
00402                 if ($_POST['saveandclosedok_x']) {
00403                     t3lib_utility_Http::redirect(t3lib_div::sanitizeLocalUrl($this->P['returnUrl']));
00404                 }
00405             }
00406         } else {    // If nothing has been submitted, load the $bodyText variable from the selected database row:
00407             if ($this->xmlStorage)  {
00408                 $cfgArr = t3lib_div::xml2array($row[$this->P['field']]);
00409             } else {    // Regular linebased form configuration:
00410                 $cfgArr = $this->cfgString2CfgArray($row[$this->P['field']]);
00411             }
00412             $cfgArr = is_array($cfgArr) ? $cfgArr : array();
00413         }
00414 
00415             // Return configuration code:
00416         return $cfgArr;
00417     }
00418 
00419     /**
00420      * Creates the HTML for the Form Wizard:
00421      *
00422      * @param   string      Form config array
00423      * @param   array       Current parent record array
00424      * @return  string      HTML for the form wizard
00425      * @access private
00426      */
00427     function getFormHTML($formCfgArray,$row)    {
00428         global $LANG;
00429 
00430             // Initialize variables:
00431         $specParts=array();
00432         $hiddenFields=array();
00433         $tRows=array();
00434 
00435             // Set header row:
00436         $cells=array($LANG->getLL('forms_preview',1).':',
00437                         $LANG->getLL('forms_element',1).':',
00438                         $LANG->getLL('forms_config',1).':',
00439         );
00440         $tRows[]='
00441             <tr class="bgColor2" id="typo3-formWizardHeader">
00442                 <td>&nbsp;</td>
00443                 <td>'.implode('</td>
00444                 <td>',$cells).'</td>
00445             </tr>';
00446 
00447             // Traverse the number of form elements:
00448         $k=0;
00449         foreach($formCfgArray as $confData) {
00450 
00451                 // Initialize:
00452             $cells=array();
00453 
00454                 // If there is a configuration line which is active, then render it:
00455             if (!isset($confData['comment'])) {
00456 
00457                     // Special parts:
00458                 if ($this->special=='formtype_mail' && t3lib_div::inList('formtype_mail,subject,html_enabled',$confData['fieldname']))  {
00459                     $specParts[$confData['fieldname']] = $confData['default'];
00460                 } else {
00461 
00462                         // Render title/field preview COLUMN
00463                     $cells[]=$confData['type']!='hidden' ? '<strong>'.htmlspecialchars($confData['label']).'</strong>' : '';
00464 
00465 
00466                         // Render general type/title COLUMN:
00467                     $temp_cells=array();
00468 
00469                         // Field type selector:
00470                     $opt=array();
00471                     $opt[]='<option value=""></option>';
00472                     $types = explode(',','input,textarea,select,check,radio,password,file,hidden,submit,property,label');
00473                     foreach($types as $t)   {
00474                         $opt[]='
00475                                 <option value="'.$t.'"'.($confData['type']==$t?' selected="selected"':'').'>'.$LANG->getLL('forms_type_'.$t,1).'</option>';
00476                     }
00477                     $temp_cells[$LANG->getLL('forms_type')]='
00478                             <select name="FORMCFG[c]['.(($k+1)*2).'][type]">
00479                                 '.implode('
00480                                 ',$opt).'
00481                             </select>';
00482 
00483                         // Title field:
00484                     if (!t3lib_div::inList('hidden,submit',$confData['type']))  {
00485                         $temp_cells[$LANG->getLL('forms_label')]='<input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[c]['.(($k+1)*2).'][label]" value="'.htmlspecialchars($confData['label']).'" />';
00486                     }
00487 
00488                         // Required checkbox:
00489                     if (!t3lib_div::inList('check,hidden,submit,label',$confData['type']))      {
00490                         $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).'" />';
00491                     }
00492 
00493                         // Put sub-items together into table cell:
00494                     $cells[]=$this->formatCells($temp_cells);
00495 
00496 
00497                         // Render specific field configuration COLUMN:
00498                     $temp_cells=array();
00499 
00500                         // Fieldname
00501                     if ($this->special=='formtype_mail' && $confData['type']=='file')   {
00502                         $confData['fieldname'] = 'attachment'.(++$this->attachmentCounter);
00503                     }
00504                     if (!t3lib_div::inList('label',$confData['type']))  {
00505                         $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).'" />';
00506                     }
00507 
00508                         // Field configuration depending on the fields type:
00509                     switch((string)$confData['type'])   {
00510                         case 'textarea':
00511                             $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).'" />';
00512                             $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).'" />';
00513                             $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).'" />';
00514                         break;
00515                         case 'input':
00516                         case 'password':
00517                             $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).'" />';
00518                             $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).'" />';
00519                         break;
00520                         case 'file':
00521                             $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).'" />';
00522                         break;
00523                         case 'select':
00524                             $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).'" />';
00525                             $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).'" />';
00526                             $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).'" />';
00527                         break;
00528                     }
00529 
00530                         // Field configuration depending on the fields type:
00531                     switch((string)$confData['type'])   {
00532                         case 'textarea':
00533                         case 'input':
00534                         case 'password':
00535                             if (strlen(trim($confData['specialEval']))) {
00536                                 $hiddenFields[] = '<input type="hidden" name="FORMCFG[c]['.(($k+1)*2).'][specialEval]" value="'.htmlspecialchars($confData['specialEval']).'" />';
00537                             }
00538                         break;
00539                     }
00540 
00541                         // Default data
00542                     if ($confData['type']=='select' || $confData['type']=='radio')  {
00543                         $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>';
00544                     } elseif ($confData['type']=='check')   {
00545                         $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).'" />';
00546                     } elseif ($confData['type'] && $confData['type']!='file') {
00547                         $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).'" />';
00548                     }
00549 
00550                     $cells[]=$confData['type']?$this->formatCells($temp_cells):'';
00551 
00552                         // CTRL panel for an item (move up/down/around):
00553                     $ctrl='';
00554                     $onClick="document.wizardForm.action+='#ANC_".(($k+1)*2-2)."';";
00555                     $onClick=' onclick="'.htmlspecialchars($onClick).'"';
00556 // FIXME $inputStyle undefined
00557                     $brTag=$inputStyle?'':'<br />';
00558                     if ($k!=0)  {
00559                         $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;
00560                     } else {
00561                         $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;
00562                     }
00563                     $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;
00564 // FIXME $tLines undefined
00565                     if (($k+1)!=count($tLines)) {
00566                         $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;
00567                     } else {
00568                         $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;
00569                     }
00570                     $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;
00571 
00572                     $ctrl='<span class="c-wizButtonsV">'.$ctrl.'</span>';
00573 
00574                         // Finally, put together the full row from the generated content above:
00575                     $bgC = $confData['type']?' class="bgColor5"':'';
00576                     $tRows[]='
00577                         <tr'.$bgC.'>
00578                             <td><a name="ANC_'.(($k+1)*2).'"></a>'.$ctrl.'</td>
00579                             <td class="bgColor4">'.implode('</td>
00580                             <td valign="top">',$cells).'</td>
00581                         </tr>';
00582                 }
00583             } else {
00584                 $hiddenFields[]='<input type="hidden" name="FORMCFG[c]['.(($k+1)*2).'][comment]" value="'.htmlspecialchars($confData['comment']).'" />';
00585             }
00586 
00587                 // Increment counter:
00588             $k++;
00589         }
00590 
00591             // If the form is of the special type "formtype_mail" (used for tt_content elements):
00592         if ($this->special=='formtype_mail')    {
00593 
00594                 // Blank spacer:
00595             $tRows[]='
00596                 <tr>
00597                     <td colspan="4">&nbsp;</td>
00598                 </tr>';
00599 
00600                 // Header:
00601             $tRows[]='
00602                 <tr>
00603                     <td colspan="2" class="bgColor2">&nbsp;</td>
00604                     <td colspan="2" class="bgColor2"><strong>'.$LANG->getLL('forms_special_eform',1).':</strong>'.
00605                         t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_formmail_info', $GLOBALS['BACK_PATH'],'').
00606                         '</td>
00607                 </tr>';
00608 
00609                 // "FORM type":
00610             $tRows[]='
00611                 <tr class="bgColor5">
00612                     <td>&nbsp;</td>
00613                     <td class="bgColor4">&nbsp;</td>
00614                     <td>'.$LANG->getLL('forms_eform_formtype_mail',1).':</td>
00615                     <td>
00616                         <input type="hidden" name="FORMCFG[c]['.(1000*2).'][fieldname]" value="formtype_mail" />
00617                         <input type="hidden" name="FORMCFG[c]['.(1000*2).'][type]" value="submit" />
00618                         <input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[c]['.(1000*2).'][default]" value="'.htmlspecialchars($specParts['formtype_mail']).'" />
00619                     </td>
00620                 </tr>';
00621 
00622                 // "Send HTML mail":
00623             $tRows[]='
00624                 <tr class="bgColor5">
00625                     <td>&nbsp;</td>
00626                     <td class="bgColor4">&nbsp;</td>
00627                     <td>'.$LANG->getLL('forms_eform_html_enabled',1).':</td>
00628                     <td>
00629                         <input type="hidden" name="FORMCFG[c]['.(1001*2).'][fieldname]" value="html_enabled" />
00630                         <input type="hidden" name="FORMCFG[c]['.(1001*2).'][type]" value="hidden" />
00631                         <input type="checkbox" name="FORMCFG[c]['.(1001*2).'][default]" value="1"'.($specParts['html_enabled']?' checked="checked"':'').' />
00632                     </td>
00633                 </tr>';
00634 
00635                 // "Subject":
00636             $tRows[]='
00637                 <tr class="bgColor5">
00638                     <td>&nbsp;</td>
00639                     <td class="bgColor4">&nbsp;</td>
00640                     <td>'.$LANG->getLL('forms_eform_subject',1).':</td>
00641                     <td>
00642                         <input type="hidden" name="FORMCFG[c]['.(1002*2).'][fieldname]" value="subject" />
00643                         <input type="hidden" name="FORMCFG[c]['.(1002*2).'][type]" value="hidden" />
00644                         <input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[c]['.(1002*2).'][default]" value="'.htmlspecialchars($specParts['subject']).'" />
00645                     </td>
00646                 </tr>';
00647 
00648                 // Recipient:
00649             $tRows[]='
00650                 <tr class="bgColor5">
00651                     <td>&nbsp;</td>
00652                     <td class="bgColor4">&nbsp;</td>
00653                     <td>'.$LANG->getLL('forms_eform_recipient',1).':</td>
00654                     <td>
00655                         <input type="text"'.$this->doc->formWidth(15).' name="FORMCFG[recipient]" value="'.htmlspecialchars($row['subheader']).'" />
00656                     </td>
00657                 </tr>';
00658         }
00659 
00660         $content = '';
00661 
00662             // Implode all table rows into a string, wrapped in table tags.
00663         $content.= '
00664 
00665             <!--
00666                 Form wizard
00667             -->
00668             <table border="0" cellpadding="1" cellspacing="1" id="typo3-formwizard">
00669                 '.implode('',$tRows).'
00670             </table>';
00671 
00672             // Add hidden fields:
00673         $content.= implode('',$hiddenFields);
00674 
00675             // Return content:
00676         return $content;
00677     }
00678 
00679     /**
00680      * Detects if a control button (up/down/around/delete) has been pressed for an item and accordingly it will manipulate the internal FORMCFG array
00681      *
00682      * @return  void
00683      * @access private
00684      */
00685     function changeFunc()   {
00686         if ($this->FORMCFG['row_remove'])   {
00687             $kk = key($this->FORMCFG['row_remove']);
00688             $cmd='row_remove';
00689         } elseif ($this->FORMCFG['row_add'])    {
00690             $kk = key($this->FORMCFG['row_add']);
00691             $cmd='row_add';
00692         } elseif ($this->FORMCFG['row_top'])    {
00693             $kk = key($this->FORMCFG['row_top']);
00694             $cmd='row_top';
00695         } elseif ($this->FORMCFG['row_bottom']) {
00696             $kk = key($this->FORMCFG['row_bottom']);
00697             $cmd='row_bottom';
00698         } elseif ($this->FORMCFG['row_up']) {
00699             $kk = key($this->FORMCFG['row_up']);
00700             $cmd='row_up';
00701         } elseif ($this->FORMCFG['row_down'])   {
00702             $kk = key($this->FORMCFG['row_down']);
00703             $cmd='row_down';
00704         }
00705 
00706         if ($cmd && t3lib_div::testInt($kk)) {
00707             if (substr($cmd,0,4)=='row_')   {
00708                 switch($cmd)    {
00709                     case 'row_remove':
00710                         unset($this->FORMCFG['c'][$kk]);
00711                     break;
00712                     case 'row_add':
00713                         $this->FORMCFG['c'][$kk+1]=array();
00714                     break;
00715                     case 'row_top':
00716                         $this->FORMCFG['c'][1]=$this->FORMCFG['c'][$kk];
00717                         unset($this->FORMCFG['c'][$kk]);
00718                     break;
00719                     case 'row_bottom':
00720                         $this->FORMCFG['c'][1000000]=$this->FORMCFG['c'][$kk];
00721                         unset($this->FORMCFG['c'][$kk]);
00722                     break;
00723                     case 'row_up':
00724                         $this->FORMCFG['c'][$kk-3]=$this->FORMCFG['c'][$kk];
00725                         unset($this->FORMCFG['c'][$kk]);
00726                     break;
00727                     case 'row_down':
00728                         $this->FORMCFG['c'][$kk+3]=$this->FORMCFG['c'][$kk];
00729                         unset($this->FORMCFG['c'][$kk]);
00730                     break;
00731                 }
00732                 ksort($this->FORMCFG['c']);
00733             }
00734         }
00735     }
00736 
00737     /**
00738      * Converts the input array to a configuration code string
00739      *
00740      * @param   array       Array of form configuration (follows the input structure from the form wizard POST form)
00741      * @return  string      The array converted into a string with line-based configuration.
00742      * @see cfgString2CfgArray()
00743      */
00744     function cfgArray2CfgString($cfgArr)    {
00745 
00746             // Initialize:
00747         $inLines=array();
00748 
00749             // Traverse the elements of the form wizard and transform the settings into configuration code.
00750         foreach($cfgArr as $vv) {
00751             if ($vv['comment']) {   // If "content" is found, then just pass it over.
00752                 $inLines[]=trim($vv['comment']);
00753             } else {    // Begin to put together the single-line configuration code of this field:
00754 
00755                     // Reset:
00756                 $thisLine=array();
00757 
00758                     // Set Label:
00759                 $thisLine[0]=str_replace('|','',$vv['label']);
00760 
00761                     // Set Type:
00762                 if ($vv['type'])    {
00763                     $thisLine[1]=($vv['required']?'*':'').str_replace(',','',($vv['fieldname']?$vv['fieldname'].'=':'').$vv['type']);
00764 
00765                         // Default:
00766                     $tArr=array('','','','','','');
00767                     switch((string)$vv['type']) {
00768                         case 'textarea':
00769                             if (intval($vv['cols']))    $tArr[0]=intval($vv['cols']);
00770                             if (intval($vv['rows']))    $tArr[1]=intval($vv['rows']);
00771                             if (trim($vv['extra']))     $tArr[2]=trim($vv['extra']);
00772                             if (strlen($vv['specialEval'])) {
00773                                 $thisLine[2] = '';  // Preset blank default value so position 3 can get a value...
00774                                 $thisLine[3] = $vv['specialEval'];
00775                             }
00776                         break;
00777                         case 'input':
00778                         case 'password':
00779                             if (intval($vv['size']))    $tArr[0]=intval($vv['size']);
00780                             if (intval($vv['max']))     $tArr[1]=intval($vv['max']);
00781                             if (strlen($vv['specialEval'])) {
00782                                 $thisLine[2] = '';  // Preset blank default value so position 3 can get a value...
00783                                 $thisLine[3] = $vv['specialEval'];
00784                             }
00785                         break;
00786                         case 'file':
00787                             if (intval($vv['size']))    $tArr[0]=intval($vv['size']);
00788                         break;
00789                         case 'select':
00790                             if (intval($vv['size']))    $tArr[0]=intval($vv['size']);
00791                             if ($vv['autosize'])    $tArr[0]='auto';
00792                             if ($vv['multiple'])    $tArr[1]='m';
00793                         break;
00794                     }
00795                     $tArr = $this->cleanT($tArr);
00796                     if (count($tArr))   $thisLine[1].=','.implode(',',$tArr);
00797 
00798                     $thisLine[1]=str_replace('|','',$thisLine[1]);
00799 
00800                         // Default:
00801                     if ($vv['type']=='select' || $vv['type']=='radio')  {
00802                         $thisLine[2]=str_replace(LF,', ',str_replace(',','',$vv['options']));
00803                     } elseif ($vv['type']=='check') {
00804                         if ($vv['default']) $thisLine[2]=1;
00805                     } elseif (strcmp(trim($vv['default']),'')) {
00806                         $thisLine[2]=$vv['default'];
00807                     }
00808                     if (isset($thisLine[2]))        $thisLine[2]=str_replace('|','',$thisLine[2]);
00809                 }
00810 
00811                     // Compile the final line:
00812                 $inLines[]=preg_replace("/[\n\r]*/",'',implode(' | ',$thisLine));
00813             }
00814         }
00815             // Finally, implode the lines into a string, and return it:
00816         return implode(LF,$inLines);
00817     }
00818 
00819     /**
00820      * Converts the input configuration code string into an array
00821      *
00822      * @param   string      Configuration code
00823      * @return  array       Configuration array
00824      * @see cfgArray2CfgString()
00825      */
00826     function cfgString2CfgArray($cfgStr)    {
00827 
00828             // Traverse the number of form elements:
00829         $tLines=explode(LF,$cfgStr);
00830         foreach($tLines as $k => $v)    {
00831 
00832                 // Initialize:
00833             $confData=array();
00834             $val=trim($v);
00835 
00836                 // Accept a line as configuration if a) it is blank(! - because blank lines indicates new, unconfigured fields) or b) it is NOT a comment.
00837             if (!$val || strcspn($val,'#/')) {
00838 
00839                     // Split:
00840                 $parts = t3lib_div::trimExplode('|',$val);
00841 
00842                     // Label:
00843                 $confData['label'] = trim($parts[0]);
00844 
00845                     // Field:
00846                 $fParts = t3lib_div::trimExplode(',',$parts[1]);
00847                 $fParts[0]=trim($fParts[0]);
00848                 if (substr($fParts[0],0,1)=='*')    {
00849                     $confData['required'] = 1;
00850                     $fParts[0] = substr($fParts[0],1);
00851                 }
00852 
00853                 $typeParts = t3lib_div::trimExplode('=',$fParts[0]);
00854                 $confData['type'] = trim(strtolower(end($typeParts)));
00855 
00856                 if ($confData['type'])  {
00857                     if (count($typeParts)==1)   {
00858                         $confData['fieldname'] = substr(preg_replace('/[^a-zA-Z0-9_]/','',str_replace(' ','_',trim($parts[0]))),0,30);
00859 
00860                             // Attachment names...
00861                         if ($confData['type']=='file')  {
00862                             $confData['fieldname']='attachment'.$attachmentCounter;
00863                             $attachmentCounter=intval($attachmentCounter)+1;
00864                         }
00865                     } else {
00866                         $confData['fieldname'] = str_replace(' ','_',trim($typeParts[0]));
00867                     }
00868 
00869                     switch((string)$confData['type'])   {
00870                         case 'select':
00871                         case 'radio':
00872                             $confData['default'] = implode(LF,t3lib_div::trimExplode(',',$parts[2]));
00873                         break;
00874                         default:
00875                             $confData['default'] = trim($parts[2]);
00876                         break;
00877                     }
00878 
00879                         // Field configuration depending on the fields type:
00880                     switch((string)$confData['type'])   {
00881                         case 'textarea':
00882                             $confData['cols'] = $fParts[1];
00883                             $confData['rows'] = $fParts[2];
00884                             $confData['extra'] = strtoupper($fParts[3])=='OFF' ? 'OFF' : '';
00885                             $confData['specialEval'] = trim($parts[3]);
00886                         break;
00887                         case 'input':
00888                         case 'password':
00889                             $confData['size'] = $fParts[1];
00890                             $confData['max'] = $fParts[2];
00891                             $confData['specialEval'] = trim($parts[3]);
00892                         break;
00893                         case 'file':
00894                             $confData['size'] = $fParts[1];
00895                         break;
00896                         case 'select':
00897                             $confData['size'] = intval($fParts[1])?$fParts[1]:'';
00898                             $confData['autosize'] = strtolower(trim($fParts[1]))=='auto' ? 1 : 0;
00899                             $confData['multiple'] = strtolower(trim($fParts[2]))=='m' ? 1 : 0;
00900                         break;
00901                     }
00902                 }
00903             } else {
00904                     // No configuration, only a comment:
00905                 $confData=array(
00906                     'comment' => $val
00907                 );
00908             }
00909 
00910                 // Adding config array:
00911             $cfgArr[]=$confData;
00912         }
00913 
00914             // Return cfgArr
00915         return $cfgArr;
00916     }
00917 
00918     /**
00919      * Removes any "trailing elements" in the array which consists of whitespace (little like trim() does for strings, so this does for arrays)
00920      *
00921      * @param   array       Single dim array
00922      * @return  array       Processed array
00923      * @access private
00924      */
00925     function cleanT($tArr)  {
00926         for($a=count($tArr);$a>0;$a--)  {
00927             if (strcmp($tArr[$a-1],'')) {
00928                 break;
00929             } else {
00930                 unset($tArr[$a-1]);
00931             }
00932         }
00933         return $tArr;
00934     }
00935 
00936     /**
00937      * Wraps items in $fArr in table cells/rows, displaying them vertically.
00938      *
00939      * @param   array       Array of label/HTML pairs.
00940      * @return  string      HTML table
00941      * @access private
00942      */
00943     function formatCells($fArr) {
00944 
00945             // Traverse the elements in $fArr and wrap them in table cells:
00946         $lines=array();
00947         foreach($fArr as $l => $c)  {
00948             $lines[]='
00949                 <tr>
00950                     <td nowrap="nowrap">'.htmlspecialchars($l.':').'&nbsp;</td>
00951                     <td>'.$c.'</td>
00952                 </tr>';
00953         }
00954 
00955             // Add a cell which will set a minimum width:
00956         $lines[]='
00957             <tr>
00958                 <td nowrap="nowrap"><img src="clear.gif" width="70" height="1" alt="" /></td>
00959                 <td></td>
00960             </tr>';
00961 
00962             // Wrap in table and return:
00963         return '
00964             <table border="0" cellpadding="0" cellspacing="0">
00965                 '.implode('',$lines).'
00966             </table>';
00967     }
00968 }
00969 
00970 
00971 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/wizard_forms.php'])) {
00972     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/wizard_forms.php']);
00973 }
00974 
00975 
00976 
00977 // Make instance:
00978 $SOBE = t3lib_div::makeInstance('SC_wizard_forms');
00979 $SOBE->init();
00980 
00981 // Include files?
00982 foreach($SOBE->include_once as $INC_FILE)   include_once($INC_FILE);
00983 
00984 $SOBE->main();
00985 $SOBE->printContent();
00986 
00987 ?>