$category->category_description = $category_description;
     if ($category->category_parent != $category_parent || $action == "add") {
         if ($category_parent > 0) {
             $q = $db->prepare("SELECT IFNULL(MAX(category_order), 0) AS ord FROM phph_categories WHERE category_parent = ?");
             $res = $db->execute($q, $category_parent);
         } else {
             $q = $db->prepare("SELECT IFNULL(MAX(category_order)) AS ord FROM phph_categories WHERE category_parent IS NULL");
             $res = $db->execute($q, $category_parent);
         }
         $row = $res->fetchRow();
         $category->category_order = $row['ord'] + 1;
     }
     if ($category_parent > 0) {
         $category->category_parent = $category_parent;
     } else {
         $category->category_parent = DB_DataObject_Cast::sql("NULL");
     }
     if ($action == "edit") {
         $r = $category->update();
     } elseif ($action == "add") {
         $r = $category->insert();
     }
     if (PEAR::isError($r)) {
         throw new Exception2(_INTERNAL_ERROR, $r->getMessage());
     }
     if (!empty($ref)) {
         header("Location: " . $ref);
     }
     $pane = new HTML_MessagePane("upd", $action == "add" ? _ADMIN_CATEGORY_CREATED : _ADMIN_CATEGORY_UPDATED, "", "a_ok_pane", "a_ok_pane_hdr");
     $pane->show();
 } catch (Exception2 $e) {
示例#2
0
 /**
  * DB_DataObject_FormBuilder::processForm()
  *
  * This will take the submitted form data and put it back into the object's properties.
  * If the primary key is not set or NULL, it will be assumed that you wish to insert a new
  * element into the database, so DataObject's insert() method is invoked.
  * Otherwise, an update() will be performed.
  * <i><b>Careful:</b> If you're using natural keys or cross-referencing tables where you don't have
  * one dedicated primary key, this will always assume that you want to do an update! As there
  * won't be a matching entry in the table, no action will be performed at all - the reason
  * for this behaviour can be very hard to detect. Thus, if you have such a situation in one
  * of your tables, simply override this method so that instead of the key check it will try
  * to do a SELECT on the table using the current settings. If a match is found, do an update.
  * If not, do an insert.</i>
  * This method is perfect for use with QuickForm's process method. Example:
  * <code>
  * if ($form->validate()) {
  *     $form->freeze();
  *     $form->process(array(&$formGenerator,'processForm'), false);
  * }
  * </code>
  *
  * If you wish to enforce a special type of query, use the forceQueryType() method.
  *
  * Always remember to pass your objects by reference - otherwise, if the operation was
  * an insert, the primary key won't get updated with the new database ID because processForm()
  * was using a local copy of the object!
  *
  * If a method named "preProcessForm()" exists in your derived class, it will be called before
  * processForm() starts doing its magic. The data that has been submitted by the form
  * will be passed to that method as a parameter.
  * Same goes for a method named "postProcessForm()", with the only difference - you might
  * have guessed this by now - that it's called after the insert/update operations have
  * been done. Use this for filtering data, notifying users of changes etc.pp. ...
  *
  * @param array $values   The values of the submitted form
  * @return mixed        TRUE if database operations were performed, FALSE if not, PEAR_Error on error
  * @access public
  */
 function processForm($values)
 {
     $origDo = clone $this->_do;
     if ($this->elementNamePrefix !== '' || $this->elementNamePostfix !== '') {
         $origValues = $values;
         $values = $this->_getMyValues($values);
     }
     $this->debug('<br>...processing form data...<br>');
     if ($this->isCallableAndExists($this->preProcessFormCallback)) {
         call_user_func_array($this->preProcessFormCallback, array(&$values, &$this));
     }
     $editableFields = array_intersect($this->_getUserEditableFields(), array_keys($this->_getFieldsToRender()));
     $tableFields = $this->_do->table();
     if (!is_array($links = $this->_do->links())) {
         $links = array();
     }
     foreach ($values as $field => $value) {
         $this->debug('Field ' . $field . ' ');
         // Double-check if the field may be edited by the user... if not, don't
         // set the submitted value, it could have been faked!
         if (in_array($field, $editableFields)) {
             if (isset($tableFields[$field])) {
                 if ($tableFields[$field] & DB_DATAOBJECT_DATE || in_array($field, $this->dateFields)) {
                     $this->debug('DATE CONVERSION for using callback from ' . $value . ' ...');
                     if ($this->isCallableAndExists($this->dateToDatabaseCallback)) {
                         $value = call_user_func($this->dateToDatabaseCallback, $value);
                     } else {
                         $this->debug('WARNING: dateToDatabaseCallback not callable', 'FormBuilder');
                     }
                 } elseif ($tableFields[$field] & DB_DATAOBJECT_TIME || in_array($field, $this->timeFields)) {
                     $this->debug('TIME CONVERSION for using callback from ' . $value . ' ...');
                     if ($this->isCallableAndExists($this->dateToDatabaseCallback)) {
                         $value = call_user_func($this->dateToDatabaseCallback, $value);
                     } else {
                         $this->debug('WARNING: dateToDatabaseCallback not callable', 'FormBuilder');
                     }
                 } elseif (is_array($value)) {
                     if (isset($value['tmp_name'])) {
                         $this->debug(' (converting file array) ');
                         $value = $value['name'];
                         //JUSTIN
                         //This is not really a valid assumption IMHO. This should only be done if the type is
                         // date or the field is in dateFields
                         /*} else {
                           $this->debug("DATE CONVERSION using callback from $value ...");
                           $value = call_user_func($this->dateToDatabaseCallback, $value);*/
                     }
                 }
                 if (isset($links[$field])) {
                     if ($value == $this->linkNewValueText && $tableFields[$field] & DB_DATAOBJECT_INT) {
                         $value = 0;
                     } elseif ($value === '') {
                         $this->debug('Casting to NULL');
                         require_once 'DB/DataObject/Cast.php';
                         $value = DB_DataObject_Cast::sql('NULL');
                     }
                 }
                 $this->debug('is substituted with "' . print_r($value, true) . '".<br/>');
                 // See if a setter method exists in the DataObject - if so, use that one
                 if ($this->useMutators && method_exists($this->_do, 'set' . $field)) {
                     $this->_do->{'set' . $field}($value);
                 } else {
                     // Otherwise, just set the property 'normally'...
                     $this->_do->{$field} = $value;
                 }
             } else {
                 $this->debug('is not a valid field.<br/>');
             }
         } else {
             $this->debug('is defined not to be editable by the user!<br/>');
         }
     }
     foreach ($this->booleanFields as $boolField) {
         if (in_array($boolField, $editableFields) && !isset($values[$boolField])) {
             if ($this->useMutators && method_exists($this->_do, 'set' . $boolField)) {
                 $this->_do->{'set' . $boolField}(0);
             } else {
                 $this->_do->{$boolField} = 0;
             }
         }
     }
     foreach ($tableFields as $field => $type) {
         if ($type & DB_DATAOBJECT_BOOL && in_array($field, $editableFields) && !isset($values[$field])) {
             if ($this->useMutators && method_exists($this->_do, 'set' . $field)) {
                 $this->_do->{'set' . $field}(0);
             } else {
                 $this->_do->{$field} = 0;
             }
         }
     }
     $dbOperations = true;
     if ($this->validateOnProcess === true) {
         $this->debug('Validating data... ');
         if (is_array($errors = $this->validateData())) {
             $dbOperations = false;
         }
     }
     $pk = $this->_getPrimaryKey($this->_do);
     // Data is valid, let's store it!
     if ($dbOperations) {
         //take care of linkNewValues
         /*if (isset($values['__DB_DataObject_FormBuilder_linkNewValue_'])) {
           foreach ($values['__DB_DataObject_FormBuilder_linkNewValue_'] as $elName => $subTable) {*/
         if (isset($this->_form->_linkNewValueForms)) {
             foreach (array_keys($this->_form->_linkNewValueForms) as $elName) {
                 $subTable = $this->_form->_linkNewValueDOs[$elName]->tableName();
                 if (isset($values['__DB_DataObject_FormBuilder_linkNewValue__' . $elName])) {
                     if ($values[$elName] == $this->linkNewValueText) {
                         //$this->_form->_prepareForLinkNewValue($elName, $subTable);
                         $ret = $this->_form->_linkNewValueForms[$elName]->process(array(&$this->_form->_linkNewValueFBs[$elName], 'processForm'), false);
                         if (PEAR::isError($ret)) {
                             $this->debug('Error processing linkNewValue for ' . serialize($this->_form->_linkNewValueDOs[$elName]));
                             return PEAR::raiseError('Error processing linkNewValue - Error from processForm: ' . $ret->getMessage(), null, null, null, $this->_form->_linkNewValueDOs[$elName]);
                         }
                         $subPk = $this->_form->_linkNewValueFBs[$elName]->_getPrimaryKey($this->_form->_linkNewValueDOs[$elName]);
                         $this->_do->{$elName} = $values[$elName] = $this->_form->_linkNewValueDOs[$elName]->{$subPk};
                     }
                 }
             }
         }
         $action = $this->_queryType;
         if ($this->_queryType == DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT) {
             // Could the primary key be detected?
             if ($pk === false) {
                 // Nope, so let's exit and return false. Sorry, you can't store data using
                 // processForm with this DataObject unless you do some tweaking :-(
                 $this->debug('Primary key not detected - storing data not possible.');
                 return false;
             }
             $action = DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE;
             if (!isset($this->_do->{$pk}) || !strlen($this->_do->{$pk})) {
                 $action = DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT;
             }
         }
         switch ($action) {
             case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT:
                 if (false === ($id = $this->_do->insert())) {
                     $this->debug('Insert of main record failed');
                     return $this->_raiseDoError('Insert of main record failed', $this->_do);
                 }
                 $this->debug('ID (' . $pk . ') of the new object: ' . $id . '<br/>');
                 break;
             case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE:
                 if (false === $this->_do->update($origDo)) {
                     $this->debug('Update of main record failed');
                     return $this->_raiseDoError('Update of main record failed', $this->_do);
                 }
                 $this->debug('Object updated.<br/>');
                 break;
         }
         // process tripleLinks
         foreach ($this->tripleLinks as $tripleLink) {
             $tripleLinkName = $this->_sanitizeFieldName('__tripleLink_' . $tripleLink['table'] . '_' . $tripleLink['fromField'] . '_' . $tripleLink['toField1'] . '_' . $tripleLink['toField2']);
             if (in_array($tripleLinkName, $editableFields)) {
                 unset($do);
                 $do = DB_DataObject::factory($tripleLink['table']);
                 $fromField = $tripleLink['fromField'];
                 $toField1 = $tripleLink['toField1'];
                 $toField2 = $tripleLink['toField2'];
                 if (isset($values[$tripleLinkName])) {
                     $rows = $values[$tripleLinkName];
                 } else {
                     $rows = array();
                 }
                 $links = $do->links();
                 list($linkTable, $linkField) = explode(':', $links[$fromField]);
                 $do->{$fromField} = $this->_do->{$linkField};
                 $do->selectAdd();
                 $do->selectAdd($toField1);
                 $do->selectAdd($toField2);
                 if ($doKey = $this->_getPrimaryKey($do)) {
                     $do->selectAdd($doKey);
                 }
                 if ($this->isCallableAndExists($this->prepareLinkedDataObjectCallback)) {
                     call_user_func_array($this->prepareLinkedDataObjectCallback, array(&$do, $tripleLinkName));
                 }
                 $oldFieldValues = array();
                 if ($do->find()) {
                     while ($do->fetch()) {
                         if (isset($rows[$do->{$toField1}]) && isset($rows[$do->{$toField1}][$do->{$toField2}])) {
                             $oldFieldValues[$do->{$toField1}][$do->{$toField2}] = true;
                         } else {
                             if (false === $do->delete()) {
                                 $this->debug('Failed to delete tripleLink ' . serialize($do));
                                 return $this->_raiseDoError('Failed to delete tripleLink', $do);
                             }
                         }
                     }
                 }
                 if (count($rows) > 0) {
                     foreach ($rows as $rowid => $row) {
                         if (count($row) > 0) {
                             foreach ($row as $fieldvalue => $on) {
                                 if (!isset($oldFieldValues[$rowid]) || !isset($oldFieldValues[$rowid][$fieldvalue])) {
                                     unset($do);
                                     $do = DB_DataObject::factory($tripleLink['table']);
                                     $do->{$fromField} = $this->_do->{$linkField};
                                     $do->{$toField1} = $rowid;
                                     $do->{$toField2} = $fieldvalue;
                                     if (false === $do->insert()) {
                                         $this->debug('Failed to insert tripleLink ' . serialize($do));
                                         return $this->_raiseDoError('Failed to insert tripleLink', $do);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
         //process crossLinks
         foreach ($this->crossLinks as $crossLink) {
             $crossLinkName = $this->_sanitizeFieldName('__crossLink_' . $crossLink['table'] . '_' . $crossLink['fromField'] . '_' . $crossLink['toField']);
             if (in_array($crossLinkName, $editableFields)) {
                 unset($do);
                 $do = DB_DataObject::factory($crossLink['table']);
                 $fromField = $crossLink['fromField'];
                 $toField = $crossLink['toField'];
                 if (isset($values[$crossLinkName])) {
                     if ($crossLink['type'] == 'select') {
                         $fieldvalues = array();
                         foreach ($values[$crossLinkName] as $value) {
                             $fieldvalues[$value] = $value;
                         }
                     } else {
                         $fieldvalues = $values[$crossLinkName];
                     }
                 } else {
                     $fieldvalues = array();
                 }
                 /*if (isset($values['__crossLink_'.$crossLink['table'].'__extraFields'])) {
                       $extraFieldValues = $values['__crossLink_'.$crossLink['table'].'__extraFields'];
                   } else {
                       $extraFieldValues = array();
                   }*/
                 $links = $do->links();
                 list($linkTable, $linkField) = explode(':', $links[$fromField]);
                 $do->{$fromField} = $this->_do->{$linkField};
                 $do->selectAdd();
                 $do->selectAdd($toField);
                 $do->selectAdd($fromField);
                 if ($doKey = $this->_getPrimaryKey($do)) {
                     $do->selectAdd($doKey);
                 }
                 if ($this->isCallableAndExists($this->prepareLinkedDataObjectCallback)) {
                     call_user_func_array($this->prepareLinkedDataObjectCallback, array(&$do, $crossLinkName));
                 }
                 $oldFieldValues = array();
                 if ($do->find()) {
                     while ($do->fetch()) {
                         if (isset($fieldvalues[$do->{$toField}])) {
                             $oldFieldValues[$do->{$toField}] = clone $do;
                         } else {
                             if (false === $do->delete()) {
                                 $this->debug('Failed to delete crossLink ' . serialize($do));
                                 return $this->_raiseDoError('Failed to delete crossLink', $do);
                             }
                         }
                     }
                 }
                 if (count($fieldvalues) > 0) {
                     foreach ($fieldvalues as $fieldvalue => $on) {
                         $crossLinkPrefix = $this->elementNamePrefix . $crossLinkName . '__' . $fieldvalue . '_';
                         $crossLinkPostfix = '_' . $this->elementNamePostfix;
                         if (isset($oldFieldValues[$fieldvalue])) {
                             if (isset($do->fb_crossLinkExtraFields) && (!isset($crossLink['type']) || $crossLink['type'] !== 'select')) {
                                 $ret = $this->_extraFieldsFb[$crossLinkPrefix . $crossLinkPostfix]->processForm(isset($origValues) ? $origValues : $values);
                                 if (PEAR::isError($ret)) {
                                     $this->debug('Failed to process extraFields for crossLink ' . serialize($do));
                                     return PEAR::raiseError('Failed to process extraFields crossLink - Error from processForm: ' . $ret->getMessage(), null, null, null, $do);
                                 }
                             }
                         } else {
                             if (isset($do->fb_crossLinkExtraFields) && (!isset($crossLink['type']) || $crossLink['type'] !== 'select')) {
                                 $insertValues = isset($origValues) ? $origValues : $values;
                                 $insertValues[$crossLinkPrefix . $fromField . $crossLinkPostfix] = $this->_do->{$linkField};
                                 $insertValues[$crossLinkPrefix . $toField . $crossLinkPostfix] = $fieldvalue;
                                 $this->_extraFieldsFb[$crossLinkPrefix . $crossLinkPostfix]->fieldsToRender[] = $fromField;
                                 $this->_extraFieldsFb[$crossLinkPrefix . $crossLinkPostfix]->fieldsToRender[] = $toField;
                                 $ret = $this->_extraFieldsFb[$crossLinkPrefix . $crossLinkPostfix]->processForm($insertValues);
                                 if (PEAR::isError($ret)) {
                                     $this->debug('Failed to process extraFields for crossLink ' . serialize($do));
                                     return PEAR::raiseError('Failed to process extraFields crossLink - Error from processForm: ' . $ret->getMessage(), null, null, null, $do);
                                 }
                             } else {
                                 unset($do);
                                 $do = DB_DataObject::factory($crossLink['table']);
                                 $do->{$fromField} = $this->_do->{$linkField};
                                 $do->{$toField} = $fieldvalue;
                                 if (false === $do->insert()) {
                                     $this->debug('Failed to insert crossLink ' . serialize($do));
                                     return $this->_raiseDoError('Failed to insert crossLink', $do);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         foreach ($this->reverseLinks as $reverseLink) {
             $elName = $this->_sanitizeFieldName('__reverseLink_' . $reverseLink['table'] . '_' . $reverseLink['field']);
             if (in_array($elName, $editableFields)) {
                 // Check for subforms
                 if (isset($this->linkElementTypes[$elName]) && $this->linkElementTypes[$elName] == 'subForm') {
                     foreach ($reverseLink['SFs'] as $sfkey => $subform) {
                         // Process each subform that was rendered.
                         if ($subform->validate()) {
                             $ret = $subform->process(array(&$reverseLink['FBs'][$sfkey], 'processForm'), false);
                             if (PEAR::isError($ret)) {
                                 $this->debug('Failed to process subForm for reverseLink ' . serialize($reverseLink['FBs'][$sfkey]->_do));
                                 return PEAR::raiseError('Failed to process extraFields crossLink - Error from processForm: ' . $ret->getMessage(), null, null, null, $reverseLink['FBs'][$sfkey]->_do);
                             }
                         }
                     }
                 } else {
                     unset($do);
                     $do = DB_DataObject::factory($reverseLink['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[$reverseLink['field']]);
                     if ($do->find()) {
                         while ($do->fetch()) {
                             unset($newVal);
                             if (isset($values[$elName][$do->{$rPk}])) {
                                 if ($do->{$reverseLink['field']} != $this->_do->{$lField}) {
                                     $do->{$reverseLink['field']} = $this->_do->{$lField};
                                     if (false === $do->update()) {
                                         $this->debug('Failed to update reverseLink ' . serialize($do));
                                         return $this->_raiseDoError('Failed to update reverseLink', $do);
                                     }
                                 }
                             } elseif ($do->{$reverseLink['field']} == $this->_do->{$lField}) {
                                 if (isset($reverseLink['defaultLinkValue'])) {
                                     $do->{$reverseLink['field']} = $reverseLink['defaultLinkValue'];
                                     if (false === $do->update()) {
                                         $this->debug('Failed to update reverseLink ' . serialize($do));
                                         return $this->_raiseDoError('Failed to update reverseLink', $do);
                                     }
                                 } else {
                                     if ($rFields[$reverseLink['field']] & DB_DATAOBJECT_NOTNULL) {
                                         //ERROR!!
                                         $this->debug('Checkbox in reverseLinks unset when link field may not be null');
                                     } else {
                                         require_once 'DB/DataObject/Cast.php';
                                         $do->{$reverseLink['field']} = DB_DataObject_Cast::sql('NULL');
                                         if (false === $do->update()) {
                                             $this->debug('Failed to update reverseLink ' . serialize($do));
                                             return $this->_raiseDoError('Failed to update reverseLink', $do);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if ($this->isCallableAndExists($this->postProcessFormCallback)) {
         call_user_func_array($this->postProcessFormCallback, array(&$values, &$this));
     }
     return $dbOperations;
 }
示例#3
0
 /**
  * DB_DataObject_FormBuilder::processForm()
  *
  * This will take the submitted form data and put it back into the object's properties.
  * If the primary key is not set or NULL, it will be assumed that you wish to insert a new
  * element into the database, so DataObject's insert() method is invoked.
  * Otherwise, an update() will be performed.
  * <i><b>Careful:</b> If you're using natural keys or cross-referencing tables where you don't have
  * one dedicated primary key, this will always assume that you want to do an update! As there
  * won't be a matching entry in the table, no action will be performed at all - the reason
  * for this behaviour can be very hard to detect. Thus, if you have such a situation in one
  * of your tables, simply override this method so that instead of the key check it will try
  * to do a SELECT on the table using the current settings. If a match is found, do an update.
  * If not, do an insert.</i>
  * This method is perfect for use with QuickForm's process method. Example:
  * <code>
  * if ($form->validate()) {
  *     $form->freeze();
  *     $form->process(array(&$formGenerator,'processForm'), false);
  * }
  * </code>
  *
  * If you wish to enforce a special type of query, use the forceQueryType() method.
  *
  * Always remember to pass your objects by reference - otherwise, if the operation was
  * an insert, the primary key won't get updated with the new database ID because processForm()
  * was using a local copy of the object!
  *
  * If a method named "preProcessForm()" exists in your derived class, it will be called before
  * processForm() starts doing its magic. The data that has been submitted by the form
  * will be passed to that method as a parameter.
  * Same goes for a method named "postProcessForm()", with the only difference - you might
  * have guessed this by now - that it's called after the insert/update operations have
  * been done. Use this for filtering data, notifying users of changes etc.pp. ...
  *
  * @param array $values   The values of the submitted form
  * @param string $queryType If the standard query behaviour ain't good enough for you, you can force a certain type of query
  * @return boolean        TRUE if database operations were performed, FALSE if not
  * @access public
  */
 function processForm($values)
 {
     if ($this->elementNamePrefix !== '' || $this->elementNamePostfix !== '') {
         $values = $this->_getMyValues($values);
     }
     $this->debug('<br>...processing form data...<br>');
     if (method_exists($this->_do, 'preprocessform')) {
         if ($this->useCallTimePassByReference) {
             $this->_do->preProcessForm(&$values);
         } else {
             $this->_do->preProcessForm($values);
         }
     }
     $editableFields = $this->_getUserEditableFields();
     $tableFields = $this->_do->table();
     $links = $this->_do->links();
     foreach ($values as $field => $value) {
         $this->debug('Field ' . $field . ' ');
         // Double-check if the field may be edited by the user... if not, don't
         // set the submitted value, it could have been faked!
         if (in_array($field, $editableFields)) {
             if (isset($tableFields[$field])) {
                 if ($tableFields[$field] & DB_DATAOBJECT_DATE || in_array($field, $this->dateFields)) {
                     $this->debug('DATE CONVERSION for using callback from ' . $value . ' ...');
                     $value = call_user_func($this->dateToDatabaseCallback, $value);
                 } elseif ($tableFields[$field] & DB_DATAOBJECT_TIME || in_array($field, $this->timeFields)) {
                     $this->debug('TIME CONVERSION for using callback from ' . $value . ' ...');
                     $value = call_user_func($this->dateToDatabaseCallback, $value);
                 } elseif (is_array($value)) {
                     if (isset($value['tmp_name'])) {
                         $this->debug(' (converting file array) ');
                         $value = $value['name'];
                         //JUSTIN
                         //This is not really a valid assumption IMHO. This should only be done if the type is
                         // date or the field is in dateFields
                         /*} else {
                           $this->debug("DATE CONVERSION using callback from $value ...");
                           $value = call_user_func($this->dateToDatabaseCallback, $value);*/
                     }
                 }
                 if (is_array($links) && isset($links[$field])) {
                     if ($value === '') {
                         $this->debug('Casting to NULL');
                         require_once 'DB/DataObject/Cast.php';
                         $value = DB_DataObject_Cast::sql('NULL');
                     }
                 }
                 $this->debug('is substituted with "' . print_r($value, true) . '".<br/>');
                 // See if a setter method exists in the DataObject - if so, use that one
                 if (method_exists($this->_do, 'set' . $field)) {
                     $this->_do->{'set' . $field}($value);
                 } else {
                     // Otherwise, just set the property 'normally'...
                     $this->_do->{$field} = $value;
                 }
             } else {
                 $this->debug('is not a valid field.<br/>');
             }
         } else {
             $this->debug('is defined not to be editable by the user!<br/>');
         }
     }
     foreach ($this->booleanFields as $boolField) {
         if (!isset($values[$boolField])) {
             $this->_do->{$boolField} = 0;
         }
     }
     $dbOperations = true;
     if ($this->validateOnProcess === true) {
         $this->debug('Validating data... ');
         if (is_array($this->validateData())) {
             $dbOperations = false;
         }
     }
     $pk = $this->_getPrimaryKey($this->_do);
     // Data is valid, let's store it!
     if ($dbOperations) {
         $action = $this->_queryType;
         if ($this->_queryType == DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT) {
             // Could the primary key be detected?
             if ($pk === false) {
                 // Nope, so let's exit and return false. Sorry, you can't store data using
                 // processForm with this DataObject unless you do some tweaking :-(
                 $this->debug('Primary key not detected - storing data not possible.');
                 return false;
             }
             $action = DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE;
             if (!isset($this->_do->{$pk}) || !strlen($this->_do->{$pk})) {
                 $action = DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT;
             }
         }
         switch ($action) {
             case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT:
                 $id = $this->_do->insert();
                 $this->debug('ID (' . $pk . ') of the new object: ' . $id . '<br/>');
                 break;
             case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE:
                 $this->_do->update();
                 $this->debug('Object updated.<br/>');
                 break;
         }
         //triple/crossLinks only work when a primark key is set
         if ($pk && isset($this->_do->{$pk}) && strlen($this->_do->{$pk})) {
             // process tripleLinks
             foreach ($this->tripleLinks as $tripleLink) {
                 $do = DB_DataObject::factory($tripleLink['table']);
                 $links = $do->links();
                 $fromField = $tripleLink['fromField'];
                 $toField1 = $tripleLink['toField1'];
                 $toField2 = $tripleLink['toField2'];
                 if (isset($values['__tripleLink_' . $tripleLink['table']])) {
                     $rows = $values['__tripleLink_' . $tripleLink['table']];
                 } else {
                     $rows = array();
                 }
                 $do->{$fromField} = $this->_do->{$pk};
                 $do->selectAdd();
                 $do->selectAdd($toField1);
                 $do->selectAdd($toField2);
                 $do->find();
                 $oldFieldValues = array();
                 while ($do->fetch()) {
                     if (isset($rows[$do->{$toField1}]) && in_array($do->{$toField2}, $rows[$do->{$toField1}])) {
                         $oldFieldValues[$do->{$toField1}][$do->{$toField2}] = true;
                     } else {
                         $do->delete();
                     }
                 }
                 if (count($rows) > 0) {
                     foreach ($rows as $rowid => $row) {
                         if (count($row) > 0) {
                             foreach ($row as $fieldvalue) {
                                 if (!isset($oldFieldValues[$rowid]) || !isset($oldFieldValues[$rowid][$fieldvalue])) {
                                     $do = DB_DataObject::factory($tripleLink['table']);
                                     $do->{$fromField} = $this->_do->{$pk};
                                     $do->{$toField1} = $rowid;
                                     $do->{$toField2} = $fieldvalue;
                                     $do->insert();
                                 }
                             }
                         }
                     }
                 }
             }
             //process crossLinks
             foreach ($this->crossLinks as $crossLink) {
                 $do = DB_DataObject::factory($crossLink['table']);
                 $links = $do->links();
                 $fromField = $crossLink['fromField'];
                 $toField = $crossLink['toField'];
                 if (isset($values['__crossLink_' . $crossLink['table']])) {
                     $fieldvalues = $values['__crossLink_' . $crossLink['table']];
                 } else {
                     $fieldvalues = array();
                 }
                 if (isset($values['__crossLink_' . $crossLink['table'] . '__extraFields'])) {
                     $extraFieldValues = $values['__crossLink_' . $crossLink['table'] . '__extraFields'];
                 } else {
                     $extraFieldValues = array();
                 }
                 $do->{$fromField} = $this->_do->{$pk};
                 $do->selectAdd();
                 $do->selectAdd($toField);
                 $do->selectAdd($fromField);
                 if ($doKeys = $do->sequenceKey()) {
                     $do->selectAdd($doKeys[0]);
                 }
                 $do->find();
                 $oldFieldValues = array();
                 while ($do->fetch()) {
                     if (isset($fieldvalues[$do->{$toField}])) {
                         $oldFieldValues[$do->{$toField}] = clone $do;
                     } else {
                         $do->delete();
                     }
                 }
                 if (count($fieldvalues) > 0) {
                     foreach ($fieldvalues as $fieldvalue) {
                         if (isset($oldFieldValues[$fieldvalue])) {
                             if (isset($do->fb_crossLinkExtraFields)) {
                                 $do = $oldFieldValues[$fieldvalue];
                                 $update = false;
                                 foreach ($do->fb_crossLinkExtraFields as $extraField) {
                                     if ($do->{$extraField} !== $extraFieldValues[$fieldvalue][$extraField]) {
                                         $update = true;
                                         $do->{$extraField} = $extraFieldValues[$fieldvalue][$extraField];
                                     }
                                 }
                                 if ($update) {
                                     $do->update();
                                 }
                             }
                         } else {
                             $do = DB_DataObject::factory($crossLink['table']);
                             $do->{$fromField} = $this->_do->{$pk};
                             $do->{$toField} = $fieldvalue;
                             if (isset($do->fb_crossLinkExtraFields)) {
                                 foreach ($do->fb_crossLinkExtraFields as $extraField) {
                                     $do->{$extraField} = $extraFieldValues[$do->{$toField}][$extraField];
                                 }
                             }
                             $do->insert();
                         }
                     }
                 }
             }
             foreach ($this->reverseLinks as $reverseLink) {
                 $elName = '__reverseLink_' . $reverseLink['table'] . '_' . $reverseLink['field'];
                 $do = DB_DataObject::factory($reverseLink['table']);
                 if (method_exists($this->_do, 'preparelinkeddataobject')) {
                     if ($this->useCallTimePassByReference) {
                         $this->_do->prepareLinkedDataObject(&$do, $key);
                     } else {
                         $this->_do->prepareLinkedDataObject($do, $key);
                     }
                 }
                 $rLinks = $do->links();
                 $rPk = $this->_getPrimaryKey($do);
                 $rFields = $do->table();
                 list($lTable, $lField) = explode(':', $rLinks[$reverseLink['field']]);
                 if ($do->find()) {
                     while ($do->fetch()) {
                         unset($newVal);
                         if (isset($values[$elName][$do->{$rPk}])) {
                             if ($do->{$reverseLink['field']} != $this->_do->{$lField}) {
                                 $do->{$reverseLink['field']} = $this->_do->{$lField};
                                 $do->update();
                             }
                         } elseif ($do->{$reverseLink['field']} == $this->_do->{$lField}) {
                             if (isset($reverseLink['defaultLinkValue'])) {
                                 $do->{$reverseLink['field']} = $reverseLink['defaultLinkValue'];
                                 $do->update();
                             } else {
                                 if ($rFields[$reverseLink['field']] & DB_DATAOBJECT_NOTNULL) {
                                     //ERROR!!
                                     $this->debug('Checkbox in reverseLinks unset when link field may not be null');
                                 } else {
                                     require_once 'DB/DataObject/Cast.php';
                                     $do->{$reverseLink['field']} = DB_DataObject_Cast::sql('NULL');
                                     $do->update();
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (method_exists($this->_do, 'postprocessform')) {
         if ($this->useCallTimePassByReference) {
             $this->_do->postProcessForm(&$values);
         } else {
             $this->_do->postProcessForm($values);
         }
     }
     return $dbOperations;
 }