These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Doctrine\ODM\MongoDB\Proxy; |
||
6 | |||
7 | use Doctrine\Common\EventManager; |
||
8 | use Doctrine\Common\NotifyPropertyChanged; |
||
9 | use Doctrine\Common\Persistence\Mapping\ClassMetadata as BaseClassMetadata; |
||
10 | use Doctrine\Common\Proxy\AbstractProxyFactory; |
||
11 | use Doctrine\Common\Proxy\Proxy as BaseProxy; |
||
12 | use Doctrine\Common\Proxy\ProxyDefinition; |
||
13 | use Doctrine\Common\Proxy\ProxyGenerator; |
||
14 | use Doctrine\Common\Util\ClassUtils; |
||
15 | use Doctrine\ODM\MongoDB\DocumentManager; |
||
16 | use Doctrine\ODM\MongoDB\DocumentNotFoundException; |
||
17 | use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; |
||
18 | use Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory; |
||
19 | use Doctrine\ODM\MongoDB\Persisters\DocumentPersister; |
||
20 | use Doctrine\ODM\MongoDB\UnitOfWork; |
||
21 | use Doctrine\ODM\MongoDB\Utility\LifecycleEventManager; |
||
22 | use ReflectionProperty; |
||
23 | use function get_class; |
||
24 | |||
25 | /** |
||
26 | * This factory is used to create proxy objects for documents at runtime. |
||
27 | * |
||
28 | */ |
||
29 | class ProxyFactory extends AbstractProxyFactory |
||
0 ignored issues
–
show
|
|||
30 | { |
||
31 | /** @var ClassMetadataFactory */ |
||
32 | private $metadataFactory; |
||
0 ignored issues
–
show
|
|||
33 | |||
34 | /** @var UnitOfWork The UnitOfWork this factory is bound to. */ |
||
35 | private $uow; |
||
36 | |||
37 | /** @var string The namespace that contains all proxy classes. */ |
||
38 | private $proxyNamespace; |
||
39 | |||
40 | /** @var EventManager */ |
||
41 | private $lifecycleEventManager; |
||
42 | |||
43 | /** |
||
44 | * Initializes a new instance of the <tt>ProxyFactory</tt> class that is |
||
45 | * connected to the given <tt>DocumentManager</tt>. |
||
46 | * |
||
47 | * @param DocumentManager $documentManager The DocumentManager the new factory works for. |
||
48 | * @param string $proxyDir The directory to use for the proxy classes. It |
||
49 | * must exist. |
||
50 | * @param string $proxyNamespace The namespace to use for the proxy classes. |
||
51 | * @param int $autoGenerate Whether to automatically generate proxy classes. |
||
52 | */ |
||
53 | 1605 | public function __construct(DocumentManager $documentManager, $proxyDir, $proxyNamespace, $autoGenerate = AbstractProxyFactory::AUTOGENERATE_NEVER) |
|
54 | { |
||
55 | 1605 | $this->metadataFactory = $documentManager->getMetadataFactory(); |
|
56 | 1605 | $this->uow = $documentManager->getUnitOfWork(); |
|
57 | 1605 | $this->proxyNamespace = $proxyNamespace; |
|
58 | 1605 | $this->lifecycleEventManager = new LifecycleEventManager($documentManager, $this->uow, $documentManager->getEventManager()); |
|
59 | 1605 | $proxyGenerator = new ProxyGenerator($proxyDir, $proxyNamespace); |
|
0 ignored issues
–
show
The class
Doctrine\Common\Proxy\ProxyGenerator has been deprecated with message: The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead.
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.
Loading history...
|
|||
60 | |||
61 | 1605 | $proxyGenerator->setPlaceholder('baseProxyInterface', Proxy::class); |
|
62 | |||
63 | 1605 | parent::__construct($proxyGenerator, $this->metadataFactory, $autoGenerate); |
|
64 | 1605 | } |
|
65 | |||
66 | /** |
||
67 | * {@inheritDoc} |
||
68 | */ |
||
69 | public function skipClass(BaseClassMetadata $class) |
||
70 | { |
||
71 | /** @var ClassMetadata $class */ |
||
72 | return $class->isMappedSuperclass || $class->isQueryResultDocument || $class->getReflectionClass()->isAbstract(); |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * {@inheritDoc} |
||
77 | */ |
||
78 | 104 | public function createProxyDefinition($className) |
|
79 | { |
||
80 | /** @var ClassMetadata $classMetadata */ |
||
81 | 104 | $classMetadata = $this->metadataFactory->getMetadataFor($className); |
|
82 | 104 | $documentPersister = $this->uow->getDocumentPersister($className); |
|
83 | 104 | $reflectionId = $classMetadata->reflFields[$classMetadata->identifier]; |
|
84 | |||
85 | 104 | return new ProxyDefinition( |
|
0 ignored issues
–
show
The class
Doctrine\Common\Proxy\ProxyDefinition has been deprecated with message: The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead.
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.
Loading history...
|
|||
86 | 104 | ClassUtils::generateProxyClassName($className, $this->proxyNamespace), |
|
87 | 104 | $classMetadata->getIdentifierFieldNames(), |
|
88 | 104 | $classMetadata->getReflectionProperties(), |
|
89 | 104 | $this->createInitializer($classMetadata, $documentPersister, $reflectionId), |
|
90 | 104 | $this->createCloner($classMetadata, $documentPersister, $reflectionId) |
|
91 | ); |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * Generates a closure capable of initializing a proxy |
||
96 | * |
||
97 | * |
||
98 | * @return \Closure |
||
99 | * |
||
100 | * @throws DocumentNotFoundException |
||
101 | */ |
||
102 | 104 | private function createInitializer( |
|
103 | BaseClassMetadata $classMetadata, |
||
104 | DocumentPersister $documentPersister, |
||
105 | ReflectionProperty $reflectionId |
||
106 | ) { |
||
107 | 104 | if ($classMetadata->getReflectionClass()->hasMethod('__wakeup')) { |
|
108 | View Code Duplication | return function (BaseProxy $proxy) use ($documentPersister, $reflectionId) { |
|
109 | $proxy->__setInitializer(null); |
||
110 | $proxy->__setCloner(null); |
||
111 | |||
112 | if ($proxy->__isInitialized()) { |
||
113 | return; |
||
114 | } |
||
115 | |||
116 | $properties = $proxy->__getLazyProperties(); |
||
117 | |||
118 | foreach ($properties as $propertyName => $property) { |
||
119 | if (isset($proxy->$propertyName)) { |
||
120 | continue; |
||
121 | } |
||
122 | |||
123 | $proxy->$propertyName = $properties[$propertyName]; |
||
124 | } |
||
125 | |||
126 | $proxy->__setInitialized(true); |
||
127 | $proxy->__wakeup(); |
||
0 ignored issues
–
show
The method
__wakeup() does not seem to exist on object<Doctrine\Common\Proxy\Proxy> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||
128 | |||
129 | $id = $reflectionId->getValue($proxy); |
||
130 | |||
131 | if ($documentPersister->load(['_id' => $id], $proxy) === null) { |
||
132 | if (! $this->lifecycleEventManager->documentNotFound($proxy, $id)) { |
||
0 ignored issues
–
show
The method
documentNotFound() does not seem to exist on object<Doctrine\Common\EventManager> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||
133 | throw DocumentNotFoundException::documentNotFound(get_class($proxy), $id); |
||
134 | } |
||
135 | } |
||
136 | |||
137 | if (! ($proxy instanceof NotifyPropertyChanged)) { |
||
138 | return; |
||
139 | } |
||
140 | |||
141 | $proxy->addPropertyChangedListener($this->uow); |
||
142 | }; |
||
143 | } |
||
144 | |||
145 | View Code Duplication | return function (BaseProxy $proxy) use ($documentPersister, $reflectionId) { |
|
146 | 35 | $proxy->__setInitializer(null); |
|
147 | 35 | $proxy->__setCloner(null); |
|
148 | |||
149 | 35 | if ($proxy->__isInitialized()) { |
|
150 | return; |
||
151 | } |
||
152 | |||
153 | 35 | $properties = $proxy->__getLazyProperties(); |
|
154 | |||
155 | 35 | foreach ($properties as $propertyName => $property) { |
|
156 | 12 | if (isset($proxy->$propertyName)) { |
|
157 | continue; |
||
158 | } |
||
159 | |||
160 | 12 | $proxy->$propertyName = $properties[$propertyName]; |
|
161 | } |
||
162 | |||
163 | 35 | $proxy->__setInitialized(true); |
|
164 | |||
165 | 35 | $id = $reflectionId->getValue($proxy); |
|
166 | |||
167 | 35 | if ($documentPersister->load(['_id' => $id], $proxy) === null) { |
|
168 | 9 | if (! $this->lifecycleEventManager->documentNotFound($proxy, $id)) { |
|
0 ignored issues
–
show
The method
documentNotFound() does not seem to exist on object<Doctrine\Common\EventManager> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||
169 | 8 | throw DocumentNotFoundException::documentNotFound(get_class($proxy), $id); |
|
170 | } |
||
171 | } |
||
172 | |||
173 | 29 | if (! ($proxy instanceof NotifyPropertyChanged)) { |
|
174 | 28 | return; |
|
175 | } |
||
176 | |||
177 | 1 | $proxy->addPropertyChangedListener($this->uow); |
|
178 | 104 | }; |
|
179 | } |
||
180 | |||
181 | /** |
||
182 | * Generates a closure capable of finalizing a cloned proxy |
||
183 | * |
||
184 | * |
||
185 | * @return \Closure |
||
186 | * |
||
187 | * @throws DocumentNotFoundException |
||
188 | */ |
||
189 | 104 | private function createCloner( |
|
190 | BaseClassMetadata $classMetadata, |
||
191 | DocumentPersister $documentPersister, |
||
192 | ReflectionProperty $reflectionId |
||
193 | ) { |
||
194 | return function (BaseProxy $proxy) use ($documentPersister, $classMetadata, $reflectionId) { |
||
195 | if ($proxy->__isInitialized()) { |
||
196 | return; |
||
197 | } |
||
198 | |||
199 | $proxy->__setInitialized(true); |
||
200 | $proxy->__setInitializer(null); |
||
201 | |||
202 | $id = $reflectionId->getValue($proxy); |
||
203 | $original = $documentPersister->load(['_id' => $id]); |
||
204 | |||
205 | if ($original === null) { |
||
206 | if (! $this->lifecycleEventManager->documentNotFound($proxy, $id)) { |
||
0 ignored issues
–
show
The method
documentNotFound() does not seem to exist on object<Doctrine\Common\EventManager> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||
207 | throw DocumentNotFoundException::documentNotFound(get_class($proxy), $id); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | foreach ($classMetadata->getReflectionClass()->getProperties() as $reflectionProperty) { |
||
212 | $propertyName = $reflectionProperty->getName(); |
||
213 | |||
214 | if (! $classMetadata->hasField($propertyName) && ! $classMetadata->hasAssociation($propertyName)) { |
||
215 | continue; |
||
216 | } |
||
217 | |||
218 | $reflectionProperty->setAccessible(true); |
||
219 | $reflectionProperty->setValue($proxy, $reflectionProperty->getValue($original)); |
||
220 | } |
||
221 | 104 | }; |
|
222 | } |
||
223 | } |
||
224 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.