Test Setup Failed
Push — develop ( 082d66...6f26e1 )
by Guilherme
63:04
created

MappingDescribeCommand   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 393
Duplicated Lines 1.53 %

Coupling/Cohesion

Components 2
Dependencies 11

Test Coverage

Coverage 95.28%

Importance

Changes 0
Metric Value
wmc 46
lcom 2
cbo 11
dl 6
loc 393
ccs 121
cts 127
cp 0.9528
rs 8.3999
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 17 1
A execute() 0 9 1
A displayEntity() 0 54 3
A getMappedEntities() 0 16 2
B getClassMetadata() 0 30 4
C formatParentClasses() 0 37 8
C formatValue() 0 36 11
A formatField() 0 8 2
A formatAssociationMappings() 3 14 3
B formatPropertyMappings() 3 20 5
B formatColumn() 0 26 3
A formatEntityListeners() 0 12 1
A formatTable() 0 18 2

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 MappingDescribeCommand 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 MappingDescribeCommand, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Tools\Console\Command;
6
7
use Doctrine\Common\Persistence\Mapping\MappingException;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Doctrine\ORM\Mapping\AssociationMetadata;
10
use Doctrine\ORM\Mapping\ClassMetadata;
11
use Doctrine\ORM\Mapping\ColumnMetadata;
12
use Doctrine\ORM\Mapping\ComponentMetadata;
13
use Doctrine\ORM\Mapping\FieldMetadata;
14
use Doctrine\ORM\Mapping\TableMetadata;
15
use Symfony\Component\Console\Command\Command;
16
use Symfony\Component\Console\Helper\Table;
17
use Symfony\Component\Console\Input\InputArgument;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Output\OutputInterface;
20
21
/**
22
 * Show information about mapped entities.
23
 *
24
 * @link    www.doctrine-project.org
25
 * @since   2.4
26
 * @author  Daniel Leech <[email protected]>
27
 */
28
final class MappingDescribeCommand extends Command
29
{
30
    /**
31
     * {@inheritdoc}
32
     */
33
    protected function configure()
34
    {
35
        $this
36
            ->setName('orm:mapping:describe')
37
            ->addArgument('entityName', InputArgument::REQUIRED, 'Full or partial name of entity')
38
            ->setDescription('Display information about mapped objects')
39
            ->setHelp(<<<EOT
40
The %command.full_name% command describes the metadata for the given full or partial entity class name.
41
42
    <info>%command.full_name%</info> My\Namespace\Entity\MyEntity
43 3
44
Or:
45
46 3
    <info>%command.full_name%</info> MyEntity
47 3
EOT
48 3
            );
49 3
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    protected function execute(InputInterface $input, OutputInterface $output)
55
    {
56 3
        /* @var $entityManager \Doctrine\ORM\EntityManagerInterface */
57
        $entityManager = $this->getHelper('em')->getEntityManager();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Helper\HelperInterface as the method getEntityManager() does only exist in the following implementations of said interface: Doctrine\ORM\Tools\Conso...per\EntityManagerHelper.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
58
59 3
        $this->displayEntity($input->getArgument('entityName'), $entityManager, $output);
60
61
        return 0;
62
    }
63
64 3
    /**
65
     * Display all the mapping information for a single Entity.
66
     *
67 3
     * @param string                 $entityName    Full or partial entity class name
68
     * @param EntityManagerInterface $entityManager
69 3
     * @param OutputInterface        $output
70
     */
71 1
    private function displayEntity($entityName, EntityManagerInterface $entityManager, OutputInterface $output)
72
    {
73
        $table = new Table($output);
74
75
        $table->setHeaders(['Field', 'Value']);
76
77
        $metadata    = $this->getClassMetadata($entityName, $entityManager);
78
        $parentValue = $metadata->getParent() === null ? '<comment>None</comment>' : '';
0 ignored issues
show
Bug introduced by
The method getParent() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
79
80
        array_map(
81 3
            [$table, 'addRow'],
82
            array_merge(
83 3
                [
84
                    $this->formatField('Name', $metadata->getClassName()),
0 ignored issues
show
Bug introduced by
The method getClassName() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
85 3
                    $this->formatField('Root entity name', $metadata->getRootClassName()),
0 ignored issues
show
Bug introduced by
The method getRootClassName() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
86
                    $this->formatField('Custom repository class', $metadata->getCustomRepositoryClassName()),
0 ignored issues
show
Bug introduced by
The method getCustomRepositoryClassName() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
87 3
                    $this->formatField('Mapped super class?', $metadata->isMappedSuperclass),
0 ignored issues
show
Bug introduced by
Accessing isMappedSuperclass on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
88
                    $this->formatField('Embedded class?', $metadata->isEmbeddedClass),
0 ignored issues
show
Bug introduced by
Accessing isEmbeddedClass on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
89 1
                    $this->formatField('Parent classes', $parentValue),
90 1
                ],
91
                $this->formatParentClasses($metadata),
0 ignored issues
show
Documentation introduced by
$metadata is of type object<Doctrine\Common\P...\Mapping\ClassMetadata>, but the function expects a object<Doctrine\ORM\Mapping\ComponentMetadata>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
                [
93 1
                    $this->formatField('Sub classes', $metadata->getSubClasses()),
0 ignored issues
show
Bug introduced by
The method getSubClasses() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
94 1
                    $this->formatField('Embedded classes', $metadata->getSubClasses()),
0 ignored issues
show
Bug introduced by
The method getSubClasses() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
95 1
                    $this->formatField('Named queries', $metadata->getNamedQueries()),
0 ignored issues
show
Bug introduced by
The method getNamedQueries() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata. Did you maybe mean getName()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
96 1
                    $this->formatField('Named native queries', $metadata->getNamedNativeQueries()),
0 ignored issues
show
Bug introduced by
The method getNamedNativeQueries() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata. Did you maybe mean getName()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
97 1
                    $this->formatField('SQL result set mappings', $metadata->getSqlResultSetMappings()),
0 ignored issues
show
Bug introduced by
The method getSqlResultSetMappings() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
98 1
                    $this->formatField('Identifier', $metadata->getIdentifier()),
99 1
                    $this->formatField('Inheritance type', $metadata->inheritanceType),
0 ignored issues
show
Bug introduced by
Accessing inheritanceType on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
100 1
                    $this->formatField('Discriminator column', ''),
101 1
                ],
102 1
                $this->formatColumn($metadata->discriminatorColumn),
0 ignored issues
show
Bug introduced by
Accessing discriminatorColumn on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
103 1
                [
104 1
                    $this->formatField('Discriminator value', $metadata->discriminatorValue),
0 ignored issues
show
Bug introduced by
Accessing discriminatorValue on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
105 1
                    $this->formatField('Discriminator map', $metadata->discriminatorMap),
0 ignored issues
show
Bug introduced by
Accessing discriminatorMap on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
106 1
                    $this->formatField('Table', ''),
107 1
                ],
108
                $this->formatTable($metadata->table),
0 ignored issues
show
Bug introduced by
Accessing table on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
109 1
                [
110
                    $this->formatField('Composite identifier?', $metadata->isIdentifierComposite()),
0 ignored issues
show
Bug introduced by
The method isIdentifierComposite() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata. Did you maybe mean isIdentifier()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
111 1
                    $this->formatField('Change tracking policy', $metadata->changeTrackingPolicy),
0 ignored issues
show
Bug introduced by
Accessing changeTrackingPolicy on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
112 1
                    $this->formatField('Versioned?', $metadata->isVersioned()),
0 ignored issues
show
Bug introduced by
The method isVersioned() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
113 1
                    $this->formatField('Version field', ($metadata->isVersioned() ? $metadata->versionProperty->getName() : '')),
0 ignored issues
show
Bug introduced by
Accessing versionProperty on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
The method isVersioned() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
114 1
                    $this->formatField('Read only?', $metadata->isReadOnly()),
0 ignored issues
show
Bug introduced by
The method isReadOnly() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
115 1
116 1
                    $this->formatEntityListeners($metadata->entityListeners),
0 ignored issues
show
Bug introduced by
Accessing entityListeners on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
117 1
                ],
118 1
                [$this->formatField('Property mappings:', '')],
119 1
                $this->formatPropertyMappings($metadata->getDeclaredPropertiesIterator())
0 ignored issues
show
Bug introduced by
The method getDeclaredPropertiesIterator() does not seem to exist on object<Doctrine\Common\P...\Mapping\ClassMetadata>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
120 1
            )
121 1
        );
122
123 1
        $table->render();
124
    }
125 1
126 1
    /**
127 1
     * Return all mapped entity class names
128 1
     *
129
     * @param EntityManagerInterface $entityManager
130
     *
131
     * @return string[]
132 1
     */
133 1
    private function getMappedEntities(EntityManagerInterface $entityManager)
134
    {
135
        $entityClassNames = $entityManager
136
            ->getConfiguration()
137
            ->getMetadataDriverImpl()
138
            ->getAllClassNames();
139
140
        if ( ! $entityClassNames) {
141
            throw new \InvalidArgumentException(
142 3
                'You do not have any mapped Doctrine ORM entities according to the current configuration. '.
143
                'If you have entities or mapping files you should check your mapping configuration for errors.'
144
            );
145 3
        }
146 3
147 3
        return $entityClassNames;
148
    }
149 3
150
    /**
151
     * Return the class metadata for the given entity
152
     * name
153
     *
154
     * @param string                 $entityName    Full or partial entity name
155
     * @param EntityManagerInterface $entityManager
156 3
     *
157
     * @return \Doctrine\ORM\Mapping\ClassMetadata
158
     */
159
    private function getClassMetadata($entityName, EntityManagerInterface $entityManager)
160
    {
161
        try {
162
            return $entityManager->getClassMetadata($entityName);
163
        } catch (MappingException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
164
        }
165
166
        $matches = array_filter(
167
            $this->getMappedEntities($entityManager),
168 3
            function ($mappedEntity) use ($entityName) {
169
                return preg_match('{' . preg_quote($entityName) . '}', $mappedEntity);
170
            }
171 3
        );
172 3
173
        if ( ! $matches) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matches 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...
174
            throw new \InvalidArgumentException(sprintf(
175 3
                'Could not find any mapped Entity classes matching "%s"',
176 3
                $entityName
177
            ));
178 3
        }
179 3
180
        if (count($matches) > 1) {
181
            throw new \InvalidArgumentException(sprintf(
182 3
                'Entity name "%s" is ambiguous, possible matches: "%s"',
183 1
                $entityName, implode(', ', $matches)
184 1
            ));
185
        }
186
187
        return $entityManager->getClassMetadata(current($matches));
188
    }
189 2
190 1
    /**
191 1
     * @param ComponentMetadata $metadata
192 1
     *
193
     * @return array
194
     */
195
    private function formatParentClasses(ComponentMetadata $metadata)
196 1
    {
197
        $output      = [];
198
        $parentClass = $metadata;
199
200
        while (($parentClass = $parentClass->getParent()) !== null) {
201
            /** @var ClassMetadata $parentClass */
202
            $attributes = [];
203
204
            if ($parentClass->isEmbeddedClass) {
205
                $attributes[] = 'Embedded';
206 1
            }
207
208 1
            if ($parentClass->isMappedSuperclass) {
209 1
                $attributes[] = 'Mapped superclass';
210
            }
211
212 1
            if ($parentClass->inheritanceType) {
213 1
                $attributes[] = ucfirst(strtolower($parentClass->inheritanceType));
214
            }
215
216 1
            if ($parentClass->isReadOnly()) {
217 1
                $attributes[] = 'Read-only';
218
            }
219
220 1
            if ($parentClass->isVersioned()) {
221 1
                $attributes[] = 'Versioned';
222
            }
223
224 1
            $output[] = $this->formatField(
225 1
                sprintf('  %s', $parentClass->getParent()),
226 1
                ($parentClass->isRootEntity() ? '(Root) ' : '') . $this->formatValue($attributes)
227
            );
228
        }
229
230
        return $output;
231
    }
232 1
233 1
    /**
234
     * Format the given value for console output
235
     *
236 1
     * @param mixed $value
237 1
     *
238
     * @return string
239
     */
240
    private function formatValue($value)
241
    {
242
        if ('' === $value) {
243
            return '';
244
        }
245
246
        if (null === $value) {
247
            return '<comment>Null</comment>';
248
        }
249
250
        if (is_bool($value)) {
251 1
            return '<comment>' . ($value ? 'True' : 'False') . '</comment>';
252
        }
253 1
254 1
        if (empty($value)) {
255
            return '<comment>Empty</comment>';
256
        }
257 1
258
        if (is_array($value)) {
259
            if (defined('JSON_UNESCAPED_UNICODE') && defined('JSON_UNESCAPED_SLASHES')) {
260
                return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
261
            }
262
263
            return json_encode($value);
264
        }
265
266
        if (is_object($value)) {
267 1
            return sprintf('<%s>', get_class($value));
268
        }
269 1
270
        if (is_scalar($value)) {
271 1
            return $value;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $value; of type integer|double|string|boolean is incompatible with the return type documented by Doctrine\ORM\Tools\Conso...ibeCommand::formatValue of type string as it can also be of type boolean which is not included in this return type.
Loading history...
272 1
        }
273
274 1
        throw new \InvalidArgumentException(sprintf('Do not know how to format value "%s"', print_r($value, true)));
275 1
    }
276
277
    /**
278
     * Add the given label and value to the two column table output
279 1
     *
280
     * @param string $label Label for the value
281
     * @param mixed  $value A Value to show
282
     *
283
     * @return array
284
     */
285
    private function formatField($label, $value)
286
    {
287
        if (null === $value) {
288
            $value = '<comment>None</comment>';
289
        }
290 1
291
        return [sprintf('<info>%s</info>', $label), $this->formatValue($value)];
292 1
    }
293
294 1
    /**
295 1
     * Format the association mappings
296
     *
297 1
     * @param array $propertyMappings
298
     *
299
     * @return array
300 1
     */
301
    private function formatAssociationMappings(array $propertyMappings)
302
    {
303
        $output = [];
304
305
        foreach ($propertyMappings as $propertyName => $mapping) {
306
            $output[] = $this->formatField(sprintf('  %s', $propertyName), '');
307
308 1 View Code Duplication
            foreach ($mapping as $field => $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...
309
                $output[] = $this->formatField(sprintf('    %s', $field), $this->formatValue($value));
310 1
            }
311
        }
312 1
313
        return $output;
314
    }
315
316
317
    /**
318 1
     * Format the property mappings
319 1
     *
320 1
     * @param iterable $propertyMappings
321 1
     *
322 1
     * @return array
323 1
     */
324 1
    private function formatPropertyMappings(iterable $propertyMappings)
325
    {
326 1
        $output = [];
327
328
        foreach ($propertyMappings as $propertyName => $property) {
329
            $output[] = $this->formatField(sprintf('  %s', $propertyName), '');
330
331
            if ($property instanceof FieldMetadata) {
332
                $output = array_merge($output, $this->formatColumn($property));
333
            }  else if ($property instanceof AssociationMetadata) {
334
                // @todo guilhermeblanco Fix me! We are trying to iterate through an AssociationMetadata instance
335 View Code Duplication
                foreach ($property as $field => $value) {
0 ignored issues
show
Bug introduced by
The expression $property of type object<Doctrine\ORM\Mapping\AssociationMetadata> is not traversable.
Loading history...
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...
336 1
                    $output[] = $this->formatField(sprintf('    %s', $field), $this->formatValue($value));
337
                }
338 1
339 1
            }
340
        }
341 1
342
        return $output;
343 1
    }
344
345
    /**
346
     * @param ColumnMetadata|null $columnMetadata
347
     *
348
     * @return array|string
349
     */
350
    private function formatColumn(ColumnMetadata $columnMetadata = null)
351
    {
352
        $output = [];
353
354
        if (null === $columnMetadata) {
355
            $output[] = '<comment>Null</comment>';
356
357
            return $output;
358
        }
359
360
        $output[] = $this->formatField('    type', $this->formatValue($columnMetadata->getTypeName()));
361
        $output[] = $this->formatField('    tableName', $this->formatValue($columnMetadata->getTableName()));
362
        $output[] = $this->formatField('    columnName', $this->formatValue($columnMetadata->getColumnName()));
363
        $output[] = $this->formatField('    columnDefinition', $this->formatValue($columnMetadata->getColumnDefinition()));
364
        $output[] = $this->formatField('    isPrimaryKey', $this->formatValue($columnMetadata->isPrimaryKey()));
365
        $output[] = $this->formatField('    isNullable', $this->formatValue($columnMetadata->isNullable()));
366
        $output[] = $this->formatField('    isUnique', $this->formatValue($columnMetadata->isUnique()));
367
        $output[] = $this->formatField('    options', $this->formatValue($columnMetadata->getOptions()));
368
369
        if ($columnMetadata instanceof FieldMetadata) {
370
            $output[] = $this->formatField('    Generator type', $this->formatValue($columnMetadata->getValueGenerator()->getType()));
371
            $output[] = $this->formatField('    Generator definition', $this->formatValue($columnMetadata->getValueGenerator()->getDefinition()));
372
        }
373
374
        return $output;
375
    }
376
377
    /**
378
     * Format the entity listeners
379
     *
380
     * @param array $entityListeners
381
     *
382
     * @return array
383
     */
384
    private function formatEntityListeners(array $entityListeners)
385
    {
386
        return $this->formatField(
387
            'Entity listeners',
388
            array_map(
389
                function ($entityListener) {
390
                    return get_class($entityListener);
391
                },
392
                $entityListeners
393
            )
394
        );
395
    }
396
397
    /**
398
     * @param TableMetadata|null $tableMetadata
399
     *
400
     * @return array|string
401
     */
402
    private function formatTable(TableMetadata $tableMetadata = null)
403
    {
404
        $output = [];
405
406
        if (null === $tableMetadata) {
407
            $output[] = '<comment>Null</comment>';
408
409
            return $output;
410
        }
411
412
        $output[] = $this->formatField('    schema', $this->formatValue($tableMetadata->getSchema()));
413
        $output[] = $this->formatField('    name', $this->formatValue($tableMetadata->getName()));
414
        $output[] = $this->formatField('    indexes', $this->formatValue($tableMetadata->getIndexes()));
415
        $output[] = $this->formatField('    uniqueConstaints', $this->formatValue($tableMetadata->getUniqueConstraints()));
416
        $output[] = $this->formatField('    options', $this->formatValue($tableMetadata->getOptions()));
417
418
        return $output;
419
    }
420
}
421