Beispiel #1
0
function makeEditForm($selfurl)
{
    // nice names for each field
    $formNames = array('cfg_incoming_path' => 'Kannel Incoming Path: ', 'cfg_username' => 'Username:'******'cfg_password' => 'Password:'******'cfg_global_sender' => 'Global Sender:', 'cfg_bearerbox_host' => 'Bearerbox IP:', 'cfg_sendsms_port' => 'Send SMS Port:', 'cfg_playsms_web' => 'PlaySMS web url:', 'cfg_restart_frequency' => 'Restart Kannel Regularly?');
    // infer the fields we're going to show
    // from the list of formNames
    $renderFields = array();
    foreach ($formNames as $field => $name) {
        $renderFields[] = $field;
    }
    // find the first record in the config table
    $do = DB_DataObject::factory('playsms_gwmodKannel_config');
    $do->get(1);
    // create the form with the user-showable names
    $fb = DB_DataObject_FormBuilder::create($do, array("fieldLabels" => $formNames, "fieldsToRender" => $renderFields));
    // set up enums
    $fb->enumFields = array('cfg_restart_frequency');
    $form = $fb->getForm("{$selfurl}");
    if ($form->validate()) {
        $err = "Gateway module configurations has been saved";
        print "<p><font color=red>{$err}</font><p>";
        $form->process(array(&$fb, 'processForm'), false);
    }
    $form->display();
    echo "<p/><hr/><p/>";
    echo "<a href=\"plugin/gateway/kannel/kannel-monitor/\">[ Monitor Status ]</a> \n";
    echo "<a href=\"{$selfurl}&op=manage_smsc\">[ Bind SMSC ]</a>";
}
Beispiel #2
0
function makeEditForm($selfurl)
{
    // nice names for each field
    $formNames = array('cfg_web_title' => 'Website title:', 'cfg_web_url' => 'Website URL:', 'cfg_email_service' => 'Website email', 'cfg_email_footer' => 'Forwarded email footer:', 'cfg_gateway_module' => 'Activated gateway module:', 'cfg_gateway_number' => 'Gateway number:', 'cfg_system_from' => 'System messages <br/> (e.g., balance updates) are sent from:', 'cfg_system_restart_frequency' => 'Restart the entire system regularly?');
    // infer the fields we're going to show
    // from the list of formNames
    $renderFields = array();
    foreach ($formNames as $field => $name) {
        $renderFields[] = $field;
    }
    // List of gateway plugins.
    // TODO: make this get listing of the gw plugin files
    // rather than be hard-coded
    $gw_mods = array("kannel" => "Kannel", "gnokii" => "Gnokii", "uplink" => "UpLink", "clickatell" => "ClickAtell");
    // find the first record in the config table
    $do = DB_DataObject::factory(playsms_tblConfig_main);
    $do->find();
    $do->fetch();
    // create the form with the user-showable names
    $fb = DB_DataObject_FormBuilder::create($do, array("fieldLabels" => $formNames, "fieldsToRender" => $renderFields));
    $fb->submitText = "Save";
    // set up gw_mod enum
    $fb->enumFields = array('cfg_gateway_module', 'cfg_system_restart_frequency');
    $fb->enumOptions = array('cfg_gateway_module' => $gw_mods);
    $form = $fb->getForm("{$selfurl}");
    if ($form->validate()) {
        $err = "Main configuration has been saved";
        print "<p><font color=red>{$err}</font><p>";
        $form->process(array(&$fb, 'processForm'), false);
    }
    $form->display();
}
Beispiel #3
0
function date2array($dt)
{
    if ($dt == NULL) {
        return array('Y' => '0000', 'm' => '00', 'd' => '00');
    } else {
        return DB_DataObject_FormBuilder::_date2array($dt);
    }
}
Beispiel #4
0
 public function __construct($module)
 {
     parent::__construct();
     $this->assign('__action', 'add');
     $tpl = Mreg::get('tpl');
     $tpl->concat('adminTitle', ' :: ' . $this->moduloptions['title'] . ' :: ' . __('Add record'));
     $mopts = PEAR::getStaticProperty('m_office', 'options');
     $mopt = $mopts['modules'][$module];
     $table = $mopt['table'];
     $do = M_Office_Util::doForModule($module);
     $this->append('subActions', '<a href="' . M_Office_Util::getQueryParams(array(), array('record', 'doSingleAction')) . '">' . __('Go to the %s list', array($mopt['title'])) . '</a>');
     $formBuilder =& MyFB::create($do);
     //	linkNewValue creates an issue if some linked elements are put in predefgroups
     //        $formBuilder->linkNewValue = true;
     $form = new MyQuickForm('editRecord', 'POST', M_Office_Util::getQueryParams(array(), array(), false), '_self', null, true);
     $form->addElement('hidden', 'submittedNewRecord', 1);
     if (isset($_REQUEST['filterField'])) {
         $form->addElement('hidden', 'filterField', $_REQUEST['filterField']);
         $form->addElement('hidden', 'filterValue', $_REQUEST['filterValue']);
         $do->{$_REQUEST['filterField']} = $_REQUEST['filterValue'];
     }
     $links = $do->links();
     if (key_exists($_REQUEST['filterField'], $links)) {
         $linfo = explode(':', $links[$_REQUEST['filterField']]);
         $form->addElement('static', 'mod', '', __('Add record with %s = %s', array($_REQUEST['filterField'], $_REQUEST['filterValue'])) . '. ' . '<a href="' . M_Office_Util::getQueryParams(array('table' => $linfo[0], 'record' => $_REQUEST['filterValue']), array('addRecord', 'filterField', 'filterValue')) . '">' . __('Back to main record') . '</a>');
     }
     $formBuilder->useForm($form);
     $formBuilder->getForm();
     if ($this->getOption('createAnother', $table)) {
         $form->addElement('static', '&nbsp;', '&nbsp;');
         $form->addElement('checkbox', 'returnHere', __('Create another record'));
         if (isset($_REQUEST['returnHere']) && $_REQUEST['returnHere']) {
             $form->setDefaults(array('returnHere' => true));
         }
     }
     M_Office_Util::addHiddenFields($form);
     if ($form->validate()) {
         if (PEAR::isError($ret = $form->process(array(&$formBuilder, 'processForm'), false))) {
             $this->append('error', __('An error occured while inserting record') . ' : ' . $ret->getMessage());
         } else {
             $pk = DB_DataObject_FormBuilder::_getPrimaryKey($do);
             $this->say(__('New record was successfully created. Its identifier is : %s', array($do->{$pk})));
             if ($this->getOption('createAnother', $table) && isset($_REQUEST['returnHere']) && $_REQUEST['returnHere']) {
                 M_Office_Util::refresh(M_Office_Util::getQueryParams(array('returnHere' => $_REQUEST['returnHere']), array(), false));
             } else {
                 $pk = DB_DataObject_FormBuilder::_getPrimaryKey($do);
                 M_Office_Util::refresh(M_Office_Util::getQueryParams(array('record' => $do->{$pk}), array('returnHere', 'addRecord'), false));
             }
         }
     } elseif ($form->isSubmitted()) {
     }
     $this->assign('addForm', $form);
     $this->assign('do', $do);
 }
Beispiel #5
0
function makeEditForm($selfurl, $id = null)
{
    // nice names for each field
    $formNames = array('frequency' => 'Frequency:', 'number' => 'To:<br/><font size="1">(number or group code, <br/>e.g., "admin")</font>', 'msg' => 'Message:');
    $do = DB_DataObject::factory(playsms_featAutoSend);
    if ($id) {
        $do->get($id);
    }
    $fb = DB_DataObject_FormBuilder::create($do, array("fieldLabels" => $formNames));
    $fb->enumFields = array('frequency');
    $form = $fb->getForm("{$selfurl}&op=edit");
    setupSmsCounting($form, 'msg', '__submit__');
    if ($form->validate()) {
        $form->process(array(&$fb, 'processForm'), false);
    }
    $form->display();
    ?>
    
    <a href="<?php 
    echo $selfurl;
    ?>
&op=list"><br><br>[back]</a>
    <?php 
}
Beispiel #6
0
 /**
  * DB_DataObject_FormBuilder::_array2date()
  *
  * Takes a date array as used by the QuickForm date element and turns it back into
  * a string representation suitable for use with a database date field (format 'YYYY-MM-DD').
  * If second parameter is true, it will return a unix timestamp instead. //FRANK: Not at this point it wont
  *
  * Beware: For the date conversion to work, you must at least use the letters "d", "m" and "Y" in
  * your format string (see "dateElementFormat" option). If you want to enter a time as well,
  * you will have to use "H", "i" and "s" as well. Other letters will not work! Exception: You can
  * also use "M" instead of "m" if you want plain text month names.
  *
  * @param array $date   An array representation of a date, as user in HTML_QuickForm's date element
  * @param boolean $timestamp  Optional. If true, return a timestamp instead of a string. Defaults to false.
  * @return mixed
  * @access protected
  */
 function _array2date($dateInput, $timestamp = false)
 {
     if (isset($dateInput['M'])) {
         $month = $dateInput['M'];
     } elseif (isset($dateInput['m'])) {
         $month = $dateInput['m'];
     } elseif (isset($dateInput['F'])) {
         $month = $dateInput['F'];
     }
     if (isset($dateInput['Y'])) {
         $year = $dateInput['Y'];
     } elseif (isset($dateInput['y'])) {
         $year = $dateInput['y'];
     }
     if (isset($dateInput['H'])) {
         $hour = $dateInput['H'];
     } elseif (isset($dateInput['h']) || isset($dateInput['g'])) {
         if (isset($dateInput['h'])) {
             $hour = $dateInput['h'];
         } elseif (isset($dateInput['g'])) {
             $hour = $dateInput['g'];
         }
         if (isset($dateInput['a'])) {
             $ampm = $dateInput['a'];
         } elseif (isset($dateInput['A'])) {
             $ampm = $dateInput['A'];
         }
         if (strtolower(preg_replace('/[\\.\\s,]/', '', $ampm)) == 'pm') {
             if ($hour != '12') {
                 $hour += 12;
                 if ($hour == 24) {
                     $hour = '';
                     ++$dateInput['d'];
                 }
             }
         } else {
             if ($hour == '12') {
                 $hour = '00';
             }
         }
     }
     $strDate = '';
     if (isset($year) || isset($month) || isset($dateInput['d'])) {
         if (isset($year) && ($len = strlen($year)) > 0) {
             if ($len < 2) {
                 $year = '0' . $year;
             }
             if ($len < 4) {
                 $year = substr(date('Y'), 0, 2) . $year;
             }
         } else {
             $year = '0000';
         }
         if (isset($month) && ($len = strlen($month)) > 0) {
             if ($len < 2) {
                 $month = '0' . $month;
             }
         } else {
             $month = '00';
         }
         if (isset($dateInput['d']) && ($len = strlen($dateInput['d'])) > 0) {
             if ($len < 2) {
                 $dateInput['d'] = '0' . $dateInput['d'];
             }
         } else {
             $dateInput['d'] = '00';
         }
         $strDate .= $year . '-' . $month . '-' . $dateInput['d'];
     }
     if (isset($hour) || isset($dateInput['i']) || isset($dateInput['s'])) {
         if (isset($hour) && ($len = strlen($hour)) > 0) {
             if ($len < 2) {
                 $hour = '0' . $hour;
             }
         } else {
             $hour = '00';
         }
         if (isset($dateInput['i']) && ($len = strlen($dateInput['i'])) > 0) {
             if ($len < 2) {
                 $dateInput['i'] = '0' . $dateInput['i'];
             }
         } else {
             $dateInput['i'] = '00';
         }
         if (!empty($strDate)) {
             $strDate .= ' ';
         }
         $strDate .= $hour . ':' . $dateInput['i'];
         if (isset($dateInput['s']) && ($len = strlen($dateInput['s'])) > 0) {
             $strDate .= ':' . ($len < 2 ? '0' : '') . $dateInput['s'];
         }
     }
     DB_DataObject_FormBuilder::debug('<i>_array2date():</i>' . serialize($dateInput) . ' to ' . $strDate . ' ...');
     return $strDate;
 }
Beispiel #7
0
 /**
  * DB_DataObject_FormBuilder_QuickForm::DB_DataObject_FormBuilder_QuickForm()
  *
  * The class constructor.
  *
  * @param object $do      The DB_DataObject-derived object for which a form shall be built
  * @param array $options  An optional associative array of options.
  * @access public
  */
 function DB_DataObject_FormBuilder_QuickForm(&$do, $options = false)
 {
     // Call parent class constructor.
     parent::DB_DataObject_FormBuilder($do, $options);
 }
Beispiel #8
0
 /**
  * Populates internal vars for linkNewValue
  *
  * @param  string the name of the element we're creating the form for
  * @param  string the name of the table to create the form for (linked table)
  */
 function _prepareForLinkNewValue($elName, $subTable)
 {
     if (!isset($this->_linkNewValueDOs[$elName])) {
         $this->_linkNewValueDOs[$elName] = DB_DataObject::factory($subTable);
         $this->_linkNewValueDOs[$elName]->fb_createSubmit = false;
         $this->_linkNewValueDOs[$elName]->fb_elementNamePrefix = $this->elementNamePrefix . $elName . '_' . $subTable . '__';
         $this->_linkNewValueDOs[$elName]->fb_elementNamePostfix = $this->elementNamePostfix;
         //$this->_linkNewValueDOs[$elName]->fb_linkNewValue = false;
         $this->_linkNewValueFBs[$elName] =& DB_DataObject_FormBuilder::create($this->_linkNewValueDOs[$elName], false, 'QuickForm', get_class($this->_fb));
         $this->_linkNewValueForms[$elName] =& $this->_linkNewValueFBs[$elName]->getForm();
         $this->_linkNewValueForms[$elName]->addElement('hidden', $this->elementNamePrefix . '__DB_DataObject_FormBuilder_linkNewValue__' . $elName . $this->elementNamePostfix, $subTable);
     }
 }
Beispiel #9
0
function makeEditAutoreplyForm($selfurl, $id = null)
{
    global $uid, $addText, $backText;
    $errNoSpaces = "You cannot have spaces in a keyword; keywords are separated <em>by</em> spaces.";
    $do = DB_DataObject::factory('playsms_featAutoreply');
    if ($id) {
        $do->get($id);
    } else {
        $do->uid = $uid;
    }
    $fb = DB_DataObject_FormBuilder::create($do, array('fieldsToRender' => array('autoreply_code')));
    $fb->submitText = "Save";
    $form = $fb->getForm("{$selfurl}&op=edit&id={$id}");
    $form->addRule('autoreply_code', $errNoSpaces, 'regex', '/^[^ ]+$/');
    if ($form->validate()) {
        $form->process(array(&$fb, 'processForm'), false);
        // if we're adding a new item, then forward
        // on to editing that item so that the user doesn't
        // add it over and over again
        header("Location: {$selfurl}&op=edit&id={$do->autoreply_id}");
    }
    $form->display();
    $addLink = "<a href=\"{$selfurl}&op=addScenario&autoreply_id={$id}\" title=\"Add Scenario\">[add scenario]</a>";
    $backLink = "<a href=\"{$selfurl}&op=list\">{$backText}</a>";
    // only show the add-scenario link if
    // we're not in the process of adding the autoreply
    if (isset($do->autoreply_id)) {
        echo "{$addLink} &nbsp;";
    }
    echo "{$backLink}";
    echo "<hr/>";
    if ($id) {
        echo genDelForm("delScenario", "{$selfurl}&op=delScenario");
        echo generateScenarios($selfurl, $id);
    }
}
Beispiel #10
0
 /**
  * Fetch
  *
  * @param   integer $offset     Limit offset (starting from 0)
  * @param   integer $len        Limit length
  * @param   string  $sortField  Field to sort by
  * @param   string  $sortDir    Sort direction : 'ASC' or 'DESC'
  * @access  public
  * @return  array   The 2D Array of the records
  */
 function &fetch($offset = 0, $len = null, $sortField = null, $sortDir = 'ASC')
 {
     // Check to see if Query has already been submitted
     if ($this->_dataobject->_DB_resultid != '') {
         $this->_rowNum = $this->_dataobject->N;
     } else {
         // Caching the number of rows
         if (PEAR::isError($count = $this->count())) {
             return $count;
         } else {
             $this->_rowNum = $count;
         }
         // Sorting
         if ($sortField) {
             $this->sort($sortField, $sortDir);
         } elseif (($sortProperty = $this->_options['sort_property']) && isset($this->_dataobject->{$sortProperty})) {
             foreach ($this->_dataobject->{$sortProperty} as $sort) {
                 $this->sort($sort);
             }
         }
         // Limiting
         if ($offset) {
             $this->_dataobject->limit($offset, $len);
         } elseif ($len) {
             $this->_dataobject->limit($len);
         }
         $result = $this->_dataobject->find();
     }
     // Retrieving data
     $records = array();
     if ($this->_rowNum) {
         if ($this->_options['formbuilder_integration']) {
             require_once 'DB/DataObject/FormBuilder.php';
             $links = $this->_dataobject->links();
         }
         while ($this->_dataobject->fetch()) {
             // Determine Fields
             if (!$this->_options['fields']) {
                 $this->_options['fields'] = array_keys($this->_dataobject->toArray());
                 //$this->_options['fields'] = array_filter(array_keys(get_object_vars($this->_dataobject)), array(&$this, '_fieldsFilter'));
             }
             $fieldList = $this->_options['fields'];
             // Build DataSet
             $rec = array();
             foreach ($fieldList as $fName) {
                 $getMethod = 'get' . $fName;
                 if (method_exists($this->_dataobject, $getMethod)) {
                     //$rec[$fName] = $this->_dataobject->$getMethod(&$this);
                     $rec[$fName] = $this->_dataobject->{$getMethod};
                 } elseif (isset($this->_dataobject->{$fName})) {
                     $rec[$fName] = $this->_dataobject->{$fName};
                 } else {
                     $rec[$fName] = null;
                 }
             }
             // Get Linked FormBuilder Fields
             if ($this->_options['formbuilder_integration']) {
                 foreach (array_keys($rec) as $field) {
                     if (isset($links[$field]) && ($linkedDo =& $this->_dataobject->getLink($field))) {
                         $rec[$field] = DB_DataObject_FormBuilder::getDataObjectString($linkedDo);
                     }
                 }
             }
             $records[] = $rec;
         }
     }
     return $records;
 }
 /**
  * DB_DataObject_FormBuilder::getDataObjectString()
  *
  * Returns a string which identitfies this dataobject.
  * If multiple display fields are given, will display them all seperated by ", ".
  * If a display field is a foreign key (link) the display value for the record it
  * points to will be used as long as the linkDisplayLevel has not been reached.
  * Its display value will be surrounded by parenthesis as it may have multiple
  * display fields of its own.
  *
  * May be called statically.
  *
  * Will use display field configurations from these locations, in this order:
  * 1) $displayFields parameter
  * 2) the fb_linkDisplayFields member variable of the dataobject
  * 3) the linkDisplayFields member variable of this class (if not called statically)
  * 4) all fields returned by the DO's table() function
  *
  * @param DB_DataObject the dataobject to get the display value for, must be populated
  * @param mixed   field to use to display, may be an array with field names or a single field.
  *    Will only be used for this DO, not linked DOs. If you wish to set the display fields
  *    all DOs the same, set the option in the FormBuilder class instance.
  * @param int     the maximum link display level. If null, $this->linkDisplayLebel will be used
  *   if it exists, otherwise 3 will be used. {@see DB_DataObject_FormBuilder::linkDisplayLevel}
  * @param int     the current recursion level. For internal use only.
  * @return string select display value for this field
  * @access public
  */
 function getDataObjectString(&$do, $displayFields = false, $linkDisplayLevel = null, $level = 1)
 {
     if ($linkDisplayLevel === null) {
         $linkDisplayLevel = isset($this) && isset($this->linkDisplayLevel) ? $this->linkDisplayLevel : 3;
     }
     $links = $do->links();
     if ($displayFields === false) {
         if (isset($do->fb_linkDisplayFields)) {
             $displayFields = $do->fb_linkDisplayFields;
         } elseif (isset($this) && isset($this->linkDisplayFields) && $this->linkDisplayFields) {
             $displayFields = $this->linkDisplayFields;
         }
         if (!$displayFields) {
             $displayFields = array_keys($do->table());
         }
     }
     $ret = '';
     $first = true;
     foreach ($displayFields as $field) {
         if ($first) {
             $first = false;
         } else {
             $ret .= ', ';
         }
         if (isset($do->{$field})) {
             if ($linkDisplayLevel > $level && isset($links[$field]) && ($subDo = $do->getLink($field))) {
                 if (isset($this) && is_a($this, 'DB_DataObject_FormBuilder')) {
                     $ret .= '(' . $this->getDataObjectString($subDo, false, $linkDisplayLevel, $level + 1) . ')';
                 } else {
                     $ret .= '(' . DB_DataObject_FormBuilder::getDataObjectString($subDo, false, $linkDisplayLevel, $level + 1) . ')';
                 }
             } else {
                 $ret .= $do->{$field};
             }
         }
     }
     return $ret;
 }
Beispiel #12
0
 function &_generateForm($action = false, $target = '_self', $formName = false, $method = 'post')
 {
     if ($formName === false) {
         $formName = strtolower(get_class($this->_do));
     }
     if ($action === false) {
         $action = $_SERVER['PHP_SELF'];
     }
     // Retrieve the form object to use (may depend on the current renderer)
     $this->_form->_createFormObject($formName, $method, $action, $target);
     // Initialize array with default values
     //$formValues = $this->_do->toArray();
     if ($this->addFormHeader) {
         // Add a header to the form - set addFormHeader property to false to prevent this
         $this->_form->_addFormHeader(is_null($this->formHeaderText) ? $this->prettyName($this->_do->tableName()) : $this->formHeaderText);
     }
     // Go through all table fields and create appropriate form elements
     $keys = $this->_do->keys();
     // Reorder elements if requested, will return _getFieldsToRender if no reordering is needed
     $elements = $this->_reorderElements();
     //get elements to freeze
     $user_editable_fields = $this->_getUserEditableFields();
     if (is_array($user_editable_fields)) {
         $elements_to_freeze = array_diff(array_keys($elements), $user_editable_fields);
     } else {
         $elements_to_freeze = array();
     }
     if (!is_array($links = $this->_do->links())) {
         $links = array();
     }
     $pk = $this->_getPrimaryKey($this->_do);
     $rules = array();
     foreach ($elements as $key => $type) {
         // Check if current field is primary key. And primary key hiding is on. If so, make hidden field
         if (in_array($key, $keys) && $this->hidePrimaryKey == true) {
             $formValues[$key] = $this->_do->{$key};
             $element =& $this->_form->_createHiddenField($key);
         } else {
             unset($element);
             // Try to determine field types depending on object properties
             $notNull = $type & DB_DATAOBJECT_NOTNULL;
             if (in_array($key, $this->dateFields)) {
                 $type = DB_DATAOBJECT_DATE;
             } elseif (in_array($key, $this->timeFields)) {
                 $type = DB_DATAOBJECT_TIME;
             } elseif (in_array($key, $this->textFields)) {
                 $type = DB_DATAOBJECT_TXT;
             } elseif (in_array($key, $this->enumFields)) {
                 $type = DB_DATAOBJECT_FORMBUILDER_ENUM;
             } elseif (in_array($key, $this->booleanFields)) {
                 $type = DB_DATAOBJECT_BOOL;
             }
             if ($notNull || in_array($key, $this->fieldsRequired)) {
                 $type |= DB_DATAOBJECT_NOTNULL;
             }
             if (isset($this->preDefElements[$key]) && (is_object($this->preDefElements[$key]) || is_array($this->preDefElements[$key]))) {
                 // Use predefined form field, IMPORTANT: This may depend on the used renderer!!
                 $element =& $this->preDefElements[$key];
             } elseif (isset($links[$key])) {
                 // If this field links to another table, display selectbox or radiobuttons
                 if (in_array($key, $elements_to_freeze)) {
                     $do =& $this->_do->getLink($key);
                     if (!is_object($do)) {
                         $string = '';
                     } else {
                         $string = $this->getDataObjectString($do);
                     }
                     $element =& $this->_form->_createStaticField($key, $string);
                 } else {
                     $isRadio = isset($this->linkElementTypes[$key]) && $this->linkElementTypes[$key] == 'radio';
                     $opt = $this->getSelectOptions($key, false, false, $isRadio ? $this->radioAddEmptyLabel : $this->selectAddEmptyLabel);
                     if ($isRadio) {
                         $element =& $this->_form->_createRadioButtons($key, $opt);
                     } else {
                         $element =& $this->_form->_createSelectBox($key, $opt);
                     }
                     unset($opt);
                 }
             }
             // No predefined object available, auto-generate new one
             $elValidator = false;
             $elValidRule = false;
             // Auto-detect field types depending on field's database type
             switch (true) {
                 case $type & DB_DATAOBJECT_BOOL:
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $formValues[$key] = $this->_do->{'get' . $key}();
                     } else {
                         $formValues[$key] = $this->_do->{$key};
                     }
                     if ($formValues[$key] === 'f') {
                         $formValues[$key] = 0;
                     }
                     if (!isset($element)) {
                         $element =& $this->_form->_createCheckbox($key, null, null, $this->getFieldLabel($key));
                     }
                     break;
                 case $type & DB_DATAOBJECT_INT:
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $formValues[$key] = $this->_do->{'get' . $key}();
                     } else {
                         $formValues[$key] = $this->_do->{$key};
                     }
                     if (!isset($element)) {
                         $element =& $this->_form->_createIntegerField($key);
                         $elValidator = 'numeric';
                     }
                     break;
                 case $type & DB_DATAOBJECT_DATE && $type & DB_DATAOBJECT_TIME:
                     $this->debug('DATE & TIME CONVERSION using callback for element ' . $key . ' (' . $this->_do->{$key} . ')!', 'FormBuilder');
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $fieldValue = $this->_do->{'get' . $key}();
                     } else {
                         $fieldValue = $this->_do->{$key};
                     }
                     if ($this->isCallableAndExists($this->dateFromDatabaseCallback)) {
                         $formValues[$key] = call_user_func($this->dateFromDatabaseCallback, $fieldValue);
                     } else {
                         $this->debug('WARNING: dateFromDatabaseCallback callback not callable', 'FormBuilder');
                         $formValues[$key] = $fieldValue;
                     }
                     if (!isset($element)) {
                         $element = $this->_form->_createDateTimeElement($key);
                     }
                     break;
                 case $type & DB_DATAOBJECT_DATE:
                     $this->debug('DATE CONVERSION using callback for element ' . $key . ' (' . $this->_do->{$key} . ')!', 'FormBuilder');
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $fieldValue = $this->_do->{'get' . $key}();
                     } else {
                         $fieldValue = $this->_do->{$key};
                     }
                     if ($this->isCallableAndExists($this->dateFromDatabaseCallback)) {
                         $formValues[$key] = call_user_func($this->dateFromDatabaseCallback, $fieldValue);
                     } else {
                         $this->debug('WARNING: dateFromDatabaseCallback callback not callable', 'FormBuilder');
                         $formValues[$key] = $fieldValue;
                     }
                     if (!isset($element)) {
                         $element =& $this->_form->_createDateElement($key);
                     }
                     break;
                 case $type & DB_DATAOBJECT_TIME:
                     $this->debug('TIME CONVERSION using callback for element ' . $key . ' (' . $this->_do->{$key} . ')!', 'FormBuilder');
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $fieldValue = $this->_do->{'get' . $key}();
                     } else {
                         $fieldValue = $this->_do->{$key};
                     }
                     if ($this->isCallableAndExists($this->dateFromDatabaseCallback)) {
                         $formValues[$key] = call_user_func($this->dateFromDatabaseCallback, $fieldValue);
                     } else {
                         $this->debug('WARNING: dateFromDatabaseCallback callback not callable', 'FormBuilder');
                         $formValues[$key] = $fieldValue;
                     }
                     if (!isset($element)) {
                         $element =& $this->_form->_createTimeElement($key);
                     }
                     break;
                 case $type & DB_DATAOBJECT_TXT || $type & DB_DATAOBJECT_BLOB:
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $formValues[$key] = $this->_do->{'get' . $key}();
                     } else {
                         $formValues[$key] = $this->_do->{$key};
                     }
                     if (!isset($element)) {
                         $element =& $this->_form->_createTextArea($key);
                     }
                     break;
                 case $type & DB_DATAOBJECT_STR:
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $formValues[$key] = $this->_do->{'get' . $key}();
                     } else {
                         $formValues[$key] = $this->_do->{$key};
                     }
                     if (!isset($element)) {
                         // If field content contains linebreaks, make textarea - otherwise, standard textbox
                         if (isset($this->_do->{$key}) && strlen($this->_do->{$key}) && strstr($this->_do->{$key}, "\n")) {
                             $element =& $this->_form->_createTextArea($key);
                         } else {
                             $element =& $this->_form->_createTextField($key);
                         }
                     }
                     break;
                 case $type & DB_DATAOBJECT_FORMBUILDER_CROSSLINK:
                     unset($element);
                     $crossLink = $this->crossLinks[$key];
                     $groupName = $this->_sanitizeFieldName($key);
                     $crossLinkDo = DB_DataObject::factory($crossLink['table']);
                     if (PEAR::isError($crossLinkDo)) {
                         throw new Exception($crossLinkDo->getMessage());
                     }
                     if (!is_array($crossLinkLinks = $crossLinkDo->links())) {
                         $crossLinkLinks = array();
                     }
                     list($linkedtable, $linkedfield) = explode(':', $crossLinkLinks[$crossLink['toField']]);
                     list($fromtable, $fromfield) = explode(':', $crossLinkLinks[$crossLink['fromField']]);
                     $all_options = $this->_getSelectOptions($linkedtable, false, false, false, $linkedfield, false, $crossLinkDo, isset($crossLinkDo->fb_crossLinkExtraFields));
                     $colNames = array();
                     $selected_options = array();
                     if (isset($this->_do->{$fromfield})) {
                         $crossLinkDo->{$crossLink['fromField']} = $this->_do->{$fromfield};
                         if ($this->isCallableAndExists($this->prepareLinkedDataObjectCallback)) {
                             call_user_func_array($this->prepareLinkedDataObjectCallback, array(&$crossLinkDo, $key));
                         }
                         if ($crossLinkDo->find() > 0) {
                             while ($crossLinkDo->fetch()) {
                                 $selected_options[$crossLinkDo->{$crossLink['toField']}] = clone $crossLinkDo;
                             }
                         }
                     }
                     if (isset($crossLink['type']) && $crossLink['type'] == 'select') {
                         unset($element);
                         $element =& $this->_form->_createSelectBox($groupName, $all_options, true);
                         $formValues[$groupName] = array_keys($selected_options);
                         // set defaults later
                         // ***X*** generate checkboxes
                     } else {
                         $element = array();
                         $rowNames = array();
                         foreach ($all_options as $optionKey => $value) {
                             if (isset($selected_options[$optionKey])) {
                                 if (!isset($formValues[$groupName])) {
                                     $formValues[$groupName] = array();
                                 }
                                 $formValues[$groupName][$optionKey] = $optionKey;
                             }
                             $crossLinkElement = $this->_form->_createCheckbox($groupName . '[' . $optionKey . ']', $value, $optionKey);
                             $elementNamePrefix = $this->elementNamePrefix . $groupName . '__' . $optionKey . '_';
                             $elementNamePostfix = '_' . $this->elementNamePostfix;
                             //']';
                             if (isset($crossLinkDo->fb_crossLinkExtraFields)) {
                                 $row = array(&$crossLinkElement);
                                 if (isset($selected_options[$optionKey])) {
                                     $extraFieldDo = $selected_options[$optionKey];
                                 } else {
                                     unset($extraFieldDo);
                                     $extraFieldDo = DB_DataObject::factory($crossLink['table']);
                                 }
                                 unset($tempFb);
                                 $tempFb = MyFB::create($extraFieldDo, false, 'QuickForm', get_class($this));
                                 $extraFieldDo->fb_fieldsToRender = $crossLinkDo->fb_crossLinkExtraFields;
                                 $extraFieldDo->fb_elementNamePrefix = $elementNamePrefix;
                                 $extraFieldDo->fb_elementNamePostfix = $elementNamePostfix;
                                 $extraFieldDo->fb_linkNewValue = false;
                                 $this->_extraFieldsFb[$elementNamePrefix . $elementNamePostfix] =& $tempFb;
                                 $tempForm = $tempFb->getForm();
                                 $colNames = array('');
                                 foreach ($crossLinkDo->fb_crossLinkExtraFields as $extraField) {
                                     if ($tempForm->elementExists($elementNamePrefix . $extraField . $elementNamePostfix)) {
                                         $tempEl =& $tempForm->getElement($elementNamePrefix . $extraField . $elementNamePostfix);
                                         $colNames[$extraField] = $tempEl->getLabel();
                                     } else {
                                         $tempEl =& $this->_form->_createStaticField($elementNamePrefix . $extraField . $elementNamePostfix, 'Error - element not found for extra field ' . $extraField);
                                     }
                                     $row[] =& $tempEl;
                                     if (!isset($formValues[$groupName . '__extraFields'])) {
                                         $formValues[$groupName . '__extraFields'] = array();
                                     }
                                     if (!isset($formValues[$groupName . '__extraFields'][$optionKey])) {
                                         $formValues[$groupName . '__extraFields'][$optionKey] = array();
                                     }
                                     $formValues[$groupName . '__extraFields'][$optionKey][$extraField] = $tempEl->getValue();
                                     unset($tempEl);
                                 }
                                 $element[] = $row;
                                 unset($tempFb, $tempForm, $extraFieldDo, $row);
                                 $rowNames[] = '<label for="' . $crossLinkElement->getAttribute('id') . '">' . $value . '</label>';
                                 $crossLinkElement->setText('');
                             } elseif ($crossLink['collapse']) {
                                 $element[] = array(&$crossLinkElement);
                                 $rowNames[] = '<label for="' . $crossLinkElement->getAttribute('id') . '">' . $value . '</label>';
                                 $crossLinkElement->setText('');
                                 $colNames = array();
                             } else {
                                 $element[] =& $crossLinkElement;
                             }
                             unset($crossLinkElement);
                         }
                         if (isset($crossLinkDo->fb_crossLinkExtraFields) || $crossLink['collapse']) {
                             $this->_form->_addElementGrid($groupName, array_values($colNames), $rowNames, $element);
                         } else {
                             $this->_form->_addElementGroup($element, $groupName, $this->crossLinkSeparator);
                         }
                         if ($crossLink['collapse']) {
                             $this->_form->_collapseRecordList($groupName);
                         }
                         unset($element);
                         unset($rowNames);
                         unset($colNames);
                     }
                     break;
                 case $type & DB_DATAOBJECT_FORMBUILDER_TRIPLELINK:
                     unset($element);
                     $tripleLink = $this->tripleLinks[$key];
                     $elName = $this->_sanitizeFieldName('__tripleLink_' . $tripleLink['table'] . '_' . $tripleLink['fromField'] . '_' . $tripleLink['toField1'] . '_' . $tripleLink['toField2']);
                     $freeze = array_search($elName, $elements_to_freeze);
                     unset($tripleLinkDo);
                     $tripleLinkDo = DB_DataObject::factory($tripleLink['table']);
                     if (PEAR::isError($tripleLinkDo)) {
                         throw new Exception($tripleLinkDo->getMessage());
                     }
                     if (!is_array($tripleLinkLinks = $tripleLinkDo->links())) {
                         $tripleLinkLinks = array();
                     }
                     list($linkedtable1, $linkedfield1) = explode(':', $tripleLinkLinks[$tripleLink['toField1']]);
                     list($linkedtable2, $linkedfield2) = explode(':', $tripleLinkLinks[$tripleLink['toField2']]);
                     list($fromtable, $fromfield) = explode(':', $tripleLinkLinks[$tripleLink['fromField']]);
                     //if ($fromtable !== $this->_do->tableName()) error?
                     $all_options1 = $this->_getSelectOptions($linkedtable1, false, false, false, $linkedfield1);
                     $all_options2 = $this->_getSelectOptions($linkedtable2, false, false, false, $linkedfield2);
                     $selected_options = array();
                     if (isset($this->_do->{$fromfield})) {
                         $tripleLinkDo->{$tripleLink['fromField']} = $this->_do->{$fromfield};
                         if ($this->isCallableAndExists($this->prepareLinkedDataObjectCallback)) {
                             call_user_func_array($this->prepareLinkedDataObjectCallback, array(&$tripleLinkDo, $key));
                         }
                         if ($tripleLinkDo->find() > 0) {
                             while ($tripleLinkDo->fetch()) {
                                 $selected_options[$tripleLinkDo->{$tripleLink['toField1']}][] = $tripleLinkDo->{$tripleLink['toField2']};
                             }
                         }
                     }
                     $columnNames = array();
                     foreach ($all_options2 as $key2 => $value2) {
                         $columnNames[] = $value2;
                     }
                     $rows = array();
                     $rowNames = array();
                     $formValues[$key] = array();
                     foreach ($all_options1 as $key1 => $value1) {
                         $rowNames[] = $value1;
                         $row = array();
                         foreach ($all_options2 as $key2 => $value2) {
                             unset($tripleLinkElement);
                             $tripleLinkElement = $this->_form->_createCheckbox($elName . '[' . $key1 . '][' . $key2 . ']', '', $key2);
                             if (isset($selected_options[$key1])) {
                                 if (in_array($key2, $selected_options[$key1])) {
                                     $tripleLinkName = '__tripleLink_' . $tripleLink['table'] . '_' . $tripleLink['fromField'] . '_' . $tripleLink['toField1'] . '_' . $tripleLink['toField2'];
                                     if (!isset($formValues[$tripleLinkName][$key1])) {
                                         $formValues[$tripleLinkName][$key1] = array();
                                     }
                                     $formValues[$tripleLinkName][$key1][$key2] = $key2;
                                 }
                             }
                             $row[] =& $tripleLinkElement;
                         }
                         $rows[] =& $row;
                         unset($row);
                     }
                     $this->_form->_addElementGrid($elName, $columnNames, $rowNames, $rows);
                     unset($columnNames, $rowNames, $rows);
                     break;
                 case $type & DB_DATAOBJECT_FORMBUILDER_ENUM:
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $formValues[$key] = $this->_do->{'get' . $key}();
                     } else {
                         $formValues[$key] = $this->_do->{$key};
                     }
                     if (!isset($element)) {
                         $isRadio = isset($this->linkElementTypes[$key]) && $this->linkElementTypes[$key] == 'radio';
                         if (isset($this->enumOptions[$key])) {
                             $options = $this->enumOptions[$key];
                         } else {
                             if ($this->isCallableAndExists($this->enumOptionsCallback)) {
                                 $options = call_user_func($this->enumOptionsCallback, $this->_do->__table, $key);
                             } else {
                                 $options =& PEAR::raiseError('enumOptionsCallback is an invalid callback');
                             }
                             if (PEAR::isError($options)) {
                                 return $options;
                             }
                         }
                         /*if (array_keys($options) === range(0, count($options)-1)) {
                         				$newOptions = array();
                         				foreach ($options as $value) {
                         				$newOptions[$value] = $value;
                         			}
                         			$options = $newOptions;
                         		}*/
                         if (in_array($key, $this->selectAddEmpty) || !($type & DB_DATAOBJECT_NOTNULL) && !$isRadio) {
                             $options = array('' => $isRadio ? $this->radioAddEmptyLabel : $this->selectAddEmptyLabel) + $options;
                         }
                         if (!$options) {
                             return PEAR::raiseError('There are no options defined for the enum field "' . $key . '". You may need to set the options in the enumOptions option or use your own enumOptionsCallback.');
                         }
                         $element = array();
                         if ($isRadio) {
                             $element =& $this->_form->_createRadioButtons($key, $options);
                         } else {
                             $element =& $this->_form->_createSelectBox($key, $options);
                         }
                         unset($options);
                     }
                     break;
                 case $type & DB_DATAOBJECT_FORMBUILDER_REVERSELINK:
                     unset($element);
                     $element = array();
                     $elName = $this->_sanitizeFieldName('__reverseLink_' . $this->reverseLinks[$key]['table'] . '_' . $this->reverseLinks[$key]['field']);
                     unset($do);
                     $do = DB_DataObject::factory($this->reverseLinks[$key]['table']);
                     if ($this->isCallableAndExists($this->prepareLinkedDataObjectCallback)) {
                         call_user_func_array($this->prepareLinkedDataObjectCallback, array(&$do, $key));
                     }
                     if (!is_array($rLinks = $do->links())) {
                         $rLinks = array();
                     }
                     $rPk = $this->_getPrimaryKey($do);
                     //$rFields = $do->table();
                     list($lTable, $lField) = explode(':', $rLinks[$this->reverseLinks[$key]['field']]);
                     $formValues[$elName] = array();
                     if ($this->reverseLinks[$key]['collapse']) {
                         $table = $rowNames = array();
                     }
                     if (is_array($do->fb_linkOrderFields)) {
                         $orderStr = implode(', ', $do->fb_linkOrderFields);
                         if ($orderStr) {
                             $do->orderBy($orderStr);
                         }
                     }
                     if ($do->find()) {
                         while ($do->fetch()) {
                             $label = $this->getDataObjectString($do);
                             if ($do->{$this->reverseLinks[$key]['field']} == $this->_do->{$lField}) {
                                 $formValues[$elName][$do->{$rPk}] = $do->{$rPk};
                             } elseif ($rLinked =& $do->getLink($this->reverseLinks[$key]['field'])) {
                                 $label .= '<b>' . $this->reverseLinks[$key]['linkText'] . $this->getDataObjectString($rLinked) . '</b>';
                             }
                             if (isset($this->linkElementTypes[$elName]) && $this->linkElementTypes[$elName] == 'subForm') {
                                 unset($subFB, $subForm, $subFormEl);
                                 $subFB =& DB_DataObject_FormBuilder::create($do, false, 'QuickForm', get_class($this));
                                 $this->reverseLinks[$key]['FBs'][] =& $subFB;
                                 $subFB->elementNamePrefix = $elName;
                                 $subFB->elementNamePostfix = '_' . count($this->reverseLinks[$key]['FBs']);
                                 $subFB->createSubmit = false;
                                 $subFB->formHeaderText = $this->getDataObjectString($do);
                                 //$this->getFieldLabel($elName).' '.count($this->reverseLinks[$key]['FBs']);
                                 $do->fb_linkNewValue = false;
                                 $subForm =& $subFB->getForm();
                                 $this->reverseLinks[$key]['SFs'][] = $subForm;
                                 $subFormEl =& $this->_form->_createSubForm($elName . count($this->reverseLinks[$key]['FBs']), null, $subForm);
                                 $element[] =& $subFormEl;
                             } else {
                                 if ($this->reverseLinks[$key]['collapse']) {
                                     $table[] = array($this->_form->_createCheckbox($elName . '[' . $do->{$rPk} . ']', '', $do->{$rPk}));
                                     $rowNames[] = $label;
                                 } else {
                                     $element[] =& $this->_form->_createCheckbox($elName . '[' . $do->{$rPk} . ']', $label, $do->{$rPk});
                                 }
                             }
                         }
                     }
                     if (isset($this->reverseLinkNewValue[$elName]) && $this->reverseLinkNewValue[$elName] !== false) {
                         if (is_int($this->reverseLinkNewValue[$elName])) {
                             $totalSubforms = $this->reverseLinkNewValue[$elName];
                         } else {
                             $totalSubforms = 1;
                         }
                         for ($i = 0; $i < $totalSubforms; $i++) {
                             unset($subFB, $subForm, $subFormEl);
                             // Add a subform to add a new reverseLink record.
                             $do = DB_DataObject::factory($this->reverseLinks[$key]['table']);
                             $do->{$lField} = $this->_do->{$this->_getPrimaryKey($this->_do)};
                             $subFB =& DB_DataObject_FormBuilder::create($do, false, 'QuickForm', get_class($this));
                             $this->reverseLinks[$key]['FBs'][] =& $subFB;
                             $subFB->elementNamePrefix = $elName;
                             $subFB->elementNamePostfix = '_' . count($this->reverseLinks[$key]['FBs']);
                             $subFB->createSubmit = false;
                             $subFB->formHeaderText = 'New ' . (isset($do->fb_formHeaderText) ? $do->fb_formHeaderText : $this->prettyName($do->__table));
                             $do->fb_linkNewValue = false;
                             $subForm =& $subFB->getForm();
                             $this->reverseLinks[$key]['SFs'][] =& $subForm;
                             $subFormEl =& $this->_form->_createSubForm($elName . count($this->reverseLinks[$key]['FBs']), null, $subForm);
                             $element[] =& $subFormEl;
                         }
                     }
                     if ($this->reverseLinks[$key]['collapse']) {
                         $this->_form->_addElementGrid($elName, array(), $rowNames, $table);
                         $this->_form->_collapseRecordList($elName);
                     } else {
                         $this->_form->_addElementGroup($element, $elName, $this->crossLinkSeparator);
                     }
                     unset($element);
                     break;
                 case $type & DB_DATAOBJECT_FORMBUILDER_GROUP:
                     unset($element);
                     $element =& $this->_form->_createHiddenField($key . '__placeholder');
                     break;
                 default:
                     if ($this->useAccessors && method_exists($this->_do, 'get' . $key)) {
                         $formValues[$key] = $this->_do->{'get' . $key}();
                     } else {
                         $formValues[$key] = $this->_do->{$key};
                     }
                     if (!isset($element)) {
                         $element =& $this->_form->_createTextField($key);
                     }
             }
             // End switch
             //} // End else
             if ($elValidator !== false) {
                 if (!isset($rules[$key])) {
                     $rules[$key] = array();
                 }
                 $rules[$key][] = array('validator' => $elValidator, 'rule' => $elValidRule, 'message' => $this->ruleViolationMessage);
             }
             // End if
         }
         // End else
         //GROUP OR ELEMENT ADDITION
         if (isset($this->preDefGroups[$key]) && !($type & DB_DATAOBJECT_FORMBUILDER_GROUP)) {
             $group = $this->preDefGroups[$key];
             $groups[$group][] = $element;
         } elseif (isset($element)) {
             if (is_array($element)) {
                 $this->_form->_addElementGroup($element, $key);
             } else {
                 $this->_form->_addElement($element);
             }
         }
         // End if
         //SET AUTO-RULES IF NOT DEACTIVATED FOR THIS OR ALL ELEMENTS
         if (!$this->_excludeAllFromAutoRules && !in_array($key, $this->excludeFromAutoRules)) {
             //ADD REQURED RULE FOR NOT_NULL FIELDS
             if ((!in_array($key, $keys) || $this->hidePrimaryKey == false) && $type & DB_DATAOBJECT_NOTNULL && !in_array($key, $elements_to_freeze) && !($type & DB_DATAOBJECT_BOOL)) {
                 $this->_form->_setFormElementRequired($key);
                 $this->debug('Adding required rule for ' . $key);
             }
             // VALIDATION RULES
             if (isset($rules[$key])) {
                 $this->_form->_addFieldRules($rules[$key], $key);
                 $this->debug("Adding rule '{$rules[$key]}' to {$key}");
             }
         } else {
             $this->debug($key . ' excluded from auto-rules');
         }
     }
     // End foreach
     if ($this->linkNewValue) {
         $this->_form->_addRuleForLinkNewValues();
     }
     // Freeze fields that are not to be edited by the user
     $this->_form->_freezeFormElements($elements_to_freeze);
     //GROUP SUBMIT
     $flag = true;
     if (isset($this->preDefGroups['__submit__'])) {
         $group = $this->preDefGroups['__submit__'];
         if (count($groups[$group]) > 1) {
             $groups[$group][] =& $this->_form->_createSubmitButton('__submit__', $this->submitText);
             $flag = false;
         } else {
             $flag = true;
         }
     }
     //GROUPING
     if (isset($groups) && is_array($groups)) {
         //apply grouping
         reset($groups);
         while (list($grp, $elements) = each($groups)) {
             if (count($elements) == 1) {
                 $this->_form->_addElement($elements[0]);
                 $this->_form->_moveElementBefore($this->_form->_getElementName($elements[0]), $grp . '__placeholder');
             } elseif (count($elements) > 1) {
                 $this->_form->_addElementGroup($elements, $grp, '&nbsp;');
                 $this->_form->_moveElementBefore($grp, $grp . '__placeholder');
             }
         }
     }
     //ELEMENT SUBMIT
     if ($flag == true && $this->createSubmit == true) {
         $this->_form->_addSubmitButton('__submit__', $this->submitText);
     }
     $this->_form->_finishForm();
     // Assign default values to the form
     $fixedFormValues = array();
     foreach ($formValues as $key => $value) {
         if (in_array($key, $elements_to_freeze) && isset($links[$key])) {
         } else {
             $fixedFormValues[$this->getFieldName($key)] = $value;
         }
     }
     $this->_form->_setFormDefaults($fixedFormValues);
     return $this->_form->getForm();
 }