Issues (258)

Doctrine/EventListener.php (1 issue)

forgotten debug code.

Debugging Code Security Critical
1
<?php
2
/**
3
 * Copyright (C) 2018 Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 * @license GPL-3.0
8
 * @author Gerrit Addiks <[email protected]>
9
 */
10
11
namespace Addiks\RDMBundle\Doctrine;
12
13
use Addiks\RDMBundle\Hydration\EntityHydratorInterface;
14
use Addiks\RDMBundle\Mapping\Drivers\MappingDriverInterface;
15
use Addiks\RDMBundle\Mapping\EntityMappingInterface;
16
use Addiks\RDMBundle\DataLoader\DataLoaderInterface;
17
use Doctrine\ORM\Event\LifecycleEventArgs;
18
use Doctrine\ORM\Mapping\ClassMetadata;
19
use Doctrine\ORM\Tools\SchemaTool;
20
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
21
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
22
use Doctrine\ORM\EntityManagerInterface;
23
use Doctrine\ORM\UnitOfWork;
24
use Doctrine\DBAL\Schema\Table;
25
use Doctrine\ORM\Event\PostFlushEventArgs;
26
use Doctrine\ORM\Proxy\Proxy;
27
use Doctrine\DBAL\Schema\Column;
28
use PDOException;
29
use Doctrine\DBAL\Exception\ConnectionException;
30
31
/**
32
 * Hooks into the event's of doctrine2-ORM and forwards the entities to other objects.
33
 */
34
final class EventListener
35
{
36
37
    /**
38
     * @var EntityHydratorInterface
39
     */
40
    private $entityHydrator;
41
42
    /**
43
     * @var MappingDriverInterface
44
     */
45
    private $mappingDriver;
46
47
    /**
48
     * @var DataLoaderInterface
49
     */
50
    private $dbalDataLoader;
51
52
    /**
53
     * @var array<class-string, bool>
54
     */
55 10
    private $hasRdmMappingForClass = array();
56
57
    public function __construct(
58
        EntityHydratorInterface $entityHydrator,
59
        MappingDriverInterface $mappingDriver,
60 10
        DataLoaderInterface $dbalDataLoader
61 10
    ) {
62 10
        $this->entityHydrator = $entityHydrator;
63
        $this->mappingDriver = $mappingDriver;
64
        $this->dbalDataLoader = $dbalDataLoader;
65 3
    }
66
67
    public function postLoad(LifecycleEventArgs $arguments): void
68 3
    {
69
        /** @var object $entity */
70
        $entity = $arguments->getEntity();
71 3
72
        /** @var EntityManagerInterface $entityManager */
73 3
        $entityManager = $arguments->getEntityManager();
74
75
        $this->entityHydrator->hydrateEntity($entity, $entityManager);
76 3
    }
77
78
    public function prePersist(LifecycleEventArgs $arguments): void
79 3
    {
80
        /** @var object $entity */
81
        $entity = $arguments->getEntity();
82 3
83
        /** @var EntityManagerInterface $entityManager */
84 3
        $entityManager = $arguments->getEntityManager();
85 3
86
        if (!($entity instanceof Proxy)) {
87
            $this->entityHydrator->assertHydrationOnEntity($entity, $entityManager);
88
        }
89 5
    }
90
91
    public function postFlush(PostFlushEventArgs $arguments): void
92 5
    {
93
        /** @var EntityManagerInterface $entityManager */
94
        $entityManager = $arguments->getEntityManager();
95 5
96
        /** @var UnitOfWork $unitOfWork */
97
        $unitOfWork = $entityManager->getUnitOfWork();
98 5
99 5
        /** @param class-string $className */
100 1
        foreach ($unitOfWork->getIdentityMap() as $className => $entities) {
101
            if (!$this->hasRdmMappingForClass($className)) {
102
                continue;
103 4
            }
104
105
            foreach ($entities as $entity) {
106 4
                /** @var object $entity */
107 4
108
                if (!$this->isUnitializedProxy($entity)) {
109
                    if ($unitOfWork->isScheduledForDelete($entity)) {
110
                        $this->dbalDataLoader->removeDBALDataForEntity($entity, $entityManager);
111 4
112
                    } else {
113
                        $this->dbalDataLoader->storeDBALDataForEntity($entity, $entityManager);
114
                    }
115
                }
116
            }
117
        }
118 5
    }
119
120
    public function loadClassMetadata(LoadClassMetadataEventArgs $arguments): void
121 5
    {
122
        /** @var EntityManagerInterface $entityManager */
123
        $entityManager = $arguments->getEntityManager();
124 5
125
        /** @var ClassMetadata $classMetadata */
126 5
        $classMetadata = $arguments->getClassMetadata();
127
128
        try {
129
            $this->dbalDataLoader->prepareOnMetadataLoad($entityManager, $classMetadata);
130
131
        } catch (PDOException | ConnectionException $exception) {
132
            var_dump($exception->getMessage());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($exception->getMessage()) looks like debug code. Are you sure you do not want to remove it?
Loading history...
133
            if (!str_contains($exception->getMessage(), 'No such file or directory')) {
134
                throw $exception;
135
            }
136 2
        }
137
    }
138
139 2
    /**
140
     * Invoked when doctrine has generated a table-definition in the target-schema.
141
     * Collects the additional schema-columns from the mapping and add's them to the table.
142 2
     *
143
     * Dispatched in:
144
     * @see SchemaTool::getSchemaFromMetadata
145 2
     */
146
    public function postGenerateSchemaTable(GenerateSchemaTableEventArgs $arguments): void
147
    {
148 2
        /** @var Table $table */
149
        $table = $arguments->getClassTable();
150 2
151
        /** @var ClassMetadata $classMetadata */
152 2
        $classMetadata = $arguments->getClassMetadata();
153
154 2
        /** @var class-string $className */
155
        $className = $classMetadata->getName();
156
157
        /** @var ?EntityMappingInterface $entityMapping */
158 2
        $entityMapping = $this->mappingDriver->loadRDMMetadataForClass($className);
159
160 2
        if ($entityMapping instanceof EntityMappingInterface) {
161 2
            /** @var array<Column> $additionalColumns */
162
            $additionalColumns = $entityMapping->collectDBALColumns();
163 2
164 2
            foreach ($additionalColumns as $column) {
165
                /** @var Column $column */
166
167
                /** @var string $columnName */
168
                $columnName = $column->getName();
169
170
                if (!$table->hasColumn($columnName)) {
171
                    
172 5
                    /** @var array<string, mixed> $columnConfig */
173
                    $columnConfig = $column->toArray();
174 5
                    unset($columnConfig['name']);
175
                    
176 5
                    $table->addColumn(
177
                        $columnName,
178
                        $column->getType()->getName(),
179 5
                        $columnConfig
180 5
                    );
181
                }
182
            }
183 5
        }
184 5
    }
185
186
    /** @param class-string $className */
187 5
    private function hasRdmMappingForClass(string $className): bool
188
    {
189
        if (!isset($this->hasRdmMappingForClass[$className])) {
190
            /** @var class-string $currentClassName */
191
            $currentClassName = $className;
192
193 4
            do {
194
                $this->hasRdmMappingForClass[$className] = is_object(
195
                    $this->mappingDriver->loadRDMMetadataForClass($currentClassName)
196 4
                );
197
198 4
                $currentClassName = current(class_parents($currentClassName));
199
            } while (class_exists($currentClassName) && !$this->hasRdmMappingForClass[$className]);
200
        }
201
202 4
        return $this->hasRdmMappingForClass[$className];
203
    }
204
205
    /**
206
     * @param object $entity
207
     */
208
    private function isUnitializedProxy($entity): bool
209
    {
210
        /** @var bool $isUnitializedProxy */
211
        $isUnitializedProxy = false;
212
213
        if ($entity instanceof Proxy && !$entity->__isInitialized()) {
214
            $isUnitializedProxy = true;
215
        }
216
217
        return $isUnitializedProxy;
218
    }
219
220
}
221