setName('wd:lucene:build-index') ->setDescription('Synchronize the index with the database') ->setHelp( <<getFilename()); } protected function execute(InputInterface $input, OutputInterface $output) { $dialog = $this->getDialogHelper(); if ($input->isInteractive()) { if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { $output->writeln( array( '', 'Command aborted', '' ) ); return 1; } } $culture = $dialog->ask( $output, $dialog->getQuestion('Lucene index to generate ', 'fr_FR'), 'fr_FR' ); $output->writeln( array( '', 'You are allowed to choose between two methods :', '- init : will remove old index entries for all Indexable objects', ' present in your project. We recommend this option if you use the', ' '.$culture.' index for third part data', '- build : will remove the index and build it from scratch', '- sync : will add new index entries for all Indexable objects', ' which aren\'t indexed yet', '', ) ); $method = $dialog->askAndValidate( $output, $dialog->getQuestion('Choose the method to process on the index', 'sync'), array($this, 'validateMethod'), false, 'sync', array('build', 'sync', 'init') ); $root_app_dir = $this->getContainer()->get('kernel')->getRootDir(); $finder = new Finder(); $files = $finder ->files() ->path('/Model/') ->notPath('/Model/map') ->notPath('/Model/om') ->contains('IndexableInterface') ->notName('IndexableInterface.php') ->in($root_app_dir.'/../src') ->in($root_app_dir.'/../vendor/trinity'); if ($method == 'build') { $this->getContainer()->get('ivory_lucene_search')->eraseIndex($culture); } $index = $this->getContainer()->get('ivory_lucene_search')->getIndex($culture); foreach ($files as $file) { $query = $this->getQuerynameFromFile($file); if (null === $query) { continue; } $objects = $query::create()->find(); $output->writeln( array( ''.$query.' number of elements indexable : '.count($objects).'', ) ); $indexed_elements = 0; foreach ($objects as $object) { $hits = $index->find('pk:'.$object->getIndexKey()); if ($method == 'init') { foreach ($hits as $hit) { $index->delete($hit->id); $index->commit(); } } if ($method == 'sync' && count($hits) > 0) { continue; } $document = $object->getLuceneDocument($culture); if (!$document) { continue; } $index->addDocument($document); $index->commit(); $index->optimize(); $indexed_elements++; } $output->writeln( array( ''.$query.' number of indexed elements : '.$indexed_elements.'', '----------------------------------------------------------------------------', ) ); } $output->writeln( array( '', 'The '.$culture.' index has been successfully '.$method.'', ''.$culture.' index information : ', 'Index format version : '.$index->getFormatVersion().'', 'Max buffered documents : '.$index->getMaxBufferedDocs().'', 'Number of documents (with deleted) : '.$index->count().'', 'Number of documents (without deleted) : '.$index->numDocs().'', 'Unique fields in index : '.implode(', ', $index->getFieldNames()).'', '', ) ); } public function validateMethod($method) { $allowed_method = array('sync', 'build', 'init'); if (!in_array($method, $allowed_method)) { throw new \InvalidArgumentException('This method isn\'t allowed by this command.'); } return $method; } /** * @return DialogHelper|\Symfony\Component\Console\Helper\HelperInterface */ protected function getDialogHelper() { $dialog = $this->getHelperSet()->get('dialog'); if (!$dialog || get_class($dialog) !== 'Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper') { $this->getHelperSet()->set($dialog = new DialogHelper()); } return $dialog; } }