Completed
Push — master ( 785c50...2c0a7f )
by Maciej
16s
created

DocumentGenerator   D

Complexity

Total Complexity 217

Size/Duplication

Total Lines 980
Duplicated Lines 6.94 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 81.36%

Importance

Changes 0
Metric Value
wmc 217
lcom 1
cbo 3
dl 68
loc 980
ccs 358
cts 440
cp 0.8136
rs 4
c 0
b 0
f 0

46 Methods

Rating   Name   Duplication   Size   Complexity  
A setBackupExisting() 0 4 1
A generateDocumentNamespace() 0 6 2
A generateDocumentClassName() 0 5 2
A hasNamespace() 0 4 2
A extendsClass() 0 4 2
A getClassToExtend() 0 4 1
A getClassToExtendName() 0 6 1
A getClassName() 0 5 2
A generateDocumentImports() 0 6 2
A generate() 0 6 2
C writeDocumentClass() 0 32 11
A generateDocumentClass() 0 21 1
A generateUpdatedDocumentClass() 0 10 2
A setNumSpaces() 0 5 1
A setExtension() 0 4 1
A setClassToExtend() 0 4 1
A setGenerateAnnotations() 0 4 1
A setUpdateDocumentIfExists() 0 4 1
A setRegenerateDocumentIfExists() 0 4 1
A setGenerateStubMethods() 0 4 1
B generateDocumentBody() 0 29 6
B generateDocumentConstructor() 0 17 5
C hasProperty() 22 22 8
C hasMethod() 22 22 8
A getNamespace() 0 4 1
B getTraits() 0 13 5
A generateInheritanceAnnotation() 0 6 2
A generateDiscriminatorFieldAnnotation() 0 6 2
A generateDiscriminatorMapAnnotation() 0 12 3
A generateDefaultDiscriminatorValueAnnotation() 0 6 3
A generateChangeTrackingPolicyAnnotation() 0 4 1
D generateDocumentStubMethods() 12 44 21
A isAssociationNullable() 0 4 2
B generateDocumentLifecycleCallbackMethods() 0 18 5
B generateDocumentAssociationMappingProperties() 0 20 6
B generateDocumentFieldMappingProperties() 0 20 7
F generateAssociationMappingPropertyDocBlock() 0 49 15
D generateFieldMappingPropertyDocBlock() 6 61 20
A prefixCodeWithSpaces() 0 10 2
A getInheritanceTypeString() 0 16 4
A getChangeTrackingPolicyString() 0 16 4
C getIdGeneratorTypeString() 0 25 7
D generateDocumentDocBlock() 6 77 18
C parseTokensInDocumentFile() 0 33 14
C generateDocumentStubMethod() 0 40 7
A generateLifecycleCallbackMethod() 0 19 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DocumentGenerator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DocumentGenerator, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ODM\MongoDB\Tools;
21
22
use Doctrine\Common\Inflector\Inflector;
23
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
24
use Doctrine\ODM\MongoDB\Types\Type;
25
26
/**
27
 * Generic class used to generate PHP5 document classes from ClassMetadataInfo instances
28
 *
29
 *     [php]
30
 *     $classes = $dm->getClassMetadataInfoFactory()->getAllMetadata();
31
 *
32
 *     $generator = new \Doctrine\ODM\MongoDB\Tools\DocumentGenerator();
33
 *     $generator->setGenerateAnnotations(true);
34
 *     $generator->setGenerateStubMethods(true);
35
 *     $generator->setRegenerateDocumentIfExists(false);
36
 *     $generator->setUpdateDocumentIfExists(true);
37
 *     $generator->generate($classes, '/path/to/generate/documents');
38
 *
39
 * @since   1.0
40
 */
41
class DocumentGenerator
42
{
43
    /**
44
     * @var bool
45
     */
46
    private $backupExisting = true;
47
48
    /** The extension to use for written php files */
49
    private $extension = '.php';
50
51
    /** Whether or not the current ClassMetadataInfo instance is new or old */
52
    private $isNew = true;
53
54
    private $staticReflection = array();
55
56
    /** Number of spaces to use for indention in generated code */
57
    private $numSpaces = 4;
58
59
    /** The actual spaces to use for indention */
60
    private $spaces = '    ';
61
62
    /** The class all generated documents should extend */
63
    private $classToExtend;
64
65
    /** Whether or not to generate annotations */
66
    private $generateAnnotations = false;
67
68
    /** Whether or not to generate stub methods */
69
    private $generateDocumentStubMethods = false;
70
71
    /** Whether or not to update the document class if it exists already */
72
    private $updateDocumentIfExists = false;
73
74
    /** Whether or not to re-generate document class if it exists already */
75
    private $regenerateDocumentIfExists = false;
76
77
    private static $classTemplate =
78
'<?php
79
80
<namespace>
81
82
<imports>
83
84
<documentAnnotation>
85
<documentClassName>
86
{
87
<documentBody>
88
}
89
';
90
91
    private static $getMethodTemplate =
92
'/**
93
 * <description>
94
 *
95
 * @return <variableType>$<variableName>
96
 */
97
public function <methodName>()
98
{
99
<spaces>return $this-><fieldName>;
100
}';
101
102
    private static $setMethodTemplate =
103
'/**
104
 * <description>
105
 *
106
 * @param <variableType>$<variableName>
107
 * @return $this
108
 */
109
public function <methodName>(<methodTypeHint>$<variableName><variableDefault>)
110
{
111
<spaces>$this-><fieldName> = $<variableName>;
112
<spaces>return $this;
113
}';
114
115
    private static $addMethodTemplate =
116
'/**
117
 * <description>
118
 *
119
 * @param <variableType>$<variableName>
120
 */
121
public function <methodName>(<methodTypeHint>$<variableName>)
122
{
123
<spaces>$this-><fieldName>[] = $<variableName>;
124
}';
125
126
    private static $removeMethodTemplate =
127
'/**
128
 * <description>
129
 *
130
 * @param <variableType>$<variableName>
131
 */
132
public function <methodName>(<methodTypeHint>$<variableName>)
133
{
134
<spaces>$this-><fieldName>->removeElement($<variableName>);
135
}';
136
137
    private static $lifecycleCallbackMethodTemplate =
138
'<comment>
139
public function <methodName>()
140
{
141
<spaces>// Add your code here
142
}';
143
144
    private static $constructorMethodTemplate =
145
'public function __construct()
146
{
147
<collections>
148
}
149
';
150
151
    /**
152
     * Generate and write document classes for the given array of ClassMetadataInfo instances
153
     *
154
     * @param array $metadatas
155
     * @param string $outputDirectory
156
     * @return void
157
     */
158
    public function generate(array $metadatas, $outputDirectory)
159
    {
160
        foreach ($metadatas as $metadata) {
161
            $this->writeDocumentClass($metadata, $outputDirectory);
162
        }
163
    }
164
165
    /**
166
     * Generated and write document class to disk for the given ClassMetadataInfo instance
167
     *
168
     * @param ClassMetadataInfo $metadata
169
     * @param string $outputDirectory
170
     * @throws \RuntimeException
171
     * @return void
172
     */
173 9
    public function writeDocumentClass(ClassMetadataInfo $metadata, $outputDirectory)
174
    {
175 9
        $path = $outputDirectory . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->extension;
176 9
        $dir = dirname($path);
177
178 9
        if ( ! is_dir($dir)) {
179
            mkdir($dir, 0775, true);
180
        }
181
182 9
        $this->isNew = ! file_exists($path) || (file_exists($path) && $this->regenerateDocumentIfExists);
183
184 9
        if ( ! $this->isNew) {
185 2
            $this->parseTokensInDocumentFile($path);
186
        }
187
188 9
        if ($this->backupExisting && file_exists($path)) {
189 2
            $backupPath = dirname($path) . DIRECTORY_SEPARATOR . basename($path) . '~';
190 2
            if ( ! copy($path, $backupPath)) {
191
                throw new \RuntimeException('Attempt to backup overwritten document file but copy operation failed.');
192
            }
193
        }
194
195
        // If document doesn't exist or we're re-generating the documents entirely
196 9
        if ($this->isNew) {
197 8
            file_put_contents($path, $this->generateDocumentClass($metadata));
198
199
        // If document exists and we're allowed to update the document class
200 2
        } elseif ( ! $this->isNew && $this->updateDocumentIfExists) {
201 2
            file_put_contents($path, $this->generateUpdatedDocumentClass($metadata, $path));
202
        }
203 9
        chmod($path, 0664);
204 9
    }
205
206
    /**
207
     * Generate a PHP5 Doctrine 2 document class from the given ClassMetadataInfo instance
208
     *
209
     * @param ClassMetadataInfo $metadata
210
     * @return string $code
211
     */
212 8
    public function generateDocumentClass(ClassMetadataInfo $metadata)
213
    {
214
        $placeHolders = array(
215 8
            '<namespace>',
216
            '<imports>',
217
            '<documentAnnotation>',
218
            '<documentClassName>',
219
            '<documentBody>'
220
        );
221
222
        $replacements = array(
223 8
            $this->generateDocumentNamespace($metadata),
224 8
            $this->generateDocumentImports(),
225 8
            $this->generateDocumentDocBlock($metadata),
226 8
            $this->generateDocumentClassName($metadata),
227 8
            $this->generateDocumentBody($metadata)
228
        );
229
230 8
        $code = str_replace($placeHolders, $replacements, self::$classTemplate);
231 8
        return str_replace('<spaces>', $this->spaces, $code);
232
    }
233
234
    /**
235
     * Generate the updated code for the given ClassMetadataInfo and document at path
236
     *
237
     * @param ClassMetadataInfo $metadata
238
     * @param string $path
239
     * @return string $code;
240
     */
241 2
    public function generateUpdatedDocumentClass(ClassMetadataInfo $metadata, $path)
242
    {
243 2
        $currentCode = file_get_contents($path);
244
245 2
        $body = $this->generateDocumentBody($metadata);
246 2
        $body = str_replace('<spaces>', $this->spaces, $body);
247 2
        $last = strrpos($currentCode, '}');
248
249 2
        return substr($currentCode, 0, $last) . $body . (strlen($body) > 0 ? "\n" : '') . "}\n";
250
    }
251
252
    /**
253
     * Set the number of spaces the exported class should have
254
     *
255
     * @param integer $numSpaces
256
     * @return void
257
     */
258
    public function setNumSpaces($numSpaces)
259
    {
260
        $this->spaces = str_repeat(' ', $numSpaces);
261
        $this->numSpaces = $numSpaces;
262
    }
263
264
    /**
265
     * Set the extension to use when writing php files to disk
266
     *
267
     * @param string $extension
268
     * @return void
269
     */
270
    public function setExtension($extension)
271
    {
272
        $this->extension = $extension;
273
    }
274
275
    /**
276
     * Set the name of the class the generated classes should extend from
277
     *
278
     * @param string $classToExtend Class name.
279
     * @return void
280
     */
281 1
    public function setClassToExtend($classToExtend)
282
    {
283 1
        $this->classToExtend = $classToExtend;
284 1
    }
285
286
    /**
287
     * Set whether or not to generate annotations for the document
288
     *
289
     * @param bool $bool
290
     * @return void
291
     */
292 9
    public function setGenerateAnnotations($bool)
293
    {
294 9
        $this->generateAnnotations = $bool;
295 9
    }
296
297
    /**
298
     * Set whether or not to try and update the document if it already exists
299
     *
300
     * @param bool $bool
301
     * @return void
302
     */
303 9
    public function setUpdateDocumentIfExists($bool)
304
    {
305 9
        $this->updateDocumentIfExists = $bool;
306 9
    }
307
308
    /**
309
     * Set whether or not to regenerate the document if it exists
310
     *
311
     * @param bool $bool
312
     * @return void
313
     */
314 9
    public function setRegenerateDocumentIfExists($bool)
315
    {
316 9
        $this->regenerateDocumentIfExists = $bool;
317 9
    }
318
319
    /**
320
     * Set whether or not to generate stub methods for the document
321
     *
322
     * @param bool $bool
323
     * @return void
324
     */
325 9
    public function setGenerateStubMethods($bool)
326
    {
327 9
        $this->generateDocumentStubMethods = $bool;
328 9
    }
329
330
    /**
331
     * Sets a value indicating whether existing documents will be backed up.
332
     *
333
     * @param bool $bool True to backup existing document, false to overwrite.
334
     */
335
    public function setBackupExisting($bool)
336
    {
337
        $this->backupExisting = $bool;
338
    }
339
340 8
    private function generateDocumentNamespace(ClassMetadataInfo $metadata)
341
    {
342 8
        if ($this->hasNamespace($metadata)) {
343 8
            return 'namespace ' . $this->getNamespace($metadata) . ';';
344
        }
345
    }
346
347 8
    private function generateDocumentClassName(ClassMetadataInfo $metadata)
348
    {
349 8
        return 'class ' . $this->getClassName($metadata) .
350 8
            ($this->extendsClass() ? ' extends ' . $this->getClassToExtendName() : null);
351
    }
352
353 9
    private function generateDocumentBody(ClassMetadataInfo $metadata)
354
    {
355 9
        $fieldMappingProperties = $this->generateDocumentFieldMappingProperties($metadata);
356 9
        $associationMappingProperties = $this->generateDocumentAssociationMappingProperties($metadata);
357 9
        $stubMethods = $this->generateDocumentStubMethods ? $this->generateDocumentStubMethods($metadata) : null;
358 9
        $lifecycleCallbackMethods = $this->generateDocumentLifecycleCallbackMethods($metadata);
359
360 9
        $code = array();
361
362 9
        if ($fieldMappingProperties) {
363 7
            $code[] = $fieldMappingProperties;
364
        }
365
366 9
        if ($associationMappingProperties) {
367 6
            $code[] = $associationMappingProperties;
368
        }
369
370 9
        $code[] = $this->generateDocumentConstructor($metadata);
371
372 9
        if ($stubMethods) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $stubMethods of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
373 9
            $code[] = $stubMethods;
374
        }
375
376 9
        if ($lifecycleCallbackMethods) {
377 6
            $code[] = "\n" . $lifecycleCallbackMethods;
378
        }
379
380 9
        return implode("\n", $code);
381
    }
382
383 9
    private function generateDocumentConstructor(ClassMetadataInfo $metadata)
384
    {
385 9
        if ($this->hasMethod('__construct', $metadata)) {
386 1
            return '';
387
        }
388
389 9
        $collections = array();
390 9
        foreach ($metadata->fieldMappings AS $mapping) {
391 9
            if ($mapping['type'] === ClassMetadataInfo::MANY) {
392 6
                $collections[] = '$this->' . $mapping['fieldName'] . ' = new \Doctrine\Common\Collections\ArrayCollection();';
393
            }
394
        }
395 9
        if ($collections) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $collections of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
396 6
            return $this->prefixCodeWithSpaces(str_replace('<collections>', $this->spaces . implode("\n" . $this->spaces, $collections), self::$constructorMethodTemplate));
397
        }
398 3
        return '';
399
    }
400
401
    /**
402
     * @todo this won't work if there is a namespace in brackets and a class outside of it.
403
     * @param string $path
404
     */
405 2
    private function parseTokensInDocumentFile($path)
406
    {
407 2
        $tokens = token_get_all(file_get_contents($path));
408 2
        $lastSeenNamespace = '';
409 2
        $lastSeenClass = false;
410
411 2
        for ($i = 0; $i < count($tokens); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
412 2
            $token = $tokens[$i];
413 2
            if ($token[0] == T_NAMESPACE) {
414 2
                $peek = $i;
415 2
                $lastSeenNamespace = '';
416 2
                while (isset($tokens[++$peek])) {
417 2
                    if (';' == $tokens[$peek]) {
418 2
                        break;
419 2
                    } elseif (is_array($tokens[$peek]) && in_array($tokens[$peek][0], array(T_STRING, T_NS_SEPARATOR))) {
420 2
                        $lastSeenNamespace .= $tokens[$peek][1];
421
                    }
422
                }
423 2
            } elseif ($token[0] == T_CLASS) {
424 2
                $lastSeenClass = $lastSeenNamespace . '\\' . $tokens[$i + 2][1];
425 2
                $this->staticReflection[$lastSeenClass]['properties'] = array();
426 2
                $this->staticReflection[$lastSeenClass]['methods'] = array();
427 2
            } elseif ($token[0] == T_FUNCTION) {
428 1
                if ($tokens[$i + 2][0] == T_STRING) {
429 1
                    $this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i + 2][1];
430
                } elseif ($tokens[$i + 2][0] == '&' && $tokens[$i + 3][0] == T_STRING) {
431
                    $this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i + 3][1];
432
                }
433 2
            } elseif (in_array($token[0], array(T_VAR, T_PUBLIC, T_PRIVATE, T_PROTECTED)) && $tokens[$i + 2][0] != T_FUNCTION) {
434 2
                $this->staticReflection[$lastSeenClass]['properties'][] = substr($tokens[$i + 2][1], 1);
435
            }
436
        }
437 2
    }
438
439 9 View Code Duplication
    private function hasProperty($property, ClassMetadataInfo $metadata)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
440
    {
441 9
        if ($this->extendsClass() || class_exists($metadata->name)) {
442
            // don't generate property if its already on the base class.
443 2
            $reflClass = new \ReflectionClass($this->getClassToExtend() ?: $metadata->name);
444
445 2
            if ($reflClass->hasProperty($property)) {
446 1
                return true;
447
            }
448
        }
449
450 8
        foreach ($this->getTraits($metadata) as $trait) {
451 2
            if ($trait->hasProperty($property)) {
452 2
                return true;
453
            }
454
        }
455
456
        return (
457 8
            isset($this->staticReflection[$metadata->name]) &&
458 8
            in_array($property, $this->staticReflection[$metadata->name]['properties'])
459
        );
460
    }
461
462 9 View Code Duplication
    private function hasMethod($method, ClassMetadataInfo $metadata)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
463
    {
464 9
        if ($this->extendsClass() || class_exists($metadata->name)) {
465
            // don't generate method if its already on the base class.
466 2
            $reflClass = new \ReflectionClass($this->getClassToExtend() ?: $metadata->name);
467
468 2
            if ($reflClass->hasMethod($method)) {
469 1
                return true;
470
            }
471
        }
472
473 9
        foreach ($this->getTraits($metadata) as $trait) {
474 2
            if ($trait->hasMethod($method)) {
475 2
                return true;
476
            }
477
        }
478
479
        return (
480 9
            isset($this->staticReflection[$metadata->name]) &&
481 9
            in_array($method, $this->staticReflection[$metadata->name]['methods'])
482
        );
483
    }
484
485 8
    private function hasNamespace(ClassMetadataInfo $metadata)
486
    {
487 8
        return strpos($metadata->name, '\\') ? true : false;
488
    }
489
490 9
    private function extendsClass()
491
    {
492 9
        return $this->classToExtend ? true : false;
493
    }
494
495 2
    private function getClassToExtend()
496
    {
497 2
        return $this->classToExtend;
498
    }
499
500 1
    private function getClassToExtendName()
501
    {
502 1
        $refl = new \ReflectionClass($this->getClassToExtend());
503
504 1
        return '\\' . $refl->getName();
0 ignored issues
show
Bug introduced by
Consider using $refl->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
505
    }
506
507 8
    private function getClassName(ClassMetadataInfo $metadata)
508
    {
509 8
        return ($pos = strrpos($metadata->name, '\\'))
510 8
            ? substr($metadata->name, $pos + 1, strlen($metadata->name)) : $metadata->name;
511
    }
512
513 8
    private function getNamespace(ClassMetadataInfo $metadata)
514
    {
515 8
        return substr($metadata->name, 0, strrpos($metadata->name, '\\'));
516
    }
517
518
    /**
519
     * @param ClassMetadataInfo $metadata
520
     *
521
     * @return array
522
     */
523 9
    protected function getTraits(ClassMetadataInfo $metadata)
524
    {
525 9
        if ($metadata->reflClass !== null || class_exists($metadata->name)) {
526 3
            $reflClass = $metadata->reflClass === null ? new \ReflectionClass($metadata->name) : $metadata->reflClass;
527 3
            $traits = array();
528 3
            while ($reflClass !== false) {
529 3
                $traits = array_merge($traits, $reflClass->getTraits());
530 3
                $reflClass = $reflClass->getParentClass();
531
            }
532 3
            return $traits;
533
        }
534 6
        return array();
535
    }
536
537 8
    private function generateDocumentImports()
538
    {
539 8
        if ($this->generateAnnotations) {
540 8
            return 'use Doctrine\\ODM\\MongoDB\\Mapping\\Annotations as ODM;';
541
        }
542
    }
543
544 8
    private function generateDocumentDocBlock(ClassMetadataInfo $metadata)
545
    {
546 8
        $lines = array();
547 8
        $lines[] = '/**';
548 8
        $lines[] = ' * ' . $metadata->name;
549
550 8
        if ($this->generateAnnotations) {
551 8
            $lines[] = ' *';
552
553 8
            if ($metadata->isMappedSuperclass) {
554
                $lines[] = ' * @ODM\\MappedSuperclass';
555 8
            } elseif ($metadata->isEmbeddedDocument) {
556
                $lines[] = ' * @ODM\\EmbeddedDocument';
557 8
            } elseif ($metadata->isQueryResultDocument) {
558
                $lines[] = ' * @ODM\\QueryResultDocument';
559
            } else {
560 8
                $lines[] = ' * @ODM\\Document';
561
            }
562
563 8
            $document = array();
564 8
            if ( ! $metadata->isMappedSuperclass && ! $metadata->isEmbeddedDocument && ! $metadata->isQueryResultDocument) {
565 8
                if ($metadata->collection) {
566 8
                    $document[] = ' *     collection="' . $metadata->collection . '"';
567
                }
568 8
                if ($metadata->customRepositoryClassName) {
569 6
                    $document[] = ' *     repositoryClass="' . $metadata->customRepositoryClassName . '"';
570
                }
571
            }
572 8
            if ($metadata->indexes) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $metadata->indexes of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
573
                $indexes = array();
574
                $indexLines = array();
575
                $indexLines[] = ' *     indexes={';
576
                foreach ($metadata->indexes as $index) {
577
                    $keys = array();
578 View Code Duplication
                    foreach ($index['keys'] as $key => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
579
                        $keys[] = '"' . $key . '"="' . $value . '"';
580
                    }
581
                    $options = array();
582 View Code Duplication
                    foreach ($index['options'] as $key => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
583
                        $options[] = '"' . $key . '"="' . $value . '"';
584
                    }
585
                    $indexes[] = '@ODM\\Index(keys={' . implode(', ', $keys) . '}, options={' . implode(', ', $options) . '})';
586
                }
587
                $indexLines[] = "\n *         " . implode(",\n *         ", $indexes);
588
                $indexLines[] = "\n *     }";
589
590
                $document[] = implode(null, $indexLines);
591
            }
592
593 8
            if ($document) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $document of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
594 8
                $lines[count($lines) - 1] .= '(';
595 8
                $lines[] = implode(",\n", $document);
596 8
                $lines[] = ' * )';
597
            }
598
599 8
            if ( ! empty($metadata->lifecycleCallbacks)) {
600 6
                $lines[] = ' * @ODM\HasLifecycleCallbacks';
601
            }
602
603
            $methods = array(
604 8
                'generateInheritanceAnnotation',
605
                'generateDiscriminatorFieldAnnotation',
606
                'generateDiscriminatorMapAnnotation',
607
                'generateDefaultDiscriminatorValueAnnotation',
608
                'generateChangeTrackingPolicyAnnotation'
609
            );
610
611 8
            foreach ($methods as $method) {
612 8
                if ($code = $this->$method($metadata)) {
613 8
                    $lines[] = ' * ' . $code;
614
                }
615
            }
616
        }
617
618 8
        $lines[] = ' */';
619 8
        return implode("\n", $lines);
620
    }
621
622 8
    private function generateInheritanceAnnotation(ClassMetadataInfo $metadata)
623
    {
624 8
        if ($metadata->inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
625
            return '@ODM\\InheritanceType("' . $this->getInheritanceTypeString($metadata->inheritanceType) . '")';
626
        }
627 8
    }
628
629 8
    private function generateDiscriminatorFieldAnnotation(ClassMetadataInfo $metadata)
630
    {
631 8
        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
632
            return '@ODM\\DiscriminatorField(name="' . $metadata->discriminatorField . '")';
633
        }
634 8
    }
635
636 8
    private function generateDiscriminatorMapAnnotation(ClassMetadataInfo $metadata)
637
    {
638 8
        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
639
            $inheritanceClassMap = array();
640
641
            foreach ($metadata->discriminatorMap as $type => $class) {
642
                $inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
643
            }
644
645
            return '@ODM\\DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
646
        }
647 8
    }
648
649 8
    private function generateDefaultDiscriminatorValueAnnotation(ClassMetadataInfo $metadata)
650
    {
651 8
        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION && isset($metadata->defaultDiscriminatorValue)) {
652
            return '@ODM\\DefaultDiscriminatorValue("' . $metadata->defaultDiscriminatorValue . '")';
653
        }
654 8
    }
655
656 8
    private function generateChangeTrackingPolicyAnnotation(ClassMetadataInfo $metadata)
657
    {
658 8
        return '@ODM\\ChangeTrackingPolicy("' . $this->getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . '")';
659
    }
660
661 9
    private function generateDocumentStubMethods(ClassMetadataInfo $metadata)
662
    {
663 9
        $methods = array();
664
665 9
        foreach ($metadata->fieldMappings as $fieldMapping) {
666 9
            if (isset($fieldMapping['id'])) {
667 9
                if ($metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE) {
668
                    if ($code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) {
669
                        $methods[] = $code;
670
                    }
671
                }
672 9
                if ($code = $code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'])) {
673 8
                    $methods[] = $code;
674
                }
675 9
            } elseif ( ! isset($fieldMapping['association'])) {
676 9
                if ($code = $code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) {
677 9
                    $methods[] = $code;
678
                }
679 9
                if ($code = $code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'])) {
680 9
                    $methods[] = $code;
681
                }
682 8
            } elseif ($fieldMapping['type'] === ClassMetadataInfo::ONE) {
683 8
                $nullable = $this->isAssociationNullable($fieldMapping) ? 'null' : null;
684 8 View Code Duplication
                if ($code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], isset($fieldMapping['targetDocument']) ? $fieldMapping['targetDocument'] : null, $nullable)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
685 6
                    $methods[] = $code;
686
                }
687 8 View Code Duplication
                if ($code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], isset($fieldMapping['targetDocument']) ? $fieldMapping['targetDocument'] : null)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
688 6
                    $methods[] = $code;
689
                }
690 6
            } elseif ($fieldMapping['type'] === ClassMetadataInfo::MANY) {
691 6 View Code Duplication
                if ($code = $this->generateDocumentStubMethod($metadata, 'add', $fieldMapping['fieldName'], isset($fieldMapping['targetDocument']) ? $fieldMapping['targetDocument'] : null)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
692 6
                    $methods[] = $code;
693
                }
694 6 View Code Duplication
                if ($code = $this->generateDocumentStubMethod($metadata, 'remove', $fieldMapping['fieldName'], isset($fieldMapping['targetDocument']) ? $fieldMapping['targetDocument'] : null)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
695 6
                    $methods[] = $code;
696
                }
697 6
                if ($code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], '\Doctrine\Common\Collections\Collection')) {
698 6
                    $methods[] = $code;
699
                }
700
            }
701
        }
702
703 9
        return implode("\n\n", $methods);
704
    }
705
706
    /**
707
     * @param array $fieldMapping
708
     *
709
     * @return bool
710
     */
711 8
    protected function isAssociationNullable($fieldMapping)
712
    {
713 8
        return isset($fieldMapping['nullable']) && $fieldMapping['nullable'];
714
    }
715
716 9
    private function generateDocumentLifecycleCallbackMethods(ClassMetadataInfo $metadata)
717
    {
718 9
        if (empty($metadata->lifecycleCallbacks)) {
719 3
            return '';
720
        }
721
722 6
        $methods = array();
723
724 6
        foreach ($metadata->lifecycleCallbacks as $event => $callbacks) {
725 6
            foreach ($callbacks as $callback) {
726 6
                if ($code = $this->generateLifecycleCallbackMethod($event, $callback, $metadata)) {
727 6
                    $methods[] = $code;
728
                }
729
            }
730
        }
731
732 6
        return implode("\n\n", $methods);
733
    }
734
735 9
    private function generateDocumentAssociationMappingProperties(ClassMetadataInfo $metadata)
736
    {
737 9
        $lines = array();
738
739 9
        foreach ($metadata->fieldMappings as $fieldMapping) {
740 9
            if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
741 8
                $metadata->isInheritedField($fieldMapping['fieldName'])) {
742 4
                continue;
743
            }
744 7
            if ( ! isset($fieldMapping['association'])) {
745 7
                continue;
746
            }
747
748 6
            $lines[] = $this->generateAssociationMappingPropertyDocBlock($fieldMapping);
749 6
            $lines[] = $this->spaces . 'protected $' . $fieldMapping['fieldName']
750 6
                . ($fieldMapping['type'] === ClassMetadataInfo::MANY ? ' = array()' : null) . ";\n";
751
        }
752
753 9
        return implode("\n", $lines);
754
    }
755
756 9
    private function generateDocumentFieldMappingProperties(ClassMetadataInfo $metadata)
757
    {
758 9
        $lines = array();
759
760 9
        foreach ($metadata->fieldMappings as $fieldMapping) {
761 9
            if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
762 8
                $metadata->isInheritedField($fieldMapping['fieldName'])) {
763 4
                continue;
764
            }
765 7
            if (isset($fieldMapping['association']) && $fieldMapping['association']) {
766 6
                continue;
767
            }
768
769 7
            $lines[] = $this->generateFieldMappingPropertyDocBlock($fieldMapping, $metadata);
770 7
            $lines[] = $this->spaces . 'protected $' . $fieldMapping['fieldName']
771 7
                . (isset($fieldMapping['default']) ? ' = ' . var_export($fieldMapping['default'], true) : null) . ";\n";
772
        }
773
774 9
        return implode("\n", $lines);
775
    }
776
777 9
    private function generateDocumentStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null)
778
    {
779
        // Add/remove methods should use the singular form of the field name
780 9
        $formattedFieldName = in_array($type, array('add', 'remove'))
781 6
            ? Inflector::singularize($fieldName)
782 9
            : $fieldName;
783
784 9
        $methodName = $type . Inflector::classify($formattedFieldName);
785 9
        $variableName = Inflector::camelize($formattedFieldName);
786
787 9
        if ($this->hasMethod($methodName, $metadata)) {
788 4
            return;
789
        }
790
791 9
        $description = ucfirst($type) . ' ' . $variableName;
792
793 9
        $types = Type::getTypesMap();
794 9
        $methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null;
795 9
        $variableType = $typeHint ? $typeHint . ' ' : null;
796
797
        $replacements = array(
798 9
            '<description>'         => $description,
799 9
            '<methodTypeHint>'      => $methodTypeHint,
800 9
            '<variableType>'        => $variableType,
801 9
            '<variableName>'        => $variableName,
802 9
            '<methodName>'          => $methodName,
803 9
            '<fieldName>'           => $fieldName,
804 9
            '<variableDefault>'     => ($defaultValue !== null ) ? (' = ' . $defaultValue) : '',
805
        );
806
807 9
        $templateVar = sprintf('%sMethodTemplate', $type);
808
809 9
        $method = str_replace(
810 9
            array_keys($replacements),
811 9
            array_values($replacements),
812 9
            self::$$templateVar
813
        );
814
815 9
        return $this->prefixCodeWithSpaces($method);
816
    }
817
818 6
    private function generateLifecycleCallbackMethod($name, $methodName, ClassMetadataInfo $metadata)
819
    {
820 6
        if ($this->hasMethod($methodName, $metadata)) {
821 1
            return;
822
        }
823
824
        $replacements = array(
825 6
            '<comment>'    => $this->generateAnnotations ? '/** @ODM\\' . ucfirst($name) . ' */' : '',
826 6
            '<methodName>' => $methodName,
827
        );
828
829 6
        $method = str_replace(
830 6
            array_keys($replacements),
831 6
            array_values($replacements),
832 6
            self::$lifecycleCallbackMethodTemplate
833
        );
834
835 6
        return $this->prefixCodeWithSpaces($method);
836
    }
837
838 6
    private function generateAssociationMappingPropertyDocBlock(array $fieldMapping)
839
    {
840 6
        $lines = array();
841 6
        $lines[] = $this->spaces . '/**';
842 6
        $lines[] = $this->spaces . ' * @var ' . (isset($fieldMapping['targetDocument']) ? $fieldMapping['targetDocument'] : 'object');
843
844 6
        if ($this->generateAnnotations) {
845 6
            $lines[] = $this->spaces . ' *';
846
847 6
            $type = null;
848 6
            switch ($fieldMapping['association']) {
849 6
                case ClassMetadataInfo::EMBED_ONE:
850
                    $type = 'EmbedOne';
851
                    break;
852 6
                case ClassMetadataInfo::EMBED_MANY:
853
                    $type = 'EmbedMany';
854
                    break;
855 6
                case ClassMetadataInfo::REFERENCE_ONE:
856 6
                    $type = 'ReferenceOne';
857 6
                    break;
858 6
                case ClassMetadataInfo::REFERENCE_MANY:
859 6
                    $type = 'ReferenceMany';
860 6
                    break;
861
            }
862 6
            $typeOptions = array();
863
864 6
            if (isset($fieldMapping['targetDocument'])) {
865 6
                $typeOptions[] = 'targetDocument="' . $fieldMapping['targetDocument'] . '"';
866
            }
867
868 6
            if (isset($fieldMapping['cascade']) && $fieldMapping['cascade']) {
869
                $cascades = array();
870
871
                if ($fieldMapping['isCascadePersist']) $cascades[] = '"persist"';
872
                if ($fieldMapping['isCascadeRemove']) $cascades[] = '"remove"';
873
                if ($fieldMapping['isCascadeDetach']) $cascades[] = '"detach"';
874
                if ($fieldMapping['isCascadeMerge']) $cascades[] = '"merge"';
875
                if ($fieldMapping['isCascadeRefresh']) $cascades[] = '"refresh"';
876
877
                $typeOptions[] = 'cascade={' . implode(',', $cascades) . '}';
878
            }
879
880 6
            $lines[] = $this->spaces . ' * @ODM\\' . $type . '(' . implode(', ', $typeOptions) . ')';
881
        }
882
883 6
        $lines[] = $this->spaces . ' */';
884
885 6
        return implode("\n", $lines);
886
    }
887
888 7
    private function generateFieldMappingPropertyDocBlock(array $fieldMapping, ClassMetadataInfo $metadata)
889
    {
890 7
        $lines = array();
891 7
        $lines[] = $this->spaces . '/**';
892 7
        if (isset($fieldMapping['id']) && $fieldMapping['id']) {
893 7
            $fieldMapping['strategy'] = isset($fieldMapping['strategy']) ? $fieldMapping['strategy'] : ClassMetadataInfo::GENERATOR_TYPE_AUTO;
894 7
            if ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_AUTO) {
895 6
                $lines[] = $this->spaces . ' * @var MongoId $' . $fieldMapping['fieldName'];
896 1 View Code Duplication
            } elseif ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_INCREMENT) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
897
                $lines[] = $this->spaces . ' * @var integer $' . $fieldMapping['fieldName'];
898 1
            } elseif ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_UUID) {
899
                $lines[] = $this->spaces . ' * @var string $' . $fieldMapping['fieldName'];
900 1 View Code Duplication
            } elseif ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_NONE) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
901
                $lines[] = $this->spaces . ' * @var $' . $fieldMapping['fieldName'];
902
            } else {
903 1
                $lines[] = $this->spaces . ' * @var $' . $fieldMapping['fieldName'];
904
            }
905
        } else {
906 7
            $lines[] = $this->spaces . ' * @var ' . $fieldMapping['type'] . ' $' . $fieldMapping['fieldName'];
907
        }
908
909 7
        if ($this->generateAnnotations) {
910 7
            $lines[] = $this->spaces . ' *';
911
912 7
            $field = array();
913 7
            if (isset($fieldMapping['id']) && $fieldMapping['id']) {
914 7
                if (isset($fieldMapping['strategy'])) {
915 7
                    $field[] = 'strategy="' . $this->getIdGeneratorTypeString($metadata->generatorType) . '"';
916
                }
917 7
                $lines[] = $this->spaces . ' * @ODM\\Id(' . implode(', ', $field) . ')';
918
            } else {
919 7
                if (isset($fieldMapping['name'])) {
920 7
                    $field[] = 'name="' . $fieldMapping['name'] . '"';
921
                }
922
923 7
                if (isset($fieldMapping['type'])) {
924 7
                    $field[] = 'type="' . $fieldMapping['type'] . '"';
925
                }
926
927 7
                if (isset($fieldMapping['nullable']) && $fieldMapping['nullable'] === true) {
928
                    $field[] = 'nullable=' . var_export($fieldMapping['nullable'], true);
929
                }
930 7
                if (isset($fieldMapping['options'])) {
931 1
                    $options = array();
932 1
                    foreach ($fieldMapping['options'] as $key => $value) {
933
                        $options[] = '"' . $key . '" = "' . $value . '"';
934
                    }
935 1
                    $field[] = 'options={' . implode(', ', $options) . '}';
936
                }
937 7
                $lines[] = $this->spaces . ' * @ODM\\Field(' . implode(', ', $field) . ')';
938
            }
939
940 7
            if (isset($fieldMapping['version']) && $fieldMapping['version']) {
941
                $lines[] = $this->spaces . ' * @ODM\\Version';
942
            }
943
        }
944
945 7
        $lines[] = $this->spaces . ' */';
946
947 7
        return implode("\n", $lines);
948
    }
949
950 9
    private function prefixCodeWithSpaces($code, $num = 1)
951
    {
952 9
        $lines = explode("\n", $code);
953
954 9
        foreach ($lines as $key => $value) {
955 9
            $lines[$key] = str_repeat($this->spaces, $num) . $lines[$key];
956
        }
957
958 9
        return implode("\n", $lines);
959
    }
960
961
    private function getInheritanceTypeString($type)
962
    {
963
        switch ($type) {
964
            case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
965
                return 'NONE';
966
967
            case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION:
968
                return 'SINGLE_COLLECTION';
969
970
            case ClassMetadataInfo::INHERITANCE_TYPE_COLLECTION_PER_CLASS:
971
                return 'COLLECTION_PER_CLASS';
972
973
            default:
974
                throw new \InvalidArgumentException('Invalid provided InheritanceType: ' . $type);
975
        }
976
    }
977
978 8
    private function getChangeTrackingPolicyString($policy)
979
    {
980
        switch ($policy) {
981 8
            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
982 8
                return 'DEFERRED_IMPLICIT';
983
984
            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
985
                return 'DEFERRED_EXPLICIT';
986
987
            case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
988
                return 'NOTIFY';
989
990
            default:
991
                throw new \InvalidArgumentException('Invalid provided ChangeTrackingPolicy: ' . $policy);
992
        }
993
    }
994
995 7
    private function getIdGeneratorTypeString($type)
996
    {
997
        switch ($type) {
998 7
            case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
999 1
                return 'AUTO';
1000
1001 6
            case ClassMetadataInfo::GENERATOR_TYPE_INCREMENT:
1002
                return 'INCREMENT';
1003
1004 6
            case ClassMetadataInfo::GENERATOR_TYPE_UUID:
1005
                return 'UUID';
1006
1007 6
            case ClassMetadataInfo::GENERATOR_TYPE_ALNUM:
1008
                return 'ALNUM';
1009
1010 6
            case ClassMetadataInfo::GENERATOR_TYPE_CUSTOM:
1011 6
                return 'CUSTOM';
1012
1013
            case ClassMetadataInfo::GENERATOR_TYPE_NONE:
1014
                return 'NONE';
1015
1016
            default:
1017
                throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
1018
        }
1019
    }
1020
}
1021