/** * set all relations of a given record * * NOTE: given relation data is expected to be an array atm. * @todo check read ACL for new relations to existing records. * * @param string $_model own model to get relations for * @param string $_backend own backend to get relations for * @param string $_id own id to get relations for * @param array $_relationData data for relations to create * @param bool $_ignoreACL create relations without checking permissions * @param bool $_inspectRelated do update/create related records on the fly * @return void */ public function setRelations($_model, $_backend, $_id, $_relationData, $_ignoreACL = FALSE, $_inspectRelated = FALSE) { $relations = new Tinebase_Record_RecordSet('Tinebase_Model_Relation'); foreach ((array) $_relationData as $relationData) { if ($relationData instanceof Tinebase_Model_Relation) { $relations->addRecord($relationData); } else { $relation = new Tinebase_Model_Relation(NULL, TRUE); $relation->setFromJsonInUsersTimezone($relationData); $relations->addRecord($relation); } } // own id sanitising $relations->own_model = $_model; $relations->own_backend = $_backend; $relations->own_id = $_id; // convert related_record to record objects // @todo move this to a relation json class / or to model->setFromJson $this->_relatedRecordToObject($relations); // compute relations to add/delete $currentRelations = $this->getRelations($_model, $_backend, $_id, NULL, array(), $_ignoreACL); $currentIds = $currentRelations->getArrayOfIds(); $relationsIds = $relations->getArrayOfIds(); $toAdd = $relations->getIdLessIndexes(); $toDel = array_diff($currentIds, $relationsIds); $toUpdate = array_intersect($currentIds, $relationsIds); $this->_validateConstraintsConfig($_model, $relations, $toDel, $toUpdate); // break relations foreach ($toDel as $relationId) { $this->_backend->breakRelation($relationId); } // add new relations foreach ($toAdd as $idx) { if (empty($relations[$idx]->related_id)) { $this->_setAppRecord($relations[$idx]); } $this->_addRelation($relations[$idx]); } // update relations foreach ($toUpdate as $relationId) { $current = $currentRelations[$currentRelations->getIndexById($relationId)]; $update = $relations[$relations->getIndexById($relationId)]; // update related records if explicitly needed if ($_inspectRelated) { // @todo do we need to omit so many fields? if (!$current->related_record->isEqual($update->related_record, array('jpegphoto', 'creation_time', 'last_modified_time', 'created_by', 'last_modified_by', 'is_deleted', 'deleted_by', 'deleted_time', 'tags', 'notes'))) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Related record diff: ' . print_r($current->related_record->diff($update->related_record)->toArray(), true)); } $this->_setAppRecord($update); } } if (!$current->isEqual($update, array('related_record'))) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Relation diff: ' . print_r($current->diff($update)->toArray(), true)); } $this->_updateRelation($update); } } }
/** * testBreakRelationExcludeSet */ public function testBreakRelationExcludeSet() { $rel = $this->relations[0]; $this->object->breakRelation($rel->getId()); $relations = $this->object->getAllRelations($rel->own_model, $rel->own_backend, $rel->own_id); // test that the other relations still exists $this->assertGreaterThan(0, count($relations)); foreach ($relations as $relation) { $this->assertFalse($relation->getId() == $this->relations[0]->getId()); } }