Command/LoadFixturesCommand.php
changeset 85 3c9f71c01d51
parent 83 e9f04298bdfa
equal deleted inserted replaced
84:2f03faa51ba1 85:3c9f71c01d51
       
     1 <?php
       
     2 /*
       
     3  * This file is part of the WikiTagBundle package.
       
     4  *
       
     5  * (c) IRI <http://www.iri.centrepompidou.fr/>
       
     6  *
       
     7  * For the full copyright and license information, please view the LICENSE
       
     8  * file that was distributed with this source code.
       
     9  */
       
    10 
       
    11 namespace IRI\Bundle\WikiTagBundle\Command;
       
    12 
       
    13 
       
    14 use IRI\Bundle\WikiTagBundle\Entity\DocumentTag;
       
    15 
       
    16 use IRI\Bundle\WikiTagBundle\Entity\Tag;
       
    17 
       
    18 use IRI\Bundle\WikiTagBundle\Entity\Category;
       
    19 
       
    20 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
       
    21 use Symfony\Component\Console\Input\InputArgument;
       
    22 use Symfony\Component\Console\Input\InputInterface;
       
    23 use Symfony\Component\Console\Input\InputOption;
       
    24 use Symfony\Component\Console\Output\OutputInterface;
       
    25 use Mandango\Mondator\Definition\Definition;
       
    26 use Mandango\Mondator\Definition\Property;
       
    27 use Mandango\Mondator\Definition\Method;
       
    28 use Mandango\Mondator\Dumper;
       
    29 
       
    30 /**
       
    31  *
       
    32  * This class implements a command to load categories, tags, and document_tags fixtures from a yaml file.
       
    33  *
       
    34  * @author ymh
       
    35  * @author tc
       
    36  *
       
    37  */
       
    38 class LoadFixturesCommand extends ProgressContainerAwareCommand
       
    39 {
       
    40     protected function configure()
       
    41     {
       
    42         parent::configure();
       
    43         
       
    44         $this
       
    45             ->setName('wikitag:load-fixtures')
       
    46             ->setDescription('Load categories, tags, document_tags in JSON format. We suppose SyncDocuments command was executed.')
       
    47             ->addArgument('path', InputArgument::REQUIRED, 'path to the yaml file.')
       
    48             ->addOption("simulate","S",InputOption::VALUE_NONE, "Load and parse file, create objects but does not save them")
       
    49             ->addOption("categories","C",InputOption::VALUE_NONE, "Will save the categories and not the tags/doctags if options are not set (useful to avoid memory problems)")
       
    50             ->addOption("tags","T",InputOption::VALUE_NONE, "Will save the tags and not the categories/doctags if options are not set (useful to avoid memory problems)")
       
    51             ->addOption("doctags","D",InputOption::VALUE_NONE, "Will save the document_tags and not the categories/tags if options are not set (useful to avoid memory problems)")
       
    52             ->addOption("ibegin","B",InputOption::VALUE_OPTIONAL, "Iteration begin, to save part of the datas (useful to avoid memory problems)")
       
    53             ->addOption("iend","E",InputOption::VALUE_OPTIONAL, "Iteration end, to save part of the datas (useful to avoid memory problems)");
       
    54     }
       
    55 
       
    56     protected function execute(InputInterface $input, OutputInterface $output)
       
    57     {
       
    58         // Default values
       
    59         $do_cat = FALSE;
       
    60         $do_tags = FALSE;
       
    61         $do_doctags = FALSE;
       
    62         // Get options
       
    63         $file_path = $input->getArgument('path');
       
    64         $simulate = $input->getOption('simulate');
       
    65         $do_cat = $input->getOption('categories');
       
    66         $do_tags = $input->getOption('tags');
       
    67         $do_doctags = $input->getOption('doctags');
       
    68         // If no options were set, we load the 3 objects
       
    69         if(!$do_cat && !$do_tags && !$do_doctags){
       
    70             $do_cat = TRUE;
       
    71             $do_tags = TRUE;
       
    72             $do_doctags = TRUE;
       
    73         }
       
    74         // Set iBegin and iEnd
       
    75         $iBegin = intval($input->getOption('ibegin'));
       
    76         $iEnd = intval($input->getOption('iend'));
       
    77         if($iEnd==0){
       
    78             $iEnd = INF;
       
    79         }
       
    80         $output->writeln("simulate = ".((!$simulate)?"false":"true").", file path = $file_path"
       
    81                         .", load cat = ".(($do_cat)?"true":"false").", load tags = ".(($do_tags)?"true":"false")
       
    82                         .", load doc_tags = ".(($do_doctags)?"true":"false").", ibegin = ".$iBegin.", iend = ".$iEnd.", min = ".min(10, $iEnd));
       
    83         
       
    84         
       
    85         // Parse json file and build the data array.
       
    86         $value = NULL;
       
    87         try {
       
    88             $content = file_get_contents($file_path);
       
    89             $value = json_decode($content, TRUE);
       
    90         } catch (Exception $e) {
       
    91             printf("Unable to parse the JSON string: %s", $e->getMessage());
       
    92         }
       
    93         
       
    94         // We build the 3 data arrays.
       
    95         $categories = array();
       
    96         $tags = array();
       
    97         $doctags = array();
       
    98         foreach ($value as $ar){
       
    99             if($ar["model"]=="hdabo.tagcategory"){
       
   100                 array_push($categories,$ar);
       
   101             }
       
   102             else if($ar["model"]=="hdabo.tag"){
       
   103                 array_push($tags,$ar);
       
   104             }
       
   105             else if($ar["model"]=="hdabo.taggedsheet"){
       
   106                 array_push($doctags,$ar);
       
   107             }
       
   108         }
       
   109         $content = NULL;
       
   110         $value = NULL;
       
   111         
       
   112         // Get the entity manager
       
   113         $em = $this->getContainer()->get('doctrine')->getEntityManager();
       
   114         
       
   115         if($do_cat){
       
   116             // We save the categories, and force their id to be coherent with the tag's data.
       
   117             $nb = count($categories);
       
   118             if($nb>0){
       
   119                 $output->writeln("Saving $nb categories...");
       
   120                 $i = 0;
       
   121                 foreach ($categories as $cat_ar){
       
   122                     $cat = new Category();
       
   123                     $cat->setId($cat_ar["pk"]);
       
   124                     $f = $cat_ar["fields"];
       
   125                     $cat->setLabel($f["label"]);
       
   126                     if(!$simulate){
       
   127                         $em->persist($cat);
       
   128                         // Temporary stop doctrine2 auto increment
       
   129                         $metadata = $em->getClassMetaData(get_class($cat));
       
   130                         $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
       
   131                     }
       
   132                     $i++;
       
   133                     $this->showProgress($output, $i, $nb, "label : ".$f["label"], 50);
       
   134                 }
       
   135                 // We flush here because we need to call the category object when we save the tag's datas.
       
   136                 if(!$simulate){
       
   137                     $em->flush();
       
   138                     $em->clear();
       
   139                     $output->writeln("Categories have been saved");
       
   140                 }
       
   141             }
       
   142         }
       
   143         
       
   144         if($do_tags){
       
   145             $nb = count($tags);
       
   146             if($nb>0){
       
   147                 $output->writeln("Saving $nb tags...");
       
   148                 $cat_repo = $this->getContainer()->get('doctrine')->getRepository('WikiTagBundle:Category');
       
   149                 $stop = min($iEnd+1,$nb);
       
   150                 $output->writeln("Saving from $iBegin to ".($stop-1)." on $nb tags...");
       
   151                 $nbToSave = $stop - $iBegin;
       
   152                 for($i=$iBegin;$i<$stop;$i++){
       
   153                     $tag = new Tag();
       
   154                     $tag->setId($tags[$i]["pk"]);
       
   155                     $f = $tags[$i]["fields"];
       
   156                     $tag->setLabel($f["label"]);
       
   157                     $tag->setNormalizedLabel($f["normalized_label"]);
       
   158                     $tag->setOriginalLabel($f["original_label"]);
       
   159                     $tag->setAlternativeLabel($f["alternative_label"]);
       
   160                     $tag->setAlias($f["alias"]);
       
   161                     $tag->setWikipediaUrl($f["wikipedia_url"]);
       
   162                     $tag->setAlternativeWikipediaUrl($f["alternative_wikipedia_url"]);
       
   163                     $tag->setWikipediaPageId($f["wikipedia_pageid"]);
       
   164                     $tag->setAlternativeWikipediaPageId($f["alternative_wikipedia_pageid"]);
       
   165                     $tag->setUrlStatus($f["url_status"]); // smallint
       
   166                     $tag->setDbpediaUri($f["dbpedia_uri"]);
       
   167                     $tag->setPopularity($f["popularity"]);
       
   168                     $cat = $f["category"];
       
   169                     if($cat!=NULL){
       
   170                         $tag->setCategory($cat_repo->findOneById($cat)); // !! OBJECT CATEGORY
       
   171                     }
       
   172                     $tag->setCreatedAt(new \DateTime($f["created_at"], new \DateTimeZone('UTC')));
       
   173                     if(!$simulate){
       
   174                         $em->persist($tag);
       
   175                         // Temporary stop doctrine2 auto increment
       
   176                         $metadata = $em->getClassMetaData(get_class($tag));
       
   177                         $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
       
   178                     }
       
   179                     // We save every 10 tags to avoid symfony's UnitOfWork crash
       
   180                     if((!$simulate) && ($i%10==0)){
       
   181                         // We flush here because we need to call the tag object when we save the document_tag's datas.
       
   182                         $em->flush();
       
   183                         $em->clear();
       
   184                         $em = $this->getContainer()->get('doctrine')->getEntityManager();
       
   185                     }
       
   186                     $memory = "mem: ".strval(memory_get_usage(true));
       
   187                     $this->showProgress($output, (($i-$iBegin)+1), $nbToSave, "$memory - label : ".$f["label"], 50);
       
   188                 }
       
   189                 // We flush one last time.
       
   190                 if(!$simulate){
       
   191                     $em->flush();
       
   192                     $em->clear();
       
   193                     $em = $this->getContainer()->get('doctrine')->getEntityManager();
       
   194                     $output->writeln("Tags have been saved");
       
   195                 }
       
   196             }
       
   197         }
       
   198         
       
   199         if($do_doctags){
       
   200             $categories = NULL;
       
   201             $tags = NULL;
       
   202             $nb = count($doctags); 
       
   203             if($nb>0){
       
   204                 $tag_repo = $repository = $this->getContainer()->get('doctrine')->getRepository('WikiTagBundle:Tag');
       
   205                 $doc_repo = $repository = $this->getContainer()->get('doctrine')->getRepository('WikiTagBundle:Document');
       
   206                 $stop = min($iEnd,$nb);
       
   207                 $output->writeln("Saving from $iBegin to $stop on $nb document_tags...");
       
   208                 $nbToSave = $stop - $iBegin;
       
   209                 for($i=$iBegin;$i<$stop;$i++){
       
   210                     $f = $doctags[$i]["fields"];
       
   211                     $dt = new DocumentTag();
       
   212                     $dt->setOriginalOrder($f["original_order"]);
       
   213                     $dt->setTagOrder($f["order"]);
       
   214                     $dt->setIndexNote($f["index_note"]);
       
   215                     $dt->setWikipediaRevisionId($f["wikipedia_revision_id"]);
       
   216                     $dt->setTag($tag_repo->findOneById($f["tag"]));
       
   217                     $doc = $doc_repo->findOneByExternalId($f["datasheet"]);
       
   218                     // We save if the document exists
       
   219                     if($doc!=NULL){
       
   220                         $dt->setDocument($doc);
       
   221                         $dt->setCreatedAt(new \DateTime($f["created_at"], new \DateTimeZone('UTC')));
       
   222                         if(!$simulate){
       
   223                             $em->persist($dt);
       
   224                         }
       
   225                     }
       
   226                     else{
       
   227                         $output->writeln("Document with external id ".$f["datasheet"]." was not found !");
       
   228                     }
       
   229                     // We save every 10 tags to avoid symfony's UnitOfWork crash
       
   230                     if((!$simulate) && ($i%10==0)){
       
   231                         // We flush here because we need to call the tag object when we save the document_tag's datas.
       
   232                         $em->flush();
       
   233                         $em->clear();
       
   234                         $em = $this->getContainer()->get('doctrine')->getEntityManager();
       
   235                     }
       
   236                     $memory = "mem: ".strval(memory_get_usage(true));
       
   237                     $this->showProgress($output, (($i-$iBegin)+1), $nbToSave, $memory, 50);
       
   238                 }
       
   239                 if(!$simulate){
       
   240                     $em->flush();
       
   241                     $em->clear();
       
   242                     $output->writeln("DocumentTags have been saved");
       
   243                 }
       
   244             }
       
   245         }
       
   246         
       
   247         
       
   248         if($simulate)
       
   249         {
       
   250             $output->writeln("you simulated.");
       
   251         }
       
   252         else
       
   253         {
       
   254             //$output->writeln("file $file_path loaded.");
       
   255             //$output->writeln(var_dump($value));
       
   256             //$output->writeln("s = ".$s);
       
   257             $output->writeln("End of fixture loading");
       
   258         }
       
   259     }
       
   260 }