/** * Returns the relation ids for the variable specified of the object * @param epObject $o the object * @param epFieldMap $fm the field map of the variable * @param epClassMap $cm the class map of the object * @return false|string|array */ public function getRelationIds(&$o, $fm, $cm) { // make sure we are dealing with valid object and non-primitive field if (!$o || !$fm || !$cm) { return false; } // object needs to have a valid id and has to be non-primitive if (!($oid_a = $o->epGetObjectId())) { return false; } // get class_a, var_a, and the related class $base_a = $fm->getBase_a(); $class_a = $cm->getName(); $var_a = $fm->getName(); $base_b = $fm->getBase_b(); if (!$base_a || !$class_a || !$var_a || !$base_b) { throw new epExceptionManager('Cannot find related class for var [' . $class_a . '::' . $var_a . ']'); return false; } // switch relations table $this->_setRelationTable($base_a, $base_b); // make an example relation objects if (!($eo =& $this->_relationExample($class_a, $oid_a, $var_a, $base_b))) { return false; } // find all relation objects using the example object // (find from db only, false: no cache, false: don't convert to objects) $rs =& parent::find($eo, EP_GET_FROM_DB, false, false); // convert result into oids $oids_b = null; if ($fm->isSingle()) { if (is_array($rs) && count($rs) > 1) { throw new epExceptionManager('Field ' . $fm->getName() . ' mapped as composed_of_/has_one but is associated with > 1 objects'); return false; } if ($rs) { $oids_b = $rs[0]; } } else { if ($fm->isMany()) { $oids_b = array(); if ($rs) { $oids_b = $rs; } } } return $oids_b; }
/** * Updates one-to-many relation between two classes * * Relations from $class_a stored that are not in array $oids_b are deleted and * new relations to $class_b objects in $oids_b are added. * * @param string $base_a name of base class a * @param string $class_a name of class a * @param integer $oid_a object id of the class a object * @param integer $var_a the relational field of object a * @param string $base_b name of base b * @param array $oids_b oids of the class b object related to the class a object * @return bool */ protected function _updateRelations($base_a, $class_a, $oid_a, $var_a, $base_b, $oids_b = array()) { // need to have a non-empty name if (!$base_a || !$class_a || !$oid_a || !$var_a || !$base_b) { throw new epExceptionManager('Incorrect parameters to update relations'); return false; } // get all relation objects for ($class_a, $a_oid, $class_b) if (!($o =& $this->_relationExample($class_a, $oid_a, $var_a, $base_b))) { throw new epExceptionManager('Cannot create relation object'); return false; } // switch relations table $this->_setRelationTable($base_a, $base_b); // return status $status = true; // array to keep all stored oids_b $stored_oids_b = array(); // find by example $o (find from db only, false no cache) if ($rs = parent::find($o, EP_GET_FROM_DB, false)) { // go through each relation found foreach ($rs as $r) { // encode class_b and oid_b $oid_b = $this->_encodeClassOid($r->get_class_b(), $r->get_oid_b()); // collect stored oids $stored_oids_b[] = $oid_b; // delete oid_b not in oids_b if (!$oids_b || !in_array($oid_b, $oids_b)) { $status &= parent::delete($r); } } } // done if oids_b is empty if (!$oids_b) { return $status; } // insert new relations ($oid_b not in $stored_oids_b) foreach ($oids_b as $oid_b_) { // weed out empty oid_b_ if (!$oid_b_) { continue; } // already stored? skip if (in_array($oid_b_, $stored_oids_b)) { continue; } // decode oid_b_ if (!$this->decodeClassOid($oid_b_, $class_b, $oid_b)) { // skip if fail (bad encoded oid) continue; } // make relation if (!($r =& parent::_create('epObjectRelation', false, false, array($class_a, $oid_a, $var_a, $base_b, $class_b, $oid_b)))) { throw new epExceptionManager('Cannot create object relation object'); $status = false; continue; } // store relation $status &= parent::commit($r); } return $status; }