2015-03-03 18:51:20 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Trinity\Bundle\SearchBundle\Command;
|
|
|
|
|
|
|
|
use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper;
|
|
|
|
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
use Symfony\Component\Finder\Finder;
|
|
|
|
|
|
|
|
class BuildIndexCommand extends ContainerAwareCommand
|
|
|
|
{
|
|
|
|
protected function configure()
|
|
|
|
{
|
|
|
|
$this
|
|
|
|
->setName('wd:lucene:build-index')
|
|
|
|
->setDescription('Synchronize the index with the database')
|
|
|
|
->setHelp(
|
|
|
|
<<<EOF
|
|
|
|
This command allow to initalize, build or sync an index define by a culture.
|
|
|
|
EOF
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getQuerynameFromFile($file)
|
|
|
|
{
|
|
|
|
$lines = file($file);
|
|
|
|
$namespace = null;
|
|
|
|
|
|
|
|
foreach ($lines as $line) {
|
|
|
|
$line = trim($line, " ;\n\r");
|
|
|
|
$parts = explode(' ', $line);
|
|
|
|
|
|
|
|
if ($parts[0] == 'namespace') {
|
|
|
|
$namespace = '\\'.ltrim(end($parts), '\\');
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($namespace === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $namespace.'\\'.str_replace('.php', 'Query', $file->getFilename());
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output)
|
|
|
|
{
|
|
|
|
$dialog = $this->getDialogHelper();
|
|
|
|
|
|
|
|
if ($input->isInteractive()) {
|
2015-03-05 17:51:23 +01:00
|
|
|
if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) {
|
2015-03-03 18:51:20 +01:00
|
|
|
$output->writeln(
|
|
|
|
array(
|
|
|
|
'',
|
|
|
|
'<error>Command aborted</error>',
|
|
|
|
''
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
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 :',
|
|
|
|
'- <comment>init</comment> : will remove old index entries for all <comment>Indexable</comment> objects',
|
|
|
|
' present in your project. We recommend this option if you use the',
|
|
|
|
' <info>'.$culture.' index</info> for third part data',
|
|
|
|
'- <comment>build</comment> : will remove the index and build it from scratch',
|
|
|
|
'- <comment>sync</comment> : will add new index entries for all <comment>Indexable</comment> 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(
|
|
|
|
'<info>'.$query.'</info> number of elements indexable : <comment>'.count($objects).'</comment>',
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
$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(
|
|
|
|
'<info>'.$query.'</info> number of indexed elements : <comment>'.$indexed_elements.'</comment>',
|
|
|
|
'----------------------------------------------------------------------------',
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$output->writeln(
|
|
|
|
array(
|
|
|
|
'',
|
|
|
|
'The <comment>'.$culture.'</comment> index has been successfully <info>'.$method.'</infos>',
|
|
|
|
'<info>'.$culture.'</info> index information : ',
|
|
|
|
'Index format version : <comment>'.$index->getFormatVersion().'</comment>',
|
|
|
|
'Max buffered documents : <comment>'.$index->getMaxBufferedDocs().'</comment>',
|
|
|
|
'Number of documents (with deleted) : <comment>'.$index->count().'</comment>',
|
|
|
|
'Number of documents (without deleted) : <comment>'.$index->numDocs().'</comment>',
|
|
|
|
'<info>Unique fields</info> 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;
|
|
|
|
}
|
2015-03-05 17:51:23 +01:00
|
|
|
}
|