/**
  * Save a form object into entry tables.
  * If this functio is over-written, it should include the fuzzy method call
  * foreach ($form as $field) {
  *      $field->save(true/false, $user)
  * }
  * @param I2CE_Form $form
  * @param I2CE_User $user
  * @param boolean $transact
  */
 public function save($form, $user, $transact)
 {
     if (!$this->isWritable()) {
         return true;
     }
     if (!$form instanceof I2CE_Form || !($form_name = $form->getName()) || !$this->init_data($form_name)) {
         return false;
     }
     $form_xml = $form->getXMLRepresentation()->ownerDocument;
     $form_id = $form->getID();
     if ($form_id != '0') {
         $endpoint = 'update';
     } else {
         $endpoint = 'create';
     }
     I2CE::raiseError("Saving ({$endpoint}) on " . $form_xml->saveXML());
     if (!array_key_exists($endpoint, $this->services[$form_name]) || !is_array($this->services[$form_name][$endpoint])) {
         I2CE::raiseError("No service set specified for {$endpoint} of {$form_name}");
         return false;
     }
     if ($form_id == '0' && (!array_key_exists('results', $this->services[$form_name]['create']) || !is_string($results = $this->services[$form_name]['create']['results']) || !$results)) {
         I2CE::raiseError("No result set specified for create {$form_name}");
         return false;
     }
     if (($out_message = $this->process_transform($form_name, $endpoint, 'out', $form_xml, true)) === false) {
         I2CE::raiseError("Could not transform out going message");
         return false;
     }
     $in_message = $this->call_service($form_name, $endpoint, $out_message);
     if (($trans_message = $this->process_transform($form_name, $endpoint, 'in', $in_message, false)) === false) {
         I2CE::raiseError("Could not transform incoming message");
         return false;
     }
     if ($form_id == '0') {
         $xpath = new DOMXpath($trans_message);
         foreach ($this->namespaces[$form_name] as $ns => $uri) {
             $xpath->registerNamespace($ns, $uri);
         }
         $xpath = new DOMXpath($trans_message);
         if (!($val_nodes = $xpath->query($results)) instanceof DOMNodeList || !($val_nodes->length == 1)) {
             I2CE::raiseError("Invalid results query");
             return false;
         }
         $val_node = $val_nodes->item(0);
         if ($val_node instanceof DOMAttr) {
             $form_id = $val_node->value;
         } else {
             if ($val_node instanceof DOMNode) {
                 $form_id = $val_node->textContent;
             }
         }
         $form->setId($form_id);
     }
     $this->clear_service_cache($form_name);
     return true;
 }