1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace JMS\JobQueueBundle\Entity\Listener; |
4
|
|
|
|
5
|
|
|
use Doctrine\ORM\Event\LifecycleEventArgs; |
6
|
|
|
use Doctrine\Persistence\ManagerRegistry; |
7
|
|
|
use JMS\JobQueueBundle\Entity\Job; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Provides many-to-any association support for jobs. |
11
|
|
|
* |
12
|
|
|
* This listener only implements the minimal support for this feature. For |
13
|
|
|
* example, currently we do not support any modification of a collection after |
14
|
|
|
* its initial creation. |
15
|
|
|
* |
16
|
|
|
* @see http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/annotations/ManyToAny.html |
17
|
|
|
* @author Johannes M. Schmitt <[email protected]> |
18
|
|
|
*/ |
19
|
|
|
class ManyToAnyListener |
20
|
|
|
{ |
21
|
|
|
private $registry; |
22
|
52 |
|
private $ref; |
23
|
|
|
|
24
|
52 |
|
public function __construct(ManagerRegistry $registry) |
25
|
52 |
|
{ |
26
|
52 |
|
$this->registry = $registry; |
27
|
52 |
|
$this->ref = new \ReflectionProperty('JMS\JobQueueBundle\Entity\Job', 'relatedEntities'); |
28
|
|
|
$this->ref->setAccessible(true); |
29
|
32 |
|
} |
30
|
|
|
|
31
|
32 |
|
public function postLoad(\Doctrine\ORM\Event\LifecycleEventArgs $event) |
32
|
32 |
|
{ |
33
|
2 |
|
$entity = $event->getEntity(); |
34
|
|
|
if (!$entity instanceof \JMS\JobQueueBundle\Entity\Job) { |
35
|
|
|
return; |
36
|
32 |
|
} |
37
|
32 |
|
|
38
|
|
|
$this->ref->setValue($entity, new PersistentRelatedEntitiesCollection($this->registry, $entity)); |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
public function preRemove(LifecycleEventArgs $event) |
42
|
|
|
{ |
43
|
|
|
$entity = $event->getEntity(); |
44
|
|
|
if (!$entity instanceof Job) { |
45
|
|
|
return; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
$con = $event->getEntityManager()->getConnection(); |
49
|
|
|
$con->executeStatement("DELETE FROM jms_job_related_entities WHERE job_id = :id", array( |
50
|
|
|
'id' => $entity->getId(), |
51
|
|
|
)); |
52
|
48 |
|
} |
53
|
|
|
|
54
|
48 |
|
public function postPersist(\Doctrine\ORM\Event\LifecycleEventArgs $event) |
55
|
48 |
|
{ |
56
|
4 |
|
$entity = $event->getEntity(); |
57
|
|
|
if (!$entity instanceof \JMS\JobQueueBundle\Entity\Job) { |
58
|
|
|
return; |
59
|
48 |
|
} |
60
|
48 |
|
|
61
|
4 |
|
$con = $event->getEntityManager()->getConnection(); |
62
|
4 |
|
foreach ($this->ref->getValue($entity) as $relatedEntity) { |
63
|
4 |
|
$relClass = \Doctrine\Common\Util\ClassUtils::getClass($relatedEntity); |
64
|
|
|
$relId = $this->registry->getManagerForClass($relClass)->getMetadataFactory()->getMetadataFor($relClass)->getIdentifierValues($relatedEntity); |
65
|
4 |
|
asort($relId); |
66
|
|
|
|
67
|
|
|
if (!$relId) { |
|
|
|
|
68
|
|
|
throw new \RuntimeException('The identifier for the related entity "' . $relClass . '" was empty.'); |
69
|
4 |
|
} |
70
|
4 |
|
|
71
|
4 |
|
$con->executeStatement("INSERT INTO jms_job_related_entities (job_id, related_class, related_id) VALUES (:jobId, :relClass, :relId)", array( |
72
|
4 |
|
'jobId' => $entity->getId(), |
73
|
|
|
'relClass' => $relClass, |
74
|
|
|
'relId' => json_encode($relId), |
75
|
48 |
|
)); |
76
|
|
|
} |
77
|
52 |
|
} |
78
|
|
|
|
79
|
52 |
|
public function postGenerateSchema(\Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs $event) |
80
|
|
|
{ |
81
|
|
|
$schema = $event->getSchema(); |
82
|
52 |
|
|
83
|
22 |
|
// When using multiple entity managers ignore events that are triggered by other entity managers. |
84
|
|
|
if ($event->getEntityManager()->getMetadataFactory()->isTransient('JMS\JobQueueBundle\Entity\Job')) { |
85
|
|
|
return; |
86
|
52 |
|
} |
87
|
52 |
|
|
88
|
52 |
|
$table = $schema->createTable('jms_job_related_entities'); |
89
|
52 |
|
$table->addColumn('job_id', 'bigint', array('notnull' => true, 'unsigned' => true)); |
90
|
52 |
|
$table->addColumn('related_class', 'string', array('notnull' => true, 'length' => '150')); |
91
|
52 |
|
$table->addColumn('related_id', 'string', array('notnull' => true, 'length' => '100')); |
92
|
52 |
|
$table->setPrimaryKey(array('job_id', 'related_class', 'related_id')); |
93
|
|
|
$table->addForeignKeyConstraint('jms_jobs', array('job_id'), array('id')); |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.