/** * Overrides {@link epManagerBase::commit()} to deal with object relationships. * @param object $o * @return bool $force (ignored - treated as false!) * @access public */ public function commit(&$o, $force = false) { // check if the object should be commited if (!$force && !$o->epNeedsCommit()) { return true; } // get class name if (!($class = $this->_getClass($o))) { return false; } // get class map for class if (!($cm =& $this->_getMap($class))) { return false; } // check if class has any non-primitive fields if (!($npfs = $cm->getNonPrimitive())) { // shouldn't happen return parent::commit($o, $force); } // set object is being commited $o->epSetCommitting(true); // array to keep track of 1-to-many relations $relations = array(); // go through each non-primitive field $status = true; foreach ($npfs as $name => $fm) { // initialize arrays to hold relation oids $relations[$name] = array(); $relations[$name][$fm->getClass()] = array(); // var field value if (!($v =& $o->epGet($name))) { continue; } // check if value is array if (is_array($v) || $v instanceof epArray) { // check if it is a "many" field if (!$fm->isMany()) { throw new epExceptionManager('Value (array) of variable [' . $cm->getName() . "::" . $fm->getName() . '] and its field map mismatch'); continue; } // go through each value in $v $oids = array(); foreach ($v as &$w) { if (is_string($w)) { $oids[] = $w; } else { if (is_object($w) && $w instanceof epObject) { // ignore deleted object if ($w->epIsDeleted()) { continue; } // commit the value (object) if ($w->epIsCommitting()) { // if the object is in the to-be-commited array, // let's do a simple commit first to get the oid. // but we need to set it dirty, so its relation // vars can be stored $status &= parent::_commit_o($w); $w->epSetDirty(true); } else { // for not in to-be-committed queue $status &= $this->commit($w); } // collect oid $oids[] = $this->encodeClassOid($w); } } } // put oids into the relation array $relations[$name][$fm->getClass()] = $oids; } else { $oid = false; if (is_string($v)) { $oid = $v; } else { if (is_object($v) && $v instanceof epObject) { // check if it is a "One" field map if (!$fm->isSingle()) { throw new epExceptionManager('Variable value (array) and field map (One) mismatch'); continue; } // ignore deleted object if ($v->epIsDeleted()) { continue; } // commit the value (object) if ($v->epIsCommitting()) { // if the object is to be commited, // let's do a simple commit first to get the oid $status &= parent::_commit_o($v); $v->epSetDirty(true); } else { // object not in to-be-committed queue. force commit $status &= $this->commit($v); } $oid = $this->encodeClassOid($v); } } // put oid into the relation array if ($oid !== false) { $relations[$name][$fm->getClass()] = array($oid); } } } // reset flag object being commited for parent::commit() to work $o->epSetCommitting(false); // call the usual commit $status &= parent::commit($o, $force); // update object relation for has_many or composed_of_many fields foreach ($relations as $var_a => $relation) { $base_a = $cm->getField($var_a)->getClassMap()->getName(); foreach ($relation as $base_b => $b_oids) { $status &= $this->_updateRelations($base_a, $class, $o->epGetObjectId(), $var_a, $base_b, $b_oids); } } return $status; }