6
6
7
7
use Doctrine \Common \Annotations \AnnotationReader ;
8
8
use Doctrine \Common \Annotations \Reader ;
9
- use Doctrine \ODM \MongoDB \Events ;
10
- use Doctrine \ODM \MongoDB \Mapping \Annotations as ODM ;
11
- use Doctrine \ODM \MongoDB \Mapping \Annotations \AbstractIndex ;
12
- use Doctrine \ODM \MongoDB \Mapping \Annotations \ShardKey ;
13
- use Doctrine \ODM \MongoDB \Mapping \ClassMetadata ;
14
- use Doctrine \ODM \MongoDB \Mapping \MappingException ;
15
- use Doctrine \Persistence \Mapping \Driver \ColocatedMappingDriver ;
16
- use Doctrine \Persistence \Mapping \Driver \MappingDriver ;
17
- use MongoDB \Driver \Exception \UnexpectedValueException ;
18
- use ReflectionClass ;
19
- use ReflectionMethod ;
20
-
21
- use function array_merge ;
22
- use function array_replace ;
23
- use function assert ;
24
- use function class_exists ;
25
- use function constant ;
26
- use function count ;
27
- use function interface_exists ;
28
- use function is_array ;
29
- use function MongoDB \BSON \fromJSON ;
30
- use function MongoDB \BSON \toPHP ;
31
- use function trigger_deprecation ;
32
9
33
10
/**
34
11
* The AnnotationDriver reads the mapping metadata from docblock annotations.
35
12
*/
36
- class AnnotationDriver implements MappingDriver
13
+ class AnnotationDriver extends AttributeDriver
37
14
{
38
- use ColocatedMappingDriver;
39
-
40
15
/**
41
16
* The annotation reader.
42
17
*
@@ -60,323 +35,6 @@ public function __construct($reader, $paths = null)
60
35
$ this ->addPaths ((array ) $ paths );
61
36
}
62
37
63
- public function isTransient ($ className )
64
- {
65
- $ classAnnotations = $ this ->reader ->getClassAnnotations (new ReflectionClass ($ className ));
66
-
67
- foreach ($ classAnnotations as $ annot ) {
68
- if ($ annot instanceof ODM \AbstractDocument) {
69
- return false ;
70
- }
71
- }
72
-
73
- return true ;
74
- }
75
-
76
- public function loadMetadataForClass ($ className , \Doctrine \Persistence \Mapping \ClassMetadata $ metadata ): void
77
- {
78
- assert ($ metadata instanceof ClassMetadata);
79
- $ reflClass = $ metadata ->getReflectionClass ();
80
-
81
- $ classAnnotations = $ this ->reader ->getClassAnnotations ($ reflClass );
82
-
83
- $ documentAnnot = null ;
84
- foreach ($ classAnnotations as $ annot ) {
85
- $ classAnnotations [$ annot ::class] = $ annot ;
86
-
87
- if ($ annot instanceof ODM \AbstractDocument) {
88
- if ($ documentAnnot !== null ) {
89
- throw MappingException::classCanOnlyBeMappedByOneAbstractDocument ($ className , $ documentAnnot , $ annot );
90
- }
91
-
92
- $ documentAnnot = $ annot ;
93
- }
94
-
95
- // non-document class annotations
96
- if ($ annot instanceof ODM \AbstractIndex) {
97
- $ this ->addIndex ($ metadata , $ annot );
98
- }
99
-
100
- if ($ annot instanceof ODM \Indexes) {
101
- trigger_deprecation (
102
- 'doctrine/mongodb-odm ' ,
103
- '2.2 ' ,
104
- 'The "@Indexes" annotation used in class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" annotations on the class. ' ,
105
- $ className ,
106
- );
107
- $ value = $ annot ->value ;
108
- foreach (is_array ($ value ) ? $ value : [$ value ] as $ index ) {
109
- $ this ->addIndex ($ metadata , $ index );
110
- }
111
- } elseif ($ annot instanceof ODM \InheritanceType) {
112
- $ metadata ->setInheritanceType (constant (ClassMetadata::class . '::INHERITANCE_TYPE_ ' . $ annot ->value ));
113
- } elseif ($ annot instanceof ODM \DiscriminatorField) {
114
- $ metadata ->setDiscriminatorField ($ annot ->value );
115
- } elseif ($ annot instanceof ODM \DiscriminatorMap) {
116
- $ value = $ annot ->value ;
117
- assert (is_array ($ value ));
118
- $ metadata ->setDiscriminatorMap ($ value );
119
- } elseif ($ annot instanceof ODM \DiscriminatorValue) {
120
- $ metadata ->setDiscriminatorValue ($ annot ->value );
121
- } elseif ($ annot instanceof ODM \ChangeTrackingPolicy) {
122
- $ metadata ->setChangeTrackingPolicy (constant (ClassMetadata::class . '::CHANGETRACKING_ ' . $ annot ->value ));
123
- } elseif ($ annot instanceof ODM \DefaultDiscriminatorValue) {
124
- $ metadata ->setDefaultDiscriminatorValue ($ annot ->value );
125
- } elseif ($ annot instanceof ODM \ReadPreference) {
126
- $ metadata ->setReadPreference ($ annot ->value , $ annot ->tags ?? []);
127
- } elseif ($ annot instanceof ODM \Validation) {
128
- if (isset ($ annot ->validator )) {
129
- try {
130
- $ validatorBson = fromJSON ($ annot ->validator );
131
- } catch (UnexpectedValueException $ e ) {
132
- throw MappingException::schemaValidationError ($ e ->getCode (), $ e ->getMessage (), $ className , 'validator ' );
133
- }
134
-
135
- $ validator = toPHP ($ validatorBson , []);
136
- $ metadata ->setValidator ($ validator );
137
- }
138
-
139
- if (isset ($ annot ->action )) {
140
- $ metadata ->setValidationAction ($ annot ->action );
141
- }
142
-
143
- if (isset ($ annot ->level )) {
144
- $ metadata ->setValidationLevel ($ annot ->level );
145
- }
146
- }
147
- }
148
-
149
- if ($ documentAnnot === null ) {
150
- throw MappingException::classIsNotAValidDocument ($ className );
151
- }
152
-
153
- if ($ documentAnnot instanceof ODM \MappedSuperclass) {
154
- $ metadata ->isMappedSuperclass = true ;
155
- } elseif ($ documentAnnot instanceof ODM \EmbeddedDocument) {
156
- $ metadata ->isEmbeddedDocument = true ;
157
- } elseif ($ documentAnnot instanceof ODM \QueryResultDocument) {
158
- $ metadata ->isQueryResultDocument = true ;
159
- } elseif ($ documentAnnot instanceof ODM \View) {
160
- if (! $ documentAnnot ->rootClass ) {
161
- throw MappingException::viewWithoutRootClass ($ className );
162
- }
163
-
164
- if (! class_exists ($ documentAnnot ->rootClass )) {
165
- throw MappingException::viewRootClassNotFound ($ className , $ documentAnnot ->rootClass );
166
- }
167
-
168
- $ metadata ->markViewOf ($ documentAnnot ->rootClass );
169
- } elseif ($ documentAnnot instanceof ODM \File) {
170
- $ metadata ->isFile = true ;
171
-
172
- if ($ documentAnnot ->chunkSizeBytes !== null ) {
173
- $ metadata ->setChunkSizeBytes ($ documentAnnot ->chunkSizeBytes );
174
- }
175
- }
176
-
177
- if (isset ($ documentAnnot ->db )) {
178
- $ metadata ->setDatabase ($ documentAnnot ->db );
179
- }
180
-
181
- if (isset ($ documentAnnot ->collection )) {
182
- $ metadata ->setCollection ($ documentAnnot ->collection );
183
- }
184
-
185
- if (isset ($ documentAnnot ->view )) {
186
- $ metadata ->setCollection ($ documentAnnot ->view );
187
- }
188
-
189
- // Store bucketName as collection name for GridFS files
190
- if (isset ($ documentAnnot ->bucketName )) {
191
- $ metadata ->setBucketName ($ documentAnnot ->bucketName );
192
- }
193
-
194
- if (isset ($ documentAnnot ->repositoryClass )) {
195
- $ metadata ->setCustomRepositoryClass ($ documentAnnot ->repositoryClass );
196
- }
197
-
198
- if (isset ($ documentAnnot ->writeConcern )) {
199
- $ metadata ->setWriteConcern ($ documentAnnot ->writeConcern );
200
- }
201
-
202
- if (isset ($ documentAnnot ->indexes ) && count ($ documentAnnot ->indexes )) {
203
- trigger_deprecation (
204
- 'doctrine/mongodb-odm ' ,
205
- '2.2 ' ,
206
- 'The "indexes" parameter in the "%s" annotation for class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" annotations on the class. ' ,
207
- $ className ,
208
- $ documentAnnot ::class,
209
- );
210
-
211
- foreach ($ documentAnnot ->indexes as $ index ) {
212
- $ this ->addIndex ($ metadata , $ index );
213
- }
214
- }
215
-
216
- if (! empty ($ documentAnnot ->readOnly )) {
217
- $ metadata ->markReadOnly ();
218
- }
219
-
220
- foreach ($ reflClass ->getProperties () as $ property ) {
221
- if (
222
- ($ metadata ->isMappedSuperclass && ! $ property ->isPrivate ())
223
- ||
224
- ($ metadata ->isInheritedField ($ property ->name ) && $ property ->getDeclaringClass ()->name !== $ metadata ->name )
225
- ) {
226
- continue ;
227
- }
228
-
229
- $ indexes = [];
230
- $ mapping = ['fieldName ' => $ property ->getName ()];
231
- $ fieldAnnot = null ;
232
-
233
- foreach ($ this ->reader ->getPropertyAnnotations ($ property ) as $ annot ) {
234
- if ($ annot instanceof ODM \AbstractField) {
235
- $ fieldAnnot = $ annot ;
236
- }
237
-
238
- if ($ annot instanceof ODM \AbstractIndex) {
239
- $ indexes [] = $ annot ;
240
- }
241
-
242
- if ($ annot instanceof ODM \Indexes) {
243
- $ value = $ annot ->value ;
244
- foreach (is_array ($ value ) ? $ value : [$ value ] as $ index ) {
245
- $ indexes [] = $ index ;
246
- }
247
- } elseif ($ annot instanceof ODM \AlsoLoad) {
248
- $ mapping ['alsoLoadFields ' ] = (array ) $ annot ->value ;
249
- } elseif ($ annot instanceof ODM \Version) {
250
- $ mapping ['version ' ] = true ;
251
- } elseif ($ annot instanceof ODM \Lock) {
252
- $ mapping ['lock ' ] = true ;
253
- }
254
- }
255
-
256
- if ($ fieldAnnot ) {
257
- $ mapping = array_replace ($ mapping , (array ) $ fieldAnnot );
258
- $ metadata ->mapField ($ mapping );
259
- }
260
-
261
- if (! $ indexes ) {
262
- continue ;
263
- }
264
-
265
- foreach ($ indexes as $ index ) {
266
- $ name = $ mapping ['name ' ] ?? $ mapping ['fieldName ' ];
267
- $ keys = [$ name => $ index ->order ?: 'asc ' ];
268
- $ this ->addIndex ($ metadata , $ index , $ keys );
269
- }
270
- }
271
-
272
- // Set shard key after all fields to ensure we mapped all its keys
273
- if (isset ($ classAnnotations [ShardKey::class])) {
274
- assert ($ classAnnotations [ShardKey::class] instanceof ShardKey);
275
- $ this ->setShardKey ($ metadata , $ classAnnotations [ShardKey::class]);
276
- }
277
-
278
- foreach ($ reflClass ->getMethods (ReflectionMethod::IS_PUBLIC ) as $ method ) {
279
- /* Filter for the declaring class only. Callbacks from parent
280
- * classes will already be registered.
281
- */
282
- if ($ method ->getDeclaringClass ()->name !== $ reflClass ->name ) {
283
- continue ;
284
- }
285
-
286
- foreach ($ this ->reader ->getMethodAnnotations ($ method ) as $ annot ) {
287
- if ($ annot instanceof ODM \AlsoLoad) {
288
- $ metadata ->registerAlsoLoadMethod ($ method ->getName (), $ annot ->value );
289
- }
290
-
291
- if (! isset ($ classAnnotations [ODM \HasLifecycleCallbacks::class])) {
292
- continue ;
293
- }
294
-
295
- if ($ annot instanceof ODM \PrePersist) {
296
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::prePersist);
297
- } elseif ($ annot instanceof ODM \PostPersist) {
298
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::postPersist);
299
- } elseif ($ annot instanceof ODM \PreUpdate) {
300
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::preUpdate);
301
- } elseif ($ annot instanceof ODM \PostUpdate) {
302
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::postUpdate);
303
- } elseif ($ annot instanceof ODM \PreRemove) {
304
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::preRemove);
305
- } elseif ($ annot instanceof ODM \PostRemove) {
306
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::postRemove);
307
- } elseif ($ annot instanceof ODM \PreLoad) {
308
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::preLoad);
309
- } elseif ($ annot instanceof ODM \PostLoad) {
310
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::postLoad);
311
- } elseif ($ annot instanceof ODM \PreFlush) {
312
- $ metadata ->addLifecycleCallback ($ method ->getName (), Events::preFlush);
313
- }
314
- }
315
- }
316
- }
317
-
318
- /**
319
- * @param ClassMetadata<object> $class
320
- * @param array<string, int|string> $keys
321
- */
322
- private function addIndex (ClassMetadata $ class , AbstractIndex $ index , array $ keys = []): void
323
- {
324
- $ keys = array_merge ($ keys , $ index ->keys );
325
- $ options = [];
326
- $ allowed = ['name ' , 'background ' , 'unique ' , 'sparse ' , 'expireAfterSeconds ' ];
327
- foreach ($ allowed as $ name ) {
328
- if (! isset ($ index ->$ name )) {
329
- continue ;
330
- }
331
-
332
- $ options [$ name ] = $ index ->$ name ;
333
- }
334
-
335
- if (! empty ($ index ->partialFilterExpression )) {
336
- $ options ['partialFilterExpression ' ] = $ index ->partialFilterExpression ;
337
- }
338
-
339
- $ options = array_merge ($ options , $ index ->options );
340
- $ class ->addIndex ($ keys , $ options );
341
- }
342
-
343
- /**
344
- * @param ClassMetadata<object> $class
345
- *
346
- * @throws MappingException
347
- */
348
- private function setShardKey (ClassMetadata $ class , ODM \ShardKey $ shardKey ): void
349
- {
350
- $ options = [];
351
- $ allowed = ['unique ' , 'numInitialChunks ' ];
352
- foreach ($ allowed as $ name ) {
353
- if (! isset ($ shardKey ->$ name )) {
354
- continue ;
355
- }
356
-
357
- $ options [$ name ] = $ shardKey ->$ name ;
358
- }
359
-
360
- $ class ->setShardKey ($ shardKey ->keys , $ options );
361
- }
362
-
363
- /**
364
- * Retrieve the current annotation reader
365
- *
366
- * @return Reader
367
- */
368
- public function getReader ()
369
- {
370
- trigger_deprecation (
371
- 'doctrine/mongodb-odm ' ,
372
- '2.4 ' ,
373
- '%s is deprecated with no replacement ' ,
374
- __METHOD__ ,
375
- );
376
-
377
- return $ this ->reader ;
378
- }
379
-
380
38
/**
381
39
* Factory method for the Annotation Driver
382
40
*
@@ -387,5 +45,3 @@ public static function create($paths = [], ?Reader $reader = null): AnnotationDr
387
45
return new self ($ reader ?? new AnnotationReader (), $ paths );
388
46
}
389
47
}
390
-
391
- interface_exists (\Doctrine \Persistence \Mapping \ClassMetadata::class);
0 commit comments