Skip to content

Commit 0662c2e

Browse files
authored
Merge pull request #1 from mdiyakov/v1.1
V1.1
2 parents e45ec13 + fbdfa9e commit 0662c2e

22 files changed

+555
-25
lines changed

Command/ClearIndexCommand.php

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
namespace Mdiyakov\DoctrineSolrBundle\Command;
4+
5+
use Doctrine\Bundle\DoctrineBundle\Registry;
6+
use Doctrine\ORM\EntityNotFoundException;
7+
use Mdiyakov\DoctrineSolrBundle\Config\Config;
8+
use Mdiyakov\DoctrineSolrBundle\Exception\EntityNotIndexedException;
9+
use Mdiyakov\DoctrineSolrBundle\Query\UpdateQueryBuilder;
10+
use Symfony\Component\Console\Input\InputArgument;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
use Symfony\Component\Console\Command\Command;
14+
15+
class ClearIndexCommand extends Command
16+
{
17+
18+
/**
19+
* @var OutputInterface
20+
*/
21+
private $output;
22+
23+
/**
24+
* @var Config
25+
*/
26+
private $config;
27+
28+
/**
29+
* @var UpdateQueryBuilder
30+
*/
31+
private $updateQueryBuilder;
32+
33+
/**
34+
* @var Registry
35+
*/
36+
private $registry;
37+
38+
/**
39+
* @param Config $config
40+
* @param UpdateQueryBuilder $updateQueryBuilder
41+
* @param Registry $registry
42+
*/
43+
public function __construct(
44+
Config $config,
45+
UpdateQueryBuilder $updateQueryBuilder,
46+
Registry $registry
47+
)
48+
{
49+
$this->config = $config;
50+
$this->possibleEntityTypes = array_keys($this->getAssocEntitiesClasses());
51+
$this->updateQueryBuilder = $updateQueryBuilder;
52+
$this->registry = $registry;
53+
54+
parent::__construct();
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*/
60+
protected function configure()
61+
{
62+
$this
63+
->setName('doctrine-solr:clear-index')
64+
->addArgument(
65+
'entity-type',
66+
InputArgument::OPTIONAL,
67+
'Specify type of entity to be removed. Possible values are "all", "' . join('","', $this->possibleEntityTypes),
68+
'all'
69+
)
70+
->addArgument(
71+
'id',
72+
InputArgument::OPTIONAL,
73+
'Specify id of entity to be removed. Value must be integer. Also entity-type must be specify'
74+
)
75+
;
76+
}
77+
78+
/**
79+
* {@inheritdoc}
80+
*/
81+
protected function execute(InputInterface $input, OutputInterface $output)
82+
{
83+
$this->output = $output;
84+
$entityType = $input->getArgument('entity-type');
85+
$entityId = (int) $input->getArgument('id');
86+
87+
if ($entityType == 'all') {
88+
foreach ($this->config->getIndexedEntities() as $entityConfig) {
89+
$this->deleteByEntityConfig(
90+
$entityConfig
91+
);
92+
}
93+
} else {
94+
$entitiesClasses = $this->getAssocEntitiesClasses();
95+
if (!array_key_exists($entityType, $entitiesClasses )) {
96+
throw new \Exception('There is no such possible entity-type. Check help section for possible values');
97+
}
98+
$entityClass = $entitiesClasses[$entityType];
99+
$entityConfig = $this->config->getEntityConfig($entityClass);
100+
if (!$entityConfig) {
101+
throw new EntityNotIndexedException(
102+
sprintf('Entity class %s is not found in config', $entityClass)
103+
);
104+
}
105+
106+
$this->deleteByEntityConfig(
107+
$entityConfig,
108+
$entityId
109+
);
110+
}
111+
}
112+
113+
/**
114+
* @return string[]
115+
*/
116+
private function getAssocEntitiesClasses()
117+
{
118+
$entitiesConfigs = $this->config->getIndexedEntities();
119+
120+
$result = [];
121+
foreach ($entitiesConfigs as $entityKey => $entityConfig) {
122+
$result[$entityKey] = $entityConfig['class'];
123+
}
124+
125+
return $result;
126+
}
127+
128+
/**
129+
* @param string[][] $entityConfig
130+
* @param null|int $id
131+
* @throws EntityNotFoundException
132+
*/
133+
private function deleteByEntityConfig($entityConfig, $id = null)
134+
{
135+
$schemaName = $entityConfig['schema'];
136+
$updateQuery = $this->updateQueryBuilder->buildUpdateQueryBySchemaName($schemaName);
137+
$schema = $this->config->getSchemaByName($schemaName);
138+
$em = $this->registry->getManagerForClass($entityConfig['class']);
139+
140+
if (empty($id)) {
141+
$discriminatorField = $schema->getDiscriminatorConfigField();
142+
$discriminatorValue = $discriminatorField->getValue($entityConfig);
143+
$updateQuery->addDeleteCriteriaByConfigField(
144+
$discriminatorField->getDocumentFieldName(),
145+
$discriminatorValue
146+
);
147+
$message = sprintf('Removing of %s is completed successfully', $entityConfig['class']);
148+
} else {
149+
$entityClass = $entityConfig['class'];
150+
$repository = $em->getRepository($entityClass);
151+
$entity = $repository->find($id);
152+
153+
if (!$entity) {
154+
throw new EntityNotFoundException(
155+
sprintf('% with %s id is not found', $entityClass, $id)
156+
);
157+
}
158+
159+
$updateQuery->addDeleteCriteriaByUniqueFieldValue(
160+
$schema->getDocumentUniqueField()->getValue($entity, $entityConfig)
161+
);
162+
163+
$message = sprintf('Removing of %s with id %s is completed successfully',
164+
$entityClass,
165+
$id
166+
);
167+
168+
}
169+
170+
$updateQuery->update();
171+
$this->output->writeln($message);
172+
}
173+
}

Command/IndexEntitiesCommand.php

+18-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Mdiyakov\DoctrineSolrBundle\Command;
44

5+
use Doctrine\Bundle\DoctrineBundle\Registry;
56
use Doctrine\ORM\EntityManager;
67
use Doctrine\ORM\EntityRepository;
78
use Symfony\Component\Console\Input\InputArgument;
@@ -17,9 +18,9 @@ class IndexEntitiesCommand extends Command
1718
const BUNCH_COUNT = 100;
1819

1920
/**
20-
* @var EntityManager
21+
* @var Registry
2122
*/
22-
private $em;
23+
private $registry;
2324

2425
/**
2526
* @var Config
@@ -44,14 +45,14 @@ class IndexEntitiesCommand extends Command
4445
/**
4546
* @param Config $config
4647
* @param IndexProcessManager $indexProcessManager
47-
* @param EntityManager $em
48+
* @param Registry $registry
4849
*/
49-
public function __construct(Config $config, IndexProcessManager $indexProcessManager, EntityManager $em)
50+
public function __construct(Config $config, IndexProcessManager $indexProcessManager, Registry $registry)
5051
{
5152
$this->config = $config;
5253
$this->indexProcessManager = $indexProcessManager;
5354
$this->possibleEntityTypes = array_keys($this->getAssocEntitiesClasses());
54-
$this->em = $em;
55+
$this->registry = $registry;
5556

5657
parent::__construct();
5758
}
@@ -105,10 +106,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
105106
* @param string $entityClass
106107
* @param int|null $id
107108
* @throws \Exception
109+
* @throws \LogicException
108110
*/
109111
private function indexEntityClass($entityClass, $id = null)
110112
{
111-
$repository = $this->em->getRepository($entityClass);
113+
$em = $this->registry->getManagerForClass($entityClass);
114+
if (!$em instanceof EntityManager) {
115+
throw new \LogicException('EntityManager must be instance of EntityManager');
116+
}
117+
118+
$repository = $em->getRepository($entityClass);
112119
if ($id) {
113120
$entity = $repository->find($id);
114121
if (!$entity) {
@@ -118,21 +125,23 @@ private function indexEntityClass($entityClass, $id = null)
118125
}
119126
$this->processEntity($entity);
120127
} else {
121-
$this->processRepository($repository);
128+
$this->processRepository($repository, $em);
122129
}
123130
}
124131

125132
/**
126133
* @param EntityRepository $repository
134+
* @param EntityManager $em
127135
*/
128-
private function processRepository(EntityRepository $repository)
136+
private function processRepository(EntityRepository $repository, EntityManager $em)
129137
{
130138
$offset = 0;
131139
while ($entities = $repository->findBy([],['id'=> 'asc'], self::BUNCH_COUNT, $offset)) {
132140
foreach ($entities as $entity) {
133141
$this->processEntity($entity);
134142
}
135-
$this->em->clear($repository->getClassName());
143+
144+
$em->clear($repository->getClassName());
136145
$offset += self::BUNCH_COUNT;
137146
}
138147
}

Manager/EntityManager.php

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace Mdiyakov\DoctrineSolrBundle\Manager;
4+
5+
use Doctrine\Bundle\DoctrineBundle\Registry;
6+
use Doctrine\ORM\EntityManagerInterface;
7+
8+
class EntityManager
9+
{
10+
/**
11+
* @var IndexProcessManager
12+
*/
13+
private $indexProcessManager;
14+
15+
/**
16+
* @var Registry
17+
*/
18+
private $registry;
19+
20+
/**
21+
* @param IndexProcessManager $indexProcessManager
22+
* @param Registry $registry
23+
*/
24+
public function __construct(
25+
IndexProcessManager $indexProcessManager,
26+
Registry $registry
27+
) {
28+
$this->indexProcessManager = $indexProcessManager;
29+
$this->registry = $registry;
30+
}
31+
32+
/**
33+
* @param object $entity
34+
* @throws \Doctrine\ORM\ORMException
35+
* @throws \InvalidArgumentException
36+
* @throws \LogicException
37+
* @throws \Exception
38+
*/
39+
public function flush($entity)
40+
{
41+
if (!is_object($entity)) {
42+
throw new \InvalidArgumentException('Entity must be an object');
43+
}
44+
45+
if (!method_exists($entity, 'getId')) {
46+
throw new \LogicException('Entity must have method "getId" to handle rollback');
47+
}
48+
49+
/** @var \Doctrine\ORM\EntityManager $em */
50+
$em = $this->getEm($entity);
51+
try {
52+
$em->persist($entity);
53+
$em->flush($entity);
54+
} catch (\Exception $e) {
55+
if (!$em->isOpen()) {
56+
$em = $em->create(
57+
$em->getConnection(), $em->getConfiguration()
58+
);
59+
}
60+
61+
$previousEntity = $em->getRepository(get_class($entity))->find($entity->getId());
62+
if ($previousEntity) {
63+
$this->indexProcessManager->reindex($previousEntity);
64+
} else {
65+
$this->indexProcessManager->remove($entity);
66+
}
67+
68+
throw $e;
69+
}
70+
}
71+
72+
/**
73+
* @param object $entity
74+
* @throws \InvalidArgumentException
75+
* @return EntityManagerInterface
76+
*/
77+
private function getEm($entity)
78+
{
79+
$em = $this->registry->getManagerForClass(get_class($entity));
80+
if (!$em) {
81+
throw new \InvalidArgumentException(
82+
sprintf('There is no entity manager for "%s" class', get_class($entity))
83+
);
84+
}
85+
86+
if (!$em instanceof EntityManagerInterface) {
87+
throw new \InvalidArgumentException(
88+
'Entity manager must be instance of "EntityManagerInterface" class'
89+
);
90+
}
91+
92+
return $em;
93+
}
94+
}

0 commit comments

Comments
 (0)