finish dynamic save
authorymh <ymh.work@gmail.com>
Thu, 27 Oct 2011 21:21:11 +0200
changeset 18 6f16b9fd6a17
parent 17 81962874e172
child 19 7051e55a3131
finish dynamic save
Command/GenerateDocumentClassCommand.php
Entity/DocumentRepository.php
Listener/DocumentListener.php
--- a/Command/GenerateDocumentClassCommand.php	Thu Oct 27 05:51:04 2011 +0200
+++ b/Command/GenerateDocumentClassCommand.php	Thu Oct 27 21:21:11 2011 +0200
@@ -29,7 +29,7 @@
         
         $this
             ->setName('wikitag:generate-document-class')
-            ->setDescription('Generate the document class document class')
+            ->setDescription('Generate the document class')
             ->addArgument('path', InputArgument::OPTIONAL, 'The generation path')
             ->addOption("simulate","S",InputOption::VALUE_NONE, "Simulate generation");
     }
@@ -44,7 +44,7 @@
         
         $definition = new Definition('IRI\Bundle\WikiTagBundle\Entity\Document');
         
-        $definition->setParentClass('IRI\Bundle\WikiTagBundle\Model\Document');
+        $definition->setParentClass('\IRI\Bundle\WikiTagBundle\Model\Document');
         
         $fields = $this->getContainer()->getParameter('wiki_tag.fields');
         foreach ( $fields as $name => $field_def)
--- a/Entity/DocumentRepository.php	Thu Oct 27 05:51:04 2011 +0200
+++ b/Entity/DocumentRepository.php	Thu Oct 27 21:21:11 2011 +0200
@@ -3,7 +3,9 @@
 namespace IRI\Bundle\WikiTagBundle\Entity;
 
 use Doctrine\ORM\EntityRepository;
-use IRI\Bundle\WikiTagBundle\Model\DocumentInterface;
+use IRI\Bundle\WikiTagBundle\Entity\Document;
+
+use \ReflectionClass;
 
 /**
  * DocumentRepository
@@ -13,23 +15,158 @@
  */
 class DocumentRepository extends EntityRepository
 {
+    /**
+     *
+     * TODO : Enter description here ...
+     * @var ReflectionClass
+     */
+    private $reflection_class;
+    private $reflection_doc_class;
+    private $set_methods = array();
+    private $get_methods = array();
+    
     function findOneByExternalId($external_id)
     {
-        return $this->findOneBy(array("externalId" => strval($external_id)));
+        return $this->findOneBy(array("externalId" => $external_id));
+    }
+    
+    private function reflectionSetField($object, $method_name, $value)
+    {
+        if(isset($this->set_methods[$method_name]))
+        {
+            $set_method = $this->set_methods[$method_name];
+        }
+        
+        if(!isset($set_method) || is_null($set_method))
+        {
+            if(is_null($this->reflection_doc_class))
+            {
+                $this->reflection_doc_class = new ReflectionClass(get_class($object));
+            }
+            
+            $set_method = NULL;
+            if($this->reflection_doc_class->hasMethod($method_name))
+            {
+                $set_method = $this->reflection_doc_class->getMethod($method_name);
+            }
+            if(!is_null($set_method))
+            {
+                $this->set_methods[$method_name]=$set_method;
+            }
+        }
+        
+        if(!isset($set_method) || is_null($set_method) || !$set_method->isPublic())
+        {
+            throw new \Exception("setter method unknown $method_name");
+        }
+        
+        //set value
+        $set_method->invoke($object, $value);
+        
     }
     
-    function writeDocument(DocumentInterface $document)
+    private function reflectionGetField($document, $accessor)
+    {
+        
+        if(!isset($this->get_methods[$accessor]) ||  is_null($this->get_methods[$accessor]))
+        {
+            if(is_null($this->reflection_class))
+            {
+                $this->reflection_class = new \ReflectionClass(get_class($document));
+            }
+            
+            //look at properties
+            if($this->reflection_class->hasProperty($accessor))
+            {
+                $get_object = $this->reflection_class->getProperty($accessor);
+                if(!$get_object->isPublic())
+                {
+                    $get_object = NULL;
+                }
+            }
+            
+            if((!isset($get_object) || is_null($get_object)) && $this->reflection_class->hasMethod($accessor))
+            {
+                $get_object = $this->reflection_class->getMethod($accessor);
+                if(!$get_object->isPublic())
+                {
+                    $get_object = NULL;
+                }
+            }
+            
+            if((!isset($get_object) || is_null($get_object)) && $this->reflection_class->hasMethod("get".ucfirst($accessor)))
+            {
+                $get_object = $this->reflection_class->getMethod("get".ucfirst($accessor));
+                if(!$get_object->isPublic())
+                {
+                    $get_object = NULL;
+                }
+            }
+
+            if(isset($get_object) && !is_null($get_object))
+            {
+                $this->get_methods[$accessor] = $get_object;
+            }
+        }
+
+        if(isset($this->get_methods[$accessor]))
+        {
+            $get_object = $this->get_methods[$accessor];
+            if(!is_null($get_object))
+            {
+                if(is_a($get_object,"\ReflectionMethod"))
+                {
+                    return $get_object->invoke($document);
+                }
+                elseif(is_a($get_object,"\ReflectionProperty"))
+                {
+                    return $get_object->getValue($document);
+                }
+                else
+                {
+                    //TODO : custom exception
+                    throw new \Exception("Bad reflection object type");
+                }
+            }
+        }
+        
+        //TODO: replace by custom exception
+        throw new \Exception("Unknown accessor $accessor");
+    }
+    
+    function writeDocument($document,  $document_id_column, $fields)
     {
         # get document from id
-        $baseDocument = $this->findOneByExternalId($document->getId());
+        $docid = $this->reflectionGetField($document, $document_id_column);
+        $baseDocument = $this->findOneByExternalId($docid);
     
         if(is_null($baseDocument))
         {
             $baseDocument = new Document();
-            $baseDocument->setExternalId(strval($document->getId()));
+            $baseDocument->setExternalId($docid);
         }
-        $baseDocument->setDescription($document->getDescription());
-        $baseDocument->setTitle($document->getTitle());
+        
+        foreach ($fields as $name => $field_def) {
+            if(isset($field_def['accessor']))
+            {
+                $accessor = $field_def['accessor'];
+            }
+            else
+            {
+                $accessor = NULL;
+            }
+            if(is_null($accessor))
+            {
+                $accessor = $name;
+            }
+            
+            $value = strval($this->reflectionGetField($document,$accessor));
+            
+            $method_name = "set".ucfirst($name);
+            
+            $this->reflectionSetField($baseDocument, $method_name, $value);
+            
+        }
         
         $this->getEntityManager()->persist($baseDocument);
         $this->getEntityManager()->flush();
@@ -37,9 +174,10 @@
     
     }
     
-    function removeDocument(DocumentInterface $document)
+    function removeDocument($document, $document_id_column)
     {
-        $baseDocument = $this->findOneByExternalId($document->getId());
+        $docid = $this->reflectionGetField($document, $document_id_column);
+        $baseDocument = $this->findOneByExternalId($docid);
         if(!is_null($baseDocument))
         {
             $this->getEntityManager()->remove($baseDocument);
--- a/Listener/DocumentListener.php	Thu Oct 27 05:51:04 2011 +0200
+++ b/Listener/DocumentListener.php	Thu Oct 27 21:21:11 2011 +0200
@@ -47,6 +47,11 @@
         $this->container = $container;
     }
     
+    public function getContainer()
+    {
+        return $this->container;
+    }
+    
     public function getSubscribedEvents()
     {
         return array(
@@ -78,7 +83,8 @@
         $logger = $this->container->get('logger');
         $logger->debug("HandleEvent : REMOVE");
         $entity = $args->getEntity();
-        if ($entity instanceof DocumentInterface && !($entity instanceof Document))
+        $class = $this->getContainer()->getParameter("wiki_tag.document_class");
+        if (is_a($entity, $class))
         {
             $this->container->get('doctrine')->getRepository("WikiTagBundle:Document")->removeDocument($entity);
         }
@@ -87,18 +93,15 @@
     
     private function handleEvent(LifecycleEventArgs $args)
     {
-//         if (null === $this->userManager) {
-//             $this->userManager = $this->container->get('fos_user.user_manager');
-//         }
         
         $logger = $this->container->get('logger');
-        
+        $entity = $args->getEntity();
         
-        $entity = $args->getEntity();
-        if ($entity instanceof DocumentInterface && !($entity instanceof Document))
+        $class = $this->getContainer()->getParameter("wiki_tag.document_class");
+        if (is_a($entity, $class))
         {
             $logger->debug("treating document : " . $entity->getTitle());
-            $this->container->get('doctrine')->getRepository("WikiTagBundle:Document")->writeDocument($entity);
+            $this->container->get('doctrine')->getRepository("WikiTagBundle:Document")->writeDocument($entity, $this->getContainer()->getParameter("wiki_tag.document_id_column"), $this->getContainer()->getParameter("wiki_tag.fields"));
         }
         
     }
@@ -119,17 +122,24 @@
             $logger->debug("DocumentListener: Add ExternalId Mapping");
             $document_id_column = $this->container->getParameter('wiki_tag.document_id_column');
             $logger->debug("DocumentListener: external id def : " . print_r($document_id_column, true));
-            $metadata->mapOneToOne(array(
+            $target_metadata = $args->getEntityManager()->getClassMetadata($document_class);
+            $mapping = array_replace(array(), $target_metadata->getFieldMapping($document_id_column));
+            $mapping['fieldName'] = 'externalId';
+            $mapping['columnName'] = 'external_id';
+            $mapping['id'] = false;
+            $metadata->mapField($mapping);
+/*            $metadata->mapOneToOne(array(
                 'targetEntity' => $document_class,
                 'fieldName' => 'externalId',
                 'joinColumns' => array(0=>array(
                     'name' => 'external_id',
                     'referencedColumnName' => $document_id_column
                 )),
-            ));
+            ));*/
             
             //map the fields
             $fields = $this->container->getParameter('wiki_tag.fields');
+            $def_columns = array();
             foreach ( $fields as $name => $field_def)
             {
                 if(isset($field_def['type']))
@@ -158,11 +168,8 @@
                     $mapping['length'] = $length;
                 }
                 $metadata->mapField($mapping);
-                
-                $metadata->table['indexes']["${name}_document_fulltext_idx"] = array("columns"=>array($name));
-                
+                                
             }
-            $metadata->table['indexes']["all_document_fulltext_idx"] = array("columns"=>array_keys($fields));
         }
     }
     
@@ -172,10 +179,10 @@
         $logger = $this->container->get('logger');
         $logger->debug("Generate schema table ".$args->getClassTable()->getName());
         
-        if($args->getClassMetadata()->name === "IRI\\Bundle\\WikiTagBundle\\Entity\\Document")
-        {
-            $args->getClassTable()->addOption('engine','MyISAM');
-        }
+        #if($args->getClassMetadata()->name === "IRI\\Bundle\\WikiTagBundle\\Entity\\Document")
+        #{
+        #    $args->getClassTable()->addOption('engine','MyISAM');
+        #}
     }