diff --git a/lib/Doctrine/ODM/PHPCR/DocumentManager.php b/lib/Doctrine/ODM/PHPCR/DocumentManager.php index ea6db503a..5f316016f 100644 --- a/lib/Doctrine/ODM/PHPCR/DocumentManager.php +++ b/lib/Doctrine/ODM/PHPCR/DocumentManager.php @@ -167,9 +167,9 @@ public function getRepository($documentName) return $this->repositories[$documentName]; } - public function persist($object, $path) + public function persist($object) { - $this->unitOfWork->scheduleInsert($object, $path); + $this->unitOfWork->scheduleInsert($object); } public function remove($object) diff --git a/lib/Doctrine/ODM/PHPCR/Id/AssignedPathGenerator.php b/lib/Doctrine/ODM/PHPCR/Id/AssignedPathGenerator.php new file mode 100644 index 000000000..fa7156dd3 --- /dev/null +++ b/lib/Doctrine/ODM/PHPCR/Id/AssignedPathGenerator.php @@ -0,0 +1,24 @@ +getFieldValue($document, $cm->path); + if (!$id) { + throw new \Exception("no id"); + } + return $id; + } +} diff --git a/lib/Doctrine/ODM/PHPCR/Id/IdGenerator.php b/lib/Doctrine/ODM/PHPCR/Id/IdGenerator.php new file mode 100644 index 000000000..6438fe787 --- /dev/null +++ b/lib/Doctrine/ODM/PHPCR/Id/IdGenerator.php @@ -0,0 +1,44 @@ + + * @author Lukas Kahwe Smith + */ +abstract class IdGenerator +{ + /** + * @param int $generatorType + * @return IdGenerator + */ + static public function create($generatorType) + { + switch ($generatorType) { + case ClassMetadata::IDGENERATOR_ASSIGNED: + $instance = new AssignedPathGenerator(); + break; + case ClassMetadata::IDGENERATOR_REPOSITORY: + $instance = new RepositoryPathGenerator(); + break; + default: + throw \Exception("ID Generator does not exist!"); + } + return $instance; + } + + /** + * @param object $document + * @param ClassMetadata $cm + * @param DocumentManager $dm + */ + abstract public function generate($document, ClassMetadata $cm, DocumentManager $dm); +} diff --git a/lib/Doctrine/ODM/PHPCR/Id/RepositoryPathGenerator.php b/lib/Doctrine/ODM/PHPCR/Id/RepositoryPathGenerator.php new file mode 100644 index 000000000..990505527 --- /dev/null +++ b/lib/Doctrine/ODM/PHPCR/Id/RepositoryPathGenerator.php @@ -0,0 +1,30 @@ +getRepository($cm->class); + if (!($repository instanceof RepositoryPathInterface)) { + throw new \Exception("no id"); + } + + // TODO: should we have some default implementation (parent path + some md5/object id)? + $id = $repository->generatePath($document); + if (!$id) { + throw new \Exception("no id"); + } + return $id; + } +} diff --git a/lib/Doctrine/ODM/PHPCR/Id/RepositoryPathInterface.php b/lib/Doctrine/ODM/PHPCR/Id/RepositoryPathInterface.php new file mode 100644 index 000000000..27801d943 --- /dev/null +++ b/lib/Doctrine/ODM/PHPCR/Id/RepositoryPathInterface.php @@ -0,0 +1,12 @@ +doScheduleInsert($document, $path, $visited); + $this->doScheduleInsert($document, $visited); } - private function doScheduleInsert($document, $path, &$visited) + private function doScheduleInsert($document, &$visited) { $oid = spl_object_hash($document); if (isset($visited[$oid])) { @@ -302,11 +302,7 @@ private function doScheduleInsert($document, $path, &$visited) switch ($state) { case self::STATE_NEW: - $this->registerManaged($document, $path, null); - - if ($this->evm->hasListeners(Event::prePersist)) { - $this->evm->dispatchEvent(Event::prePersist, new Events\LifecycleEventArgs($document, $this->dm)); - } + $this->persistNew($class, $document); break; case self::STATE_MANAGED: // TODO: Change Tracking Deferred Explicit @@ -351,6 +347,14 @@ private function cascadeScheduleInsert($class, $document, &$visited) } } + private function getIdGenerator($type) + { + if (!isset($this->idGenerators[$type])) { + $this->idGenerators[$type] = Id\IdGenerator::create($type); + } + return $this->idGenerators[$type]; + } + public function scheduleRemove($document) { $oid = spl_object_hash($document); @@ -470,6 +474,27 @@ public function getDocumentChangeSet($document) return array(); } + /** + * Persist new document, marking it managed and generating the id. + * + * This method is either called through `DocumentManager#persist()` or during `DocumentManager#flush()`, + * when persistence by reachability is applied. + * + * @param ClassMetadata $class + * @param object $document + * @return void + */ + public function persistNew($class, $document) + { + $path = $this->getIdGenerator($class->idGenerator)->generate($document, $class, $this->dm); + + $this->registerManaged($document, $path, null); + + if ($this->evm->hasListeners(Event::prePersist)) { + $this->evm->dispatchEvent(Event::prePersist, new Events\LifecycleEventArgs($document, $this->dm)); + } + } + /** * Flush Operation - Write all dirty entries to the PHPCR. *