Selaa lähdekoodia

[mapping] event argument adapter for single listener support

gediminasm 14 vuotta sitten
vanhempi
commit
502003f57d

+ 183 - 0
lib/Gedmo/Mapping/Event/Adapter/ODM.php

@@ -0,0 +1,183 @@
+<?php
+
+namespace Gedmo\Mapping\Event\Adapter;
+
+use Gedmo\Mapping\Event\AdapterInterface;
+use Doctrine\Common\EventArgs;
+use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
+use Doctrine\ODM\MongoDB\UnitOfWork;
+use Doctrine\ODM\MongoDB\DocumentManager;
+use Doctrine\ODM\MongoDB\Proxy\Proxy;
+
+/**
+ * Doctrine event adapter for ODM specific
+ * event arguments
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ * @package Gedmo.Mapping.Event.Adapter
+ * @subpackage ODM
+ * @link http://www.gediminasm.org
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class ODM implements AdapterInterface
+{
+    /**
+     * @var EventArgs
+     */
+    private $args;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setEventArgs(EventArgs $args)
+    {
+        $this->args = $args;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDomainObjectName()
+    {
+        return 'Document';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getManagerName()
+    {
+        return 'ODM';
+    }
+
+    /**
+     * Extracts identifiers from object or proxy
+     *
+     * @param DocumentManager $dm
+     * @param object $object
+     * @param bool $single
+     * @return mixed - array or single identifier
+     */
+    public function extractIdentifier(DocumentManager $dm, $object, $single = true)
+    {
+        if ($object instanceof Proxy) {
+            $id = $dm->getUnitOfWork()->getDocumentIdentifier($object);
+        } else {
+            $meta = $dm->getClassMetadata(get_class($object));
+            $id = $meta->getReflectionProperty($meta->identifier)->getValue($object);
+        }
+        if ($single) {
+            return $id;
+        } else {
+            return array($meta->identifier => $id);
+        }
+    }
+
+    /**
+     * Call event specific method
+     *
+     * @param string $method
+     * @param array $args
+     * @return mixed
+     */
+    public function __call($method, $args)
+    {
+        $method = str_replace('Object', $this->getDomainObjectName(), $method);
+        return call_user_func_array(array($this->args, $method), $args);
+    }
+
+    /**
+     * Get the object changeset from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @param Object $object
+     * @return array
+     */
+    public function getObjectChangeSet(UnitOfWork $uow, $object)
+    {
+        return $uow->getDocumentChangeSet($object);
+    }
+
+    /**
+     * Get the single identifier field name
+     *
+     * @param ClassMetadataInfo $meta
+     * @throws MappingException - if identifier is composite
+     * @return string
+     */
+    public function getSingleIdentifierFieldName(ClassMetadataInfo $meta)
+    {
+        return $meta->identifier;
+    }
+
+    /**
+     * Recompute the single object changeset from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @param ClassMetadataInfo $meta
+     * @param Object $object
+     * @return void
+     */
+    public function recomputeSingleObjectChangeSet(UnitOfWork $uow, ClassMetadataInfo $meta, $object)
+    {
+        $uow->recomputeSingleDocumentChangeSet($meta, $object);
+    }
+
+    /**
+     * Get the scheduled object updates from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @return array
+     */
+    public function getScheduledObjectUpdates(UnitOfWork $uow)
+    {
+        return $uow->getScheduledDocumentUpdates();
+    }
+
+    /**
+     * Get the scheduled object insertions from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @return array
+     */
+    public function getScheduledObjectInsertions(UnitOfWork $uow)
+    {
+        return $uow->getScheduledDocumentInsertions();
+    }
+
+    /**
+     * Get the scheduled object deletions from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @return array
+     */
+    public function getScheduledObjectDeletions(UnitOfWork $uow)
+    {
+        return $uow->getScheduledDocumentDeletions();
+    }
+
+    /**
+     * Sets a property value of the original data array of an object
+     *
+     * @param UnitOfWork $uow
+     * @param string $oid
+     * @param string $property
+     * @param mixed $value
+     * @return void
+     */
+    public function setOriginalObjectProperty(UnitOfWork $uow, $oid, $property, $value)
+    {
+        $uow->setOriginalDocumentProperty($oid, $property, $value);
+    }
+
+    /**
+     * Clears the property changeset of the object with the given OID.
+     *
+     * @param UnitOfWork $uow
+     * @param string $oid The object's OID.
+     */
+    public function clearObjectChangeSet(UnitOfWork $uow, $oid)
+    {
+        $uow->clearDocumentChangeSet($oid);
+    }
+}

+ 185 - 0
lib/Gedmo/Mapping/Event/Adapter/ORM.php

@@ -0,0 +1,185 @@
+<?php
+
+namespace Gedmo\Mapping\Event\Adapter;
+
+use Gedmo\Mapping\Event\AdapterInterface;
+use Doctrine\Common\EventArgs;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Doctrine\ORM\UnitOfWork;
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Proxy\Proxy;
+
+/**
+ * Doctrine event adapter for ORM specific
+ * event arguments
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ * @package Gedmo.Mapping.Event.Adapter
+ * @subpackage ORM
+ * @link http://www.gediminasm.org
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class ORM implements AdapterInterface
+{
+    /**
+     * @var EventArgs
+     */
+    private $args;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setEventArgs(EventArgs $args)
+    {
+        $this->args = $args;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDomainObjectName()
+    {
+        return 'Entity';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getManagerName()
+    {
+        return 'ORM';
+    }
+
+    /**
+     * Extracts identifiers from object or proxy
+     *
+     * @param EntityManager $em
+     * @param object $object
+     * @param bool $single
+     * @return mixed - array or single identifier
+     */
+    public function extractIdentifier(EntityManager $em, $object, $single = true)
+    {
+        if ($object instanceof Proxy) {
+            $id = $em->getUnitOfWork()->getEntityIdentifier($object);
+        } else {
+            $meta = $em->getClassMetadata(get_class($object));
+            $id = array();
+            foreach ($meta->identifier as $name) {
+                $id[$name] = $meta->getReflectionProperty($name)->getValue($object);
+            }
+        }
+        if ($single) {
+            $id = current($id);
+        }
+        return $id;
+    }
+
+    /**
+     * Call event specific method
+     *
+     * @param string $method
+     * @param array $args
+     * @return mixed
+     */
+    public function __call($method, $args)
+    {
+        $method = str_replace('Object', $this->getDomainObjectName(), $method);
+        return call_user_func_array(array($this->args, $method), $args);
+    }
+
+    /**
+     * Get the object changeset from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @param Object $object
+     * @return array
+     */
+    public function getObjectChangeSet(UnitOfWork $uow, $object)
+    {
+        return $uow->getEntityChangeSet($object);
+    }
+
+    /**
+     * Get the single identifier field name
+     *
+     * @param ClassMetadataInfo $meta
+     * @throws MappingException - if identifier is composite
+     * @return string
+     */
+    public function getSingleIdentifierFieldName(ClassMetadataInfo $meta)
+    {
+        return $meta->getSingleIdentifierFieldName();
+    }
+
+    /**
+     * Recompute the single object changeset from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @param ClassMetadataInfo $meta
+     * @param Object $object
+     * @return void
+     */
+    public function recomputeSingleObjectChangeSet(UnitOfWork $uow, ClassMetadataInfo $meta, $object)
+    {
+        $uow->recomputeSingleEntityChangeSet($meta, $object);
+    }
+
+    /**
+     * Get the scheduled object updates from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @return array
+     */
+    public function getScheduledObjectUpdates(UnitOfWork $uow)
+    {
+        return $uow->getScheduledEntityUpdates();
+    }
+
+    /**
+     * Get the scheduled object insertions from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @return array
+     */
+    public function getScheduledObjectInsertions(UnitOfWork $uow)
+    {
+        return $uow->getScheduledEntityInsertions();
+    }
+
+    /**
+     * Get the scheduled object deletions from a UnitOfWork
+     *
+     * @param UnitOfWork $uow
+     * @return array
+     */
+    public function getScheduledObjectDeletions(UnitOfWork $uow)
+    {
+        return $uow->getScheduledEntityDeletions();
+    }
+
+    /**
+     * Sets a property value of the original data array of an object
+     *
+     * @param UnitOfWork $uow
+     * @param string $oid
+     * @param string $property
+     * @param mixed $value
+     * @return void
+     */
+    public function setOriginalObjectProperty(UnitOfWork $uow, $oid, $property, $value)
+    {
+        $uow->setOriginalEntityProperty($oid, $property, $value);
+    }
+
+    /**
+     * Clears the property changeset of the object with the given OID.
+     *
+     * @param UnitOfWork $uow
+     * @param string $oid The object's OID.
+     */
+    public function clearObjectChangeSet(UnitOfWork $uow, $oid)
+    {
+        $uow->clearEntityChangeSet($oid);
+    }
+}

+ 39 - 0
lib/Gedmo/Mapping/Event/AdapterInterface.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace Gedmo\Mapping\Event;
+
+use Doctrine\Common\EventArgs;
+
+/**
+ * Doctrine event adapter interface is used
+ * to retrieve common functionality for Doctrine
+ * events
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ * @package Gedmo.Mapping.Event
+ * @subpackage AdapterInterface
+ * @link http://www.gediminasm.org
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+interface AdapterInterface
+{
+    /**
+     * Set the eventargs
+     *
+     * @param EventArgs $args
+     */
+    function setEventArgs(EventArgs $args);
+
+    /**
+     * Get the name of domain object
+     *
+     * @return string
+     */
+    function getDomainObjectName();
+
+    /**
+     * Get the name of used manager for this
+     * event adapter
+     */
+    function getManagerName();
+}

+ 50 - 16
lib/Gedmo/Mapping/MappedEventSubscriber.php

@@ -12,11 +12,11 @@ use Gedmo\Mapping\ExtensionMetadataFactory,
  * This is extension of event subscriber class and is
  * used specifically for handling the extension metadata
  * mapping for extensions.
- * 
+ *
  * It dries up some reusable code which is common for
  * all extensions who mapps additional metadata through
  * extended drivers
- * 
+ *
  * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  * @package Gedmo.Mapping
  * @subpackage MappedEventSubscriber
@@ -24,26 +24,59 @@ use Gedmo\Mapping\ExtensionMetadataFactory,
  * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  */
 abstract class MappedEventSubscriber implements EventSubscriber
-{    
+{
     /**
      * List of cached object configurations
-     *  
+     *
      * @var array
      */
     protected $configurations = array();
-    
+
     /**
      * ExtensionMetadataFactory used to read the extension
      * metadata through the extension drivers
-     * 
+     *
      * @var Gedmo\Mapping\ExtensionMetadataFactory
      */
-    protected $extensionMetadataFactory = null;
-    
+    private $extensionMetadataFactory;
+
+    /**
+     * List of event adapters used for this listener
+     *
+     * @var array
+     */
+    private $adapters = array();
+
+    /**
+     * Get an event adapter to handle event specific
+     * methods
+     *
+     * @param EventArgs $args
+     * @throws \Gedmo\Exception\InvalidArgumentException - if event is not recognized
+     * @return \Gedmo\Mapping\Event\AdapterInterface
+     */
+    protected function getEventAdapter(EventArgs $args)
+    {
+        $class = get_class($args);
+        if (preg_match('@Doctrine\\\([^\\\]+)@', $class, $m) && in_array($m[1], array('ODM', 'ORM'))) {
+            if (!isset($this->adapters[$m[1]])) {
+                $adapterClass = $this->getNamespace() . '\\Mapping\\Event\\Adapter\\' . $m[1];
+                if (!class_exists($adapterClass)) {
+                    $adapterClass = 'Gedmo\\Mapping\\Event\\Adapter\\'.$m[1];
+                }
+                $this->adapters[$m[1]] = new $adapterClass;
+            }
+            $this->adapters[$m[1]]->setEventArgs($args);
+            return $this->adapters[$m[1]];
+        } else {
+            throw new \Gedmo\Exception\InvalidArgumentException('Event mapper does not support event arg class: '.$class);
+        }
+    }
+
     /**
      * Get the configuration for specific object class
      * if cache driver is present it scans it also
-     * 
+     *
      * @param ObjectManager $objectManager
      * @param string $class
      * @return array
@@ -62,10 +95,10 @@ abstract class MappedEventSubscriber implements EventSubscriber
         }
         return $config;
     }
-    
+
     /**
      * Get extended metadata mapping reader
-     * 
+     *
      * @param ObjectManager $objectManager
      * @return Gedmo\Mapping\ExtensionMetadataFactory
      */
@@ -79,11 +112,11 @@ abstract class MappedEventSubscriber implements EventSubscriber
         }
         return $this->extensionMetadataFactory;
     }
-    
+
     /**
      * Scans the objects for extended annotations
      * event subscribers must subscribe to loadClassMetadata event
-     * 
+     *
      * @param ObjectManager $objectManager
      * @param ClassMetadata $metadata
      * @return void
@@ -96,11 +129,12 @@ abstract class MappedEventSubscriber implements EventSubscriber
             $this->configurations[$metadata->name] = $config;
         }
     }
-    
+
     /**
      * Get the namespace of extension event subscriber.
-     * used for cache id of extensions
-     * 
+     * used for cache id of extensions also to know where
+     * to find Mapping drivers and event adapters
+     *
      * @return string
      */
     abstract protected function getNamespace();