Skip to content

Instantly share code, notes, and snippets.

@ElectricMaxxx
Created May 20, 2014 10:33
Show Gist options
  • Save ElectricMaxxx/68a7d033a6357e757329 to your computer and use it in GitHub Desktop.
Save ElectricMaxxx/68a7d033a6357e757329 to your computer and use it in GitHub Desktop.
Purpose of the the doctrine bride/use cases

#Purpose of the DoctrineOrmOdmAdapter

tasks:

  • persist referenced object out of the box, when an object is persisted
  • update referenced object out of the box, when object is updated and referenced object has changed
  • remove referenced object out of the box, when object is removed
  • load just a reference/proxy of the referenced object, when the object is loaded

As you can see i just speak about an object and an referenced object. I do want to keep all various doctrine implementation stuff out of it. When referencing an phpcr-odm document on an an orm entity, then the object would be the entity and the referenced object the document:

$productEntity = new ProductEntity();
$productDocument = new ProductDocument();
$productDocument->setTitle('My new and awesome product');
$productDocument->setBody('....');
// add some phpcr specific stuff
...
$productEntity->setDocument($productDocument);
$productEntity->addGroup(...);
$productEntity->addPriceLists(...);

$entityManager->persist($productEntity);

That's all! I do not want to write more then this combined with a mapping like that:

/**
 * @ORM\Entity
 * @ORM\Table(name="object")
 * @ODMAdapter\ObjectAdapter
 */
class ProductEntity
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    public $uuid;

    /**
     * @var object
     * @ODMAdapter\ReferencePhpcr(
     *  referencedBy="uuid",
     *  inversedBy="uuid",
     *  targetObject="ProductDocument",
     *  name="document",
     *  commonField={
     *      @ODMAdapter\CommonField(referencedBy="title", inversedBy="title")
     *  }
     * )
     */
    public $document;

    /**
     * @ORM\Column(type="string")
     */
    public $title;
}

So that works fine (xml is done, yml planed). I got an bundle (https://github.com/ElectricMaxxx/DoctrineOrmPhpcrAdapterBundle) that would handle that use-case. It just injects the Entity-/DocumentRegistry by a configuration into a so called ObjectAdapterManager (in https://github.com/ElectricMaxxx/DoctrineOrmOdmAdapter) similar to the common ObjectManager configuration. The bundle serves a listener for ORM/PHPCR-ODM lifecycle events, which just calls the ObjectAdapterManager to trigger the persistence operations. Those hard work is done by an own UnitOfWork, which is able to fire own events.

That is just a short example how it works. And it does working. All operations are triggered. I do just have got an issue with the inconsistent use of id/uuid in phpcr-odm's UoW. But one step back:

As i do not wanna really load a referenced object onLoad of the object (incredible performance issues), i decided (with the help of @Ocramius) to use the getReference() method on the manager that is responsible for the referenced object. That method needs the className and id as a parameter. And so the trouble beginns.... If i reference an orm entity i will reference on it's id, which is the mapped identifier too. If i reference a phpcr-odm document i will definitely reference the document's uuid. But when injecting that into $dm->getReference('className', $uuid); i got an exception cause: When retrieving the document by doing an $entity->getDocument()->getTitle() the ODM's UoW calls $node = $this->session->getNode($this->determineDocumentId($document));. As i injected the uuid as id into the proxy the UoW tries to the document's node by that, which is impossible cause the session wanna have the path-identifier.

The decisions would be here:

  • chance to let the UoW use $this->session->getNodeByIdentifier($uuid); in case of an uuid (as the $dm->find() does) or is that inconsistency hidden somewhere else in the UoW
  • crate an own proxy for referenced and lazy-loading object, which calls the responsible manager's find() method. That would cause redundant data
@ElectricMaxxx
Copy link
Author

Btw i know that the document's uuid and the id arn't the same. So the word inconsistency is maybe wrong. But i think as the DocumentManager allows to fetch a document by its uuid all methods should allow that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment