Completed
Pull Request — master (#1523)
by
unknown
10:09
created

DocumentGenerator   D

Complexity

Total Complexity 218

Size/Duplication

Total Lines 987
Duplicated Lines 7.7 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 81.46%

Importance

Changes 0
Metric Value
wmc 218
lcom 1
cbo 3
dl 76
loc 987
ccs 356
cts 437
cp 0.8146
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 generateInheritanceAnnotation() 0 6 2
A generateDiscriminatorFieldAnnotation() 0 6 2
A generateDefaultDiscriminatorValueAnnotation() 0 6 3
A generateChangeTrackingPolicyAnnotation() 0 4 1
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 parseTokensInDocumentFile() 0 33 14
C hasProperty() 22 22 8
C hasMethod() 22 22 8
A getNamespace() 0 4 1
B getTraits() 0 13 5
D generateDocumentDocBlock() 6 75 16
A generateDiscriminatorMapAnnotation() 0 12 3
D generateDocumentStubMethods() 20 47 22
A isAssociationNullable() 0 4 2
B generateDocumentLifecycleCallbackMethods() 0 18 5
B generateDocumentAssociationMappingProperties() 0 20 6
B generateDocumentFieldMappingProperties() 0 20 7
C generateDocumentStubMethod() 0 40 8
A generateLifecycleCallbackMethod() 0 19 3
F generateAssociationMappingPropertyDocBlock() 0 49 15
D generateFieldMappingPropertyDocBlock() 6 67 21
A prefixCodeWithSpaces() 0 10 2
A getInheritanceTypeString() 0 16 4
A getChangeTrackingPolicyString() 0 16 4
C getIdGeneratorTypeString() 0 25 7

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 9
                $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 1
                    $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
            } else {
558 8
                $lines[] = ' * @ODM\\Document';
559
            }
560
561 8
            $document = array();
562 8
            if ( ! $metadata->isMappedSuperclass && ! $metadata->isEmbeddedDocument) {
563 8
                if ($metadata->collection) {
564 8
                    $document[] = ' *     collection="' . $metadata->collection . '"';
565
                }
566 8
                if ($metadata->customRepositoryClassName) {
567 6
                    $document[] = ' *     repositoryClass="' . $metadata->customRepositoryClassName . '"';
568
                }
569
            }
570 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...
571
                $indexes = array();
572
                $indexLines = array();
573
                $indexLines[] = ' *     indexes={';
574
                foreach ($metadata->indexes as $index) {
575
                    $keys = array();
576 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...
577
                        $keys[] = '"' . $key . '"="' . $value . '"';
578
                    }
579
                    $options = array();
580 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...
581
                        $options[] = '"' . $key . '"="' . $value . '"';
582
                    }
583
                    $indexes[] = '@ODM\\Index(keys={' . implode(', ', $keys) . '}, options={' . implode(', ', $options) . '})';
584
                }
585
                $indexLines[] = "\n *         " . implode(",\n *         ", $indexes);
586
                $indexLines[] = "\n *     }";
587
588
                $document[] = implode(null, $indexLines);
589
            }
590
591 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...
592 8
                $lines[count($lines) - 1] .= '(';
593 8
                $lines[] = implode(",\n", $document);
594 8
                $lines[] = ' * )';
595
            }
596
597 8
            if ( ! empty($metadata->lifecycleCallbacks)) {
598 6
                $lines[] = ' * @ODM\HasLifecycleCallbacks';
599
            }
600
601
            $methods = array(
602 8
                'generateInheritanceAnnotation',
603
                'generateDiscriminatorFieldAnnotation',
604
                'generateDiscriminatorMapAnnotation',
605
                'generateDefaultDiscriminatorValueAnnotation',
606
                'generateChangeTrackingPolicyAnnotation'
607
            );
608
609 8
            foreach ($methods as $method) {
610 8
                if ($code = $this->$method($metadata)) {
611 8
                    $lines[] = ' * ' . $code;
612
                }
613
            }
614
        }
615
616 8
        $lines[] = ' */';
617 8
        return implode("\n", $lines);
618
    }
619
620 8
    private function generateInheritanceAnnotation(ClassMetadataInfo $metadata)
621
    {
622 8
        if ($metadata->inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
623
            return '@ODM\\InheritanceType("' . $this->getInheritanceTypeString($metadata->inheritanceType) . '")';
624
        }
625 8
    }
626
627 8
    private function generateDiscriminatorFieldAnnotation(ClassMetadataInfo $metadata)
628
    {
629 8
        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
630
            return '@ODM\\DiscriminatorField(name="' . $metadata->discriminatorField . '")';
631
        }
632 8
    }
633
634 8
    private function generateDiscriminatorMapAnnotation(ClassMetadataInfo $metadata)
635
    {
636 8
        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
637
            $inheritanceClassMap = array();
638
639
            foreach ($metadata->discriminatorMap as $type => $class) {
640
                $inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
641
            }
642
643
            return '@ODM\\DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
644
        }
645 8
    }
646
647 8
    private function generateDefaultDiscriminatorValueAnnotation(ClassMetadataInfo $metadata)
648
    {
649 8
        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION && isset($metadata->defaultDiscriminatorValue)) {
650
            return '@ODM\\DefaultDiscriminatorValue("' . $metadata->defaultDiscriminatorValue . '")';
651
        }
652 8
    }
653
654 8
    private function generateChangeTrackingPolicyAnnotation(ClassMetadataInfo $metadata)
655
    {
656 8
        return '@ODM\\ChangeTrackingPolicy("' . $this->getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . '")';
657
    }
658
659 9
    private function generateDocumentStubMethods(ClassMetadataInfo $metadata)
660
    {
661 9
        $methods = array();
662
663 9
        foreach ($metadata->fieldMappings as $fieldMapping) {
664
            // fieldTypeName is optional in the yml-configuration, otherwise the non-optional type is used as field type name
665 9
            $typeHint = isset($fieldMapping['fieldTypeName']) ? $fieldMapping['fieldTypeName'] : $fieldMapping['type'];
666
            
667 9
            if (isset($fieldMapping['id'])) {
668 9 View Code Duplication
                if ($metadata->generatorType == 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...
669
                    if ($code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], $typeHint)) {
670
                        $methods[] = $code;
671
                    }
672
                }
673 9 View Code Duplication
                if ($code = $code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], $typeHint)) {
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...
674 9
                    $methods[] = $code;
675
                }
676 9
            } elseif ( ! isset($fieldMapping['association'])) {
677 9
                if ($code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], $typeHint)) {
678 9
                    $methods[] = $code;
679
                }
680 9
                if ($code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], $typeHint)) {
681 9
                    $methods[] = $code;
682
                }
683 8
            } elseif ($fieldMapping['type'] === ClassMetadataInfo::ONE) {
684 8
                $nullable = $this->isAssociationNullable($fieldMapping) ? 'null' : null;
685 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...
686 6
                    $methods[] = $code;
687
                }
688 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...
689 8
                    $methods[] = $code;
690
                }
691 6
            } elseif ($fieldMapping['type'] === ClassMetadataInfo::MANY) {
692 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...
693 6
                    $methods[] = $code;
694
                }
695 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...
696 6
                    $methods[] = $code;
697
                }
698 6
                if ($code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], '\Doctrine\Common\Collections\Collection')) {
699 9
                    $methods[] = $code;
700
                }
701
            }
702
        }
703
704 9
        return implode("\n\n", $methods);
705
    }
706
707
    /**
708
     * @param array $fieldMapping
709
     *
710
     * @return bool
711
     */
712 8
    protected function isAssociationNullable($fieldMapping)
713
    {
714 8
        return isset($fieldMapping['nullable']) && $fieldMapping['nullable'];
715
    }
716
717 9
    private function generateDocumentLifecycleCallbackMethods(ClassMetadataInfo $metadata)
718
    {
719 9
        if (empty($metadata->lifecycleCallbacks)) {
720 3
            return '';
721
        }
722
723 6
        $methods = array();
724
725 6
        foreach ($metadata->lifecycleCallbacks as $event => $callbacks) {
726 6
            foreach ($callbacks as $callback) {
727 6
                if ($code = $this->generateLifecycleCallbackMethod($event, $callback, $metadata)) {
728 6
                    $methods[] = $code;
729
                }
730
            }
731
        }
732
733 6
        return implode("\n\n", $methods);
734
    }
735
736 9
    private function generateDocumentAssociationMappingProperties(ClassMetadataInfo $metadata)
737
    {
738 9
        $lines = array();
739
740 9
        foreach ($metadata->fieldMappings as $fieldMapping) {
741 9
            if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
742 9
                $metadata->isInheritedField($fieldMapping['fieldName'])) {
743 4
                continue;
744
            }
745 7
            if ( ! isset($fieldMapping['association'])) {
746 7
                continue;
747
            }
748
749 6
            $lines[] = $this->generateAssociationMappingPropertyDocBlock($fieldMapping);
750 6
            $lines[] = $this->spaces . 'protected $' . $fieldMapping['fieldName']
751 6
                . ($fieldMapping['type'] === ClassMetadataInfo::MANY ? ' = array()' : null) . ";\n";
752
        }
753
754 9
        return implode("\n", $lines);
755
    }
756
757 9
    private function generateDocumentFieldMappingProperties(ClassMetadataInfo $metadata)
758
    {
759 9
        $lines = array();
760
761 9
        foreach ($metadata->fieldMappings as $fieldMapping) {
762 9
            if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
763 9
                $metadata->isInheritedField($fieldMapping['fieldName'])) {
764 4
                continue;
765
            }
766 7
            if (isset($fieldMapping['association']) && $fieldMapping['association']) {
767 6
                continue;
768
            }
769
770 7
            $lines[] = $this->generateFieldMappingPropertyDocBlock($fieldMapping, $metadata);
771 7
            $lines[] = $this->spaces . 'protected $' . $fieldMapping['fieldName']
772 7
                . (isset($fieldMapping['default']) ? ' = ' . var_export($fieldMapping['default'], true) : null) . ";\n";
773
        }
774
775 9
        return implode("\n", $lines);
776
    }
777
778 9
    private function generateDocumentStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null)
779
    {
780
        // Add/remove methods should use the singular form of the field name
781 9
        $formattedFieldName = in_array($type, array('add', 'remove'))
782 6
            ? Inflector::singularize($fieldName)
783 9
            : $fieldName;
784
785 9
        $methodName = $type . Inflector::classify($formattedFieldName);
786 9
        $variableName = Inflector::camelize($formattedFieldName);
787
788 9
        if ($this->hasMethod($methodName, $metadata)) {
789 4
            return;
790
        }
791
792 9
        $description = ucfirst($type) . ' ' . $variableName;
793
794 9
        $types = Type::getTypesMap();
795 9
        $methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? (substr($typeHint, 0, 1) !== '\\' ? '\\' : '') . $typeHint . ' ' : null;
796 9
        $variableType = $typeHint ? $typeHint . ' ' : null;
797
798
        $replacements = array(
799 9
            '<description>'         => $description,
800 9
            '<methodTypeHint>'      => $methodTypeHint,
801 9
            '<variableType>'        => $variableType,
802 9
            '<variableName>'        => $variableName,
803 9
            '<methodName>'          => $methodName,
804 9
            '<fieldName>'           => $fieldName,
805 9
            '<variableDefault>'     => ($defaultValue !== null ) ? (' = ' . $defaultValue) : '',
806
        );
807
808 9
        $templateVar = sprintf('%sMethodTemplate', $type);
809
810 9
        $method = str_replace(
811
            array_keys($replacements),
812
            array_values($replacements),
813 9
            self::$$templateVar
814
        );
815
816 9
        return $this->prefixCodeWithSpaces($method);
817
    }
818
819 6
    private function generateLifecycleCallbackMethod($name, $methodName, ClassMetadataInfo $metadata)
820
    {
821 6
        if ($this->hasMethod($methodName, $metadata)) {
822 1
            return;
823
        }
824
825
        $replacements = array(
826 6
            '<comment>'    => $this->generateAnnotations ? '/** @ODM\\' . ucfirst($name) . ' */' : '',
827 6
            '<methodName>' => $methodName,
828
        );
829
830 6
        $method = str_replace(
831
            array_keys($replacements),
832
            array_values($replacements),
833 6
            self::$lifecycleCallbackMethodTemplate
834
        );
835
836 6
        return $this->prefixCodeWithSpaces($method);
837
    }
838
839 6
    private function generateAssociationMappingPropertyDocBlock(array $fieldMapping)
840
    {
841 6
        $lines = array();
842 6
        $lines[] = $this->spaces . '/**';
843 6
        $lines[] = $this->spaces . ' * @var ' . (isset($fieldMapping['targetDocument']) ? $fieldMapping['targetDocument'] : 'object');
844
845 6
        if ($this->generateAnnotations) {
846 6
            $lines[] = $this->spaces . ' *';
847
848 6
            $type = null;
849 6
            switch ($fieldMapping['association']) {
850 6
                case ClassMetadataInfo::EMBED_ONE:
851
                    $type = 'EmbedOne';
852
                    break;
853 6
                case ClassMetadataInfo::EMBED_MANY:
854
                    $type = 'EmbedMany';
855
                    break;
856 6
                case ClassMetadataInfo::REFERENCE_ONE:
857 6
                    $type = 'ReferenceOne';
858 6
                    break;
859 6
                case ClassMetadataInfo::REFERENCE_MANY:
860 6
                    $type = 'ReferenceMany';
861 6
                    break;
862
            }
863 6
            $typeOptions = array();
864
865 6
            if (isset($fieldMapping['targetDocument'])) {
866 6
                $typeOptions[] = 'targetDocument="' . $fieldMapping['targetDocument'] . '"';
867
            }
868
869 6
            if (isset($fieldMapping['cascade']) && $fieldMapping['cascade']) {
870
                $cascades = array();
871
872
                if ($fieldMapping['isCascadePersist']) $cascades[] = '"persist"';
873
                if ($fieldMapping['isCascadeRemove']) $cascades[] = '"remove"';
874
                if ($fieldMapping['isCascadeDetach']) $cascades[] = '"detach"';
875
                if ($fieldMapping['isCascadeMerge']) $cascades[] = '"merge"';
876
                if ($fieldMapping['isCascadeRefresh']) $cascades[] = '"refresh"';
877
878
                $typeOptions[] = 'cascade={' . implode(',', $cascades) . '}';
879
            }
880
881 6
            $lines[] = $this->spaces . ' * @ODM\\' . $type . '(' . implode(', ', $typeOptions) . ')';
882
        }
883
884 6
        $lines[] = $this->spaces . ' */';
885
886 6
        return implode("\n", $lines);
887
    }
888
889 7
    private function generateFieldMappingPropertyDocBlock(array $fieldMapping, ClassMetadataInfo $metadata)
890
    {
891 7
        $lines = array();
892 7
        $lines[] = $this->spaces . '/**';
893 7
        if (isset($fieldMapping['id']) && $fieldMapping['id']) {
894 7
            $fieldMapping['strategy'] = isset($fieldMapping['strategy']) ? $fieldMapping['strategy'] : ClassMetadataInfo::GENERATOR_TYPE_AUTO;
895 7
            if ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_AUTO) {
896 6
                $lines[] = $this->spaces . ' * @var MongoId $' . $fieldMapping['fieldName'];
897 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...
898
                $lines[] = $this->spaces . ' * @var integer $' . $fieldMapping['fieldName'];
899 1
            } elseif ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_UUID) {
900
                $lines[] = $this->spaces . ' * @var string $' . $fieldMapping['fieldName'];
901 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...
902
                $lines[] = $this->spaces . ' * @var $' . $fieldMapping['fieldName'];
903
            } else {
904 7
                $lines[] = $this->spaces . ' * @var $' . $fieldMapping['fieldName'];
905
            }
906
        } else {
907
            // fieldTypeName is optional in the yml-configuration, otherwise the non-optional type is used as field type name
908
            
909 7
            if (isset($fieldMapping['fieldTypeName'])){
910
                $lines[] = $this->spaces . ' * @var ' . $fieldMapping['fieldTypeName'] . ' $' . $fieldMapping['fieldName'];
911
            } else {
912 7
                $lines[] = $this->spaces . ' * @var ' . $fieldMapping['type'] . ' $' . $fieldMapping['fieldName'];
913
            }
914
        }
915
916 7
        if ($this->generateAnnotations) {
917 7
            $lines[] = $this->spaces . ' *';
918
919 7
            $field = array();
920 7
            if (isset($fieldMapping['id']) && $fieldMapping['id']) {
921 7
                if (isset($fieldMapping['strategy'])) {
922 7
                    $field[] = 'strategy="' . $this->getIdGeneratorTypeString($metadata->generatorType) . '"';
923
                }
924 7
                $lines[] = $this->spaces . ' * @ODM\\Id(' . implode(', ', $field) . ')';
925
            } else {
926 7
                if (isset($fieldMapping['name'])) {
927 7
                    $field[] = 'name="' . $fieldMapping['name'] . '"';
928
                }
929
930 7
                if (isset($fieldMapping['type'])) {
931 7
                    $field[] = 'type="' . $fieldMapping['type'] . '"';
932
                }
933
934 7
                if (isset($fieldMapping['nullable']) && $fieldMapping['nullable'] === true) {
935
                    $field[] = 'nullable=' . var_export($fieldMapping['nullable'], true);
936
                }
937 7
                if (isset($fieldMapping['options'])) {
938 1
                    $options = array();
939 1
                    foreach ($fieldMapping['options'] as $key => $value) {
940
                        $options[] = '"' . $key . '" = "' . $value . '"';
941
                    }
942 1
                    $field[] = 'options={' . implode(', ', $options) . '}';
943
                }
944 7
                $lines[] = $this->spaces . ' * @ODM\\Field(' . implode(', ', $field) . ')';
945
            }
946
947 7
            if (isset($fieldMapping['version']) && $fieldMapping['version']) {
948
                $lines[] = $this->spaces . ' * @ODM\\Version';
949
            }
950
        }
951
952 7
        $lines[] = $this->spaces . ' */';
953
954 7
        return implode("\n", $lines);
955
    }
956
957 9
    private function prefixCodeWithSpaces($code, $num = 1)
958
    {
959 9
        $lines = explode("\n", $code);
960
961 9
        foreach ($lines as $key => $value) {
962 9
            $lines[$key] = str_repeat($this->spaces, $num) . $lines[$key];
963
        }
964
965 9
        return implode("\n", $lines);
966
    }
967
968
    private function getInheritanceTypeString($type)
969
    {
970
        switch ($type) {
971
            case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
972
                return 'NONE';
973
974
            case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION:
975
                return 'SINGLE_COLLECTION';
976
977
            case ClassMetadataInfo::INHERITANCE_TYPE_COLLECTION_PER_CLASS:
978
                return 'COLLECTION_PER_CLASS';
979
980
            default:
981
                throw new \InvalidArgumentException('Invalid provided InheritanceType: ' . $type);
982
        }
983
    }
984
985 8
    private function getChangeTrackingPolicyString($policy)
986
    {
987
        switch ($policy) {
988 8
            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
989 8
                return 'DEFERRED_IMPLICIT';
990
991
            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
992
                return 'DEFERRED_EXPLICIT';
993
994
            case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
995
                return 'NOTIFY';
996
997
            default:
998
                throw new \InvalidArgumentException('Invalid provided ChangeTrackingPolicy: ' . $policy);
999
        }
1000
    }
1001
1002 7
    private function getIdGeneratorTypeString($type)
1003
    {
1004
        switch ($type) {
1005 7
            case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
1006 1
                return 'AUTO';
1007
1008 6
            case ClassMetadataInfo::GENERATOR_TYPE_INCREMENT:
1009
                return 'INCREMENT';
1010
1011 6
            case ClassMetadataInfo::GENERATOR_TYPE_UUID:
1012
                return 'UUID';
1013
1014 6
            case ClassMetadataInfo::GENERATOR_TYPE_ALNUM:
1015
                return 'ALNUM';
1016
1017 6
            case ClassMetadataInfo::GENERATOR_TYPE_CUSTOM:
1018 6
                return 'CUSTOM';
1019
1020
            case ClassMetadataInfo::GENERATOR_TYPE_NONE:
1021
                return 'NONE';
1022
1023
            default:
1024
                throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
1025
        }
1026
    }
1027
}
1028