/** * Saves relationship data to a link table containing the id's of both objects. * * This method inserts / updates the foreign objects. * Missing foreign objects will be removed from the link table, but not deleted. * * @param DataObjectInterface[] $objects * @param string $className Class name of foreign objects to load * @param string $linkTable Table that links two objects together * @param string $foreignObjectGetter Name of getter to retrieve foreign objects * @param string $idColumn Column on link table = the id on this object * @param string $foreignIdColumn Column on link table = the id on the foreign object table */ public function saveManyToMany(array $objects, $className, $linkTable, $foreignObjectGetter = null, $idColumn = null, $foreignIdColumn = null) { if (empty($objects)) { return; } if (!$foreignObjectGetter) { $foreignObjectGetter = 'get' . $this->inflector->methodNameFromClass($className, true); } $foreignObjectsToSave = []; foreach ($objects as $object) { if (!method_exists($object, $foreignObjectGetter)) { throw new MethodNotImplementedException("{$foreignObjectGetter} must be defined on {$object->getClassName()} to save relationship"); } /** @var DataObjectInterface[] $foreignObjects */ $foreignObjects = $object->{$foreignObjectGetter}(); if (!empty($foreignObjects)) { if (!is_array($foreignObjects)) { throw new MethodNotImplementedException("{$foreignObjectGetter} on {$object->getClassName()} must return an array to save relationship"); } foreach ($foreignObjects as $foreignObject) { $foreignObjectsToSave[] = $foreignObject; } } } $this->objectMapper->unitOfWork()->executeTransaction(function () use($foreignObjectsToSave, $objects, $className, $linkTable, $foreignObjectGetter, $idColumn, $foreignIdColumn) { $this->objectMapper->saveAll($foreignObjectsToSave); $this->saveManyToManyLinks($objects, $className, $linkTable, $foreignObjectGetter, $idColumn, $foreignIdColumn); }); }
/** * Executes all operations * * @param callable $exceptionHandler */ public function flush(callable $exceptionHandler = null) { $this->executeTransaction(function () { foreach ($this->objectsToSave as $objects) { if (count($objects) == 1) { $this->orm->save($objects[0]); } else { $this->orm->saveAll($objects); } } foreach ($this->objectsToDelete as $objects) { if (count($objects) == 1) { $this->orm->delete($objects[0]); } else { $this->orm->deleteAll($objects); } } }, $exceptionHandler); $this->objectsToSave = []; $this->objectsToDelete = []; }
public function testSaveManyToMany() { $otherObjects = []; $otherObject = new OtherDataObject(); $otherObject->setName('Other object many-to-many 1-1'); $otherObject2 = new OtherDataObject(); $otherObject2->setName('Other object many-to-many 1-2'); $otherObject3 = new OtherDataObject(); $otherObject3->setName('Other object many-to-many 2-1'); $otherObject4 = new OtherDataObject(); $otherObject4->setName('Other object many-to-many 2-2'); $otherObjectToDelete = new OtherDataObject(); $otherObjects[] = $otherObjectToDelete->setName('Other object many-to-many 1-3'); $otherObjectToDelete2 = new OtherDataObject(); $otherObjects[] = $otherObjectToDelete2->setName('Other object many-to-many 2-3'); $objects = []; $object = new ExtendedDataObject(); $object2 = new ExtendedDataObject(); $objects[] = $object->setMyColumn('Save many-to-many 1')->setOtherDataObjects([$otherObject, $otherObject2]); $objects[] = $object2->setMyColumn('Save many-to-many 2')->setOtherDataObjects([$otherObject3, $otherObject4]); $this->repository->saveAll($objects); $this->objectMapper->saveAll($otherObjects); $queryHelper = $this->objectMapper->getQueryHelper(); $queryHelper->massInsert('extended_other_rel', [['extendedDataObjectId' => $object->getId(), 'otherDataObjectId' => $otherObjectToDelete->getId()], ['extendedDataObjectId' => $object2->getId(), 'otherDataObjectId' => $otherObjectToDelete2->getId()]]); $relationshipSaver = $this->objectMapper->getRelationshipSaver(); $relationshipSaver->saveManyToMany($objects, OtherDataObject::class, 'extended_other_rel'); $this->assertGreaterThan(0, $otherObject->getId()); $this->assertGreaterThan(0, $otherObject2->getId()); $this->assertGreaterThan(0, $otherObject3->getId()); $this->assertGreaterThan(0, $otherObject4->getId()); $objectLinks = $queryHelper->buildSelectQuery('extended_other_rel', self::$connection->quoteIdentifier('otherDataObjectId'), ['extendedDataObjectId' => $object->getId()])->execute()->fetchAll(\PDO::FETCH_COLUMN); $this->assertCount(2, $objectLinks); $this->assertEquals($otherObject->getId(), $objectLinks[0]); $this->assertEquals($otherObject2->getId(), $objectLinks[1]); $object2Links = $queryHelper->buildSelectQuery('extended_other_rel', self::$connection->quoteIdentifier('otherDataObjectId'), ['extendedDataObjectId' => $object2->getId()])->execute()->fetchAll(\PDO::FETCH_COLUMN); $this->assertCount(2, $object2Links); $this->assertEquals($otherObject3->getId(), $object2Links[0]); $this->assertEquals($otherObject4->getId(), $object2Links[1]); }