public function testAcceptanceSynchronization_toCollectionAsObjectsWithId() { $o = function ($id, $label) { return (object) compact('id', 'label'); }; $article = $this->findArticle(); $toCollection = $this->getToCollection($o); $repository = $this->em->getRepository('Psc\\Doctrine\\TestEntities\\Tag'); $synchronizer = new \Psc\Doctrine\ActionsCollectionSynchronizer(); $synchronizer->onHydrate(function ($toObject) use($repository) { $qb = $repository->createQueryBuilder('tag'); $qb->where($qb->expr()->orX($qb->expr()->eq('tag.label', ':label'), $qb->expr()->eq('tag.id', ':id'))); $qb->setParameter('id', $toObject->id)->setParameter('label', $toObject->label); $result = $repository->deliverQuery($qb, NULL, 'singleOrNull'); //\Psc\Doctrine\Helper::dump($result); return $result; }); $synchronizer->onHash(function (Entity $tag) { return $tag->getIdentifier(); }); $synchronizer->onInsert(function ($o) use($repository, $article) { //print "insert ".$o->label."\n"; $tag = new Tag($o->label); $article->addTag($tag); $repository->persist($tag); }); $synchronizer->onDelete(function (Entity $tag) use($repository, $article) { //print "remove ".$tag->getLabel()."\n"; $article->removeTag($tag); // wenn tag 0 verknüpfungen hat, könnte man es hier auch löschen }); $synchronizer->onUpdate(function (Entity $tag, $o) use($repository, $article) { //print "update ".$tag->getLabel()."\n"; $tag->setLabel($o->label); $article->addTag($tag); $repository->persist($tag); }); $synchronizer->process($article->getTags(), $toCollection); $this->em->flush(); $this->assertSyncResult(); }
/** * @param array $flat der Output der Funktion Psc.UI.Navigation::serialize() als decodierter JSON-Array * @return Psc\System\Logger */ public function persistFromUI(array $flat) { $logger = new \Psc\System\BufferLogger(); $em = $this->dc->getEntityManager(); try { $em->getConnection()->beginTransaction(); $repository = $this->repository; $pageRepository = $em->getRepository($this->container->getRoleFQN('Page')); $controller = $this; $bridge = new DoctrineBridge($em); $this->initDoctrineBridge($bridge); $bridge->beginTransaction(); $jsonNodes = array(); $synchronizer = new \Psc\Doctrine\ActionsCollectionSynchronizer(); $hydrator = new \Psc\Doctrine\UniqueEntityHydrator($repository); $synchronizer->onHydrate(function ($jsonNode) use($hydrator) { return $hydrator->getEntity((array) $jsonNode); // hydriert nach id }); $persistNode = function (Entity $node, $jsonNode) use($bridge, $pageRepository, $repository, &$jsonNodes, $logger, $controller) { $node->setContext($repository->getContext()); $node->setParent(isset($jsonNode->parent) ? $jsonNodes[$jsonNode->parent->guid] : NULL); // ist immer schon definiert $node->setI18nTitle((array) $jsonNode->title); $node->setImage(isset($jsonNode->image) ? $jsonNode->image : NULL); $logger->writeln(sprintf("persist %snode: '%s'", $node->isNew() ? 'new ' : ':' . $node->getIdentifier() . ' ', $node->getTitle($repository->displayLocale))); if (isset($jsonNode->pageId) && $jsonNode->pageId > 0) { $page = $pageRepository->hydrate($jsonNode->pageId); $node->setPage($page); $logger->writeln(' page: ' . $node->getPage()->getSlug()); } else { $defaultSlug = current($node->getI18nSlug()); // not matter what current language is, this is the default language $page = $controller->createNewPage($defaultSlug); $node->setPage($page); $pageRepository->persist($page); } // flat ist von oben nach unten sortiert: // wenn wir also oben anfangen müssen wir die weiteren immmer nach unten anhängen if ($node->getParent() != NULL) { $logger->writeln(' parent: ' . $node->getParent()->getTitle($repository->displayLocale)); } $bridge->persist($node); // index nach guid damit wir sowohl neue als auch bestehende haben $jsonNodes[$jsonNode->guid] = $node; }; $synchronizer->onInsert(function ($jsonNode) use($controller, $persistNode) { $persistNode($node = $controller->createNewNode($jsonNode), $jsonNode); }); $synchronizer->onUpdate(function ($node, $jsonNode) use($repository, $persistNode, $logger) { $persistNode($node, $jsonNode); }); $synchronizer->onDelete(function ($node) use($em, $logger, $repository) { $logger->writeln(sprintf("remove node: '%s'", $node->getTitle($repository->displayLocale))); $em->remove($node); }); $synchronizer->onHash(function (Entity $node) { return $node->getIdentifier(); }); $synchronizer->process($this->repository->findAllNodes($this->context), $flat); $bridge->commit(); $em->flush(); $em->getConnection()->commit(); } catch (\Exception $e) { $em->getConnection()->rollback(); throw $e; } return $logger; }