Command/SyncDocumentsCommand.php
author ymh <ymh.work@gmail.com>
Thu, 17 Nov 2011 11:29:26 +0100
changeset 34 21fab44f46fe
parent 27 8551d844b4f3
child 42 0e57c730bb18
permissions -rwxr-xr-x
add event on tag changed

<?php
/*
 * This file is part of the WikiTagBundle package.
 *
 * (c) IRI <http://www.iri.centrepompidou.fr/>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace IRI\Bundle\WikiTagBundle\Command;

use IRI\Bundle\WikiTagBundle\Event\WikiTagEvents;
use IRI\Bundle\WikiTagBundle\Event\DocumentTagEvent;
use Doctrine\ORM\Query;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class SyncDocumentsCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        parent::configure();
        
        $this
            ->setName('wikitag:sync-doc')
            ->setDescription('Synchronize and index document class')
            ->addOption('missing', 'm', InputOption::VALUE_NONE, "process missing")
            ->addOption('tags', 't', InputOption::VALUE_NONE, "update tags")
            ->addOption('clear', 'c', InputOption::VALUE_NONE, "clear all docs");
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $class = $this->getContainer()->getParameter('wiki_tag.document_class');
        $clear = $input->getOption('clear');
        $missing = $input->getOption('missing');
     
        
        $doctrine = $this->getContainer()->get('doctrine');
        
        $docrep = $doctrine->getRepository('WikiTagBundle:Document');
        $rep = $doctrine->getRepository($class);
        
        if(is_null($rep)) {
            //TODO : translate
            $output->writeln("$class does not have a repository : exiting.");
            return ;
        }
        
        if($input->getOption('tags'))
        {
            if(!$missing)
            {
                $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc from WikiTagBundle:Document doc");
                $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT COUNT(doc.id) from WikiTagBundle:Document doc");
            }
            else
            {
                $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc from WikiTagBundle:Document doc WHERE doc.tagsStr IS NULL");
                $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT COUNT(doc.id) from WikiTagBundle:Document doc WHERE doc.tagsStr IS NULL");
            }
            
            
            $total = $doccountquery->getSingleScalarResult();
            $done = 0;
            $iterable = $docquery->iterate();
            $todetach = array();
            while (($row = $iterable->next()) !== false) {
                $done++;
                $memory = ((($done%10)==0)?" - mem: ".strval(memory_get_usage(true)):"");
                $doc = $row[0];
                $todetach[] = $doc;
                $output->writeln("Process doc id ".$doc->getId()." $done/$total ".strval(intval(floatval($done)/floatval($total)*100.0))."%$memory");
                $docrep->updateTagsStr($doc);
                //dispatch event
                $event_dispatcher = $this->getContainer()->get('event_dispatcher');
                $event = new DocumentTagEvent($doc);
                $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event);
                
                if($done%10 == 0)
                {
                    $doctrine->getEntityManager()->flush();
                    foreach($todetach as $obj)
                    {
                        $doctrine->getEntityManager()->detach($obj);
                    }
                    $todetach = array();
                }
            }
            $doctrine->getEntityManager()->flush();
                        
            return;
            
        }
        
        //TODO : check class to implement DocumentInterface
        //TODO : write progress
        if($missing)
        {
            $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc FROM $class doc WHERE doc.id not in (SELECT wtdoc FROM WikiTagBundle:Document wtdoc)");
            $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT count(doc.id) FROM $class doc WHERE doc.id not in (SELECT wtdoc FROM WikiTagBundle:Document wtdoc)");
            //$doclist = $doctrine->getEntityManager()->createQuery("SELECT doc FROM $class doc WHERE doc.id not in (SELECT wtdoc FROM WikiTagBundle:Document wtdoc)")->getResult();
        }
        else
        {
            $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc FROM $class doc");
            $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT count(doc.id) FROM $class doc");
            //$doclist = $rep->findAll();
        }
        $total = $doccountquery->getSingleScalarResult();
        $done = 0;
        $iterable = $docquery->iterate();
        while (($row = $iterable->next()) !== false) {
            $done++;
            $doc = $row[0];
            $memory = ((($done%10)==0)?" - mem: ".strval(memory_get_usage(true)):"");
            $output->writeln("Process doc id ".$doc->getId()." $done/$total ".strval(intval(floatval($done)/floatval($total)*100.0))."%$memory");
            $docrep->writeDocument($doc, $this->getContainer()->getParameter('wiki_tag.document_id_column'), $this->getContainer()->getParameter('wiki_tag.fields'));
            if($done%10 == 0)
            {
                $doctrine->getEntityManager()->flush();
                $doctrine->getEntityManager()->clear();
            }
        }
        $doctrine->getEntityManager()->flush();
        
        if($clear) {
            
            $req = $doctrine->getEntityManager()->createQuery("DELETE WikiTagBundle:Document wtdoc WHERE wtdoc.externalId NOT IN (SELECT doc FROM $class doc)");
            $req->getResult();
            $doctrine->getEntityManager()->flush();
        }

        $output->writeln(strval(count($doclist)) ." documents imported.");
    }
}