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

ResultSetMappingBuilder::addAllClassFields()   C

Complexity

Conditions 10
Paths 9

Size

Total Lines 56
Code Lines 31

Duplication

Lines 38
Ratio 67.86 %

Code Coverage

Tests 27
CRAP Score 10.0045

Importance

Changes 0
Metric Value
dl 38
loc 56
ccs 27
cts 28
cp 0.9643
rs 6.7741
c 0
b 0
f 0
cc 10
eloc 31
nc 9
nop 4
crap 10.0045

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Query;
6
7
use Doctrine\DBAL\Types\Type;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Doctrine\ORM\Mapping\AssociationMetadata;
10
use Doctrine\ORM\Mapping\ClassMetadata;
11
use Doctrine\ORM\Mapping\FieldMetadata;
12
use Doctrine\ORM\Mapping\InheritanceType;
13
use Doctrine\ORM\Mapping\JoinColumnMetadata;
14
use Doctrine\ORM\Mapping\MappingException;
15
use Doctrine\ORM\Mapping\ToOneAssociationMetadata;
16
use Doctrine\ORM\Utility\PersisterHelper;
17
18
/**
19
 * A ResultSetMappingBuilder uses the EntityManager to automatically populate entity fields.
20
 *
21
 * @author Michael Ridgway <[email protected]>
22
 * @since 2.1
23
 */
24
class ResultSetMappingBuilder extends ResultSetMapping
25
{
26
    /**
27
     * Picking this rename mode will register entity columns as is,
28
     * as they are in the database. This can cause clashes when multiple
29
     * entities are fetched that have columns with the same name.
30
     *
31
     * @var int
32
     */
33
    const COLUMN_RENAMING_NONE = 1;
34
35
    /**
36
     * Picking custom renaming allows the user to define the renaming
37
     * of specific columns with a rename array that contains column names as
38
     * keys and result alias as values.
39
     *
40
     * @var int
41
     */
42
    const COLUMN_RENAMING_CUSTOM = 2;
43
44
    /**
45
     * Incremental renaming uses a result set mapping internal counter to add a
46
     * number to each column result, leading to uniqueness. This only works if
47
     * you use {@see generateSelectClause()} to generate the SELECT clause for
48
     * you.
49
     *
50
     * @var int
51
     */
52
    const COLUMN_RENAMING_INCREMENT = 3;
53
54
    /**
55
     * @var int
56
     */
57
    private $sqlCounter = 0;
58
59
    /**
60
     * @var EntityManagerInterface
61
     */
62
    private $em;
63
64
    /**
65
     * Default column renaming mode.
66
     *
67
     * @var int
68
     */
69
    private $defaultRenameMode;
70
71
    /**
72
     * @param EntityManagerInterface $em
73
     * @param integer                $defaultRenameMode
74
     */
75
    public function __construct(EntityManagerInterface $em, $defaultRenameMode = self::COLUMN_RENAMING_NONE)
76
    {
77
        $this->em                = $em;
78
        $this->defaultRenameMode = $defaultRenameMode;
79
    }
80
81
    /**
82
     * Adds a root entity and all of its fields to the result set.
83
     *
84
     * @param string   $class          The class name of the root entity.
85 57
     * @param string   $alias          The unique alias to use for the root entity.
86
     * @param array    $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName).
87 57
     * @param int|null $renameMode     One of the COLUMN_RENAMING_* constants or array for BC reasons (CUSTOM).
88 57
     *
89 57
     * @return void
90
     */
91 View Code Duplication
    public function addRootEntityFromClassMetadata(
92
        string $class,
93
        string $alias,
94
        array $renamedColumns = [],
95
        int $renameMode = null
96
    )
97
    {
98
        $renameMode = $renameMode ?: (empty($renamedColumns) ? $this->defaultRenameMode : self::COLUMN_RENAMING_CUSTOM);
99
100
        $this->addEntityResult($class, $alias);
101 38
        $this->addAllClassFields($class, $alias, $renamedColumns, $renameMode);
102
    }
103 38
104 38
    /**
105
     * Adds a joined entity and all of its fields to the result set.
106 38
     *
107 38
     * @param string   $class          The class name of the joined entity.
108 37
     * @param string   $alias          The unique alias to use for the joined entity.
109
     * @param string   $parentAlias    The alias of the entity result that is the parent of this joined result.
110
     * @param string   $relation       The association field that connects the parent entity result
111
     *                                 with the joined entity result.
112
     * @param array    $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName).
113
     * @param int|null $renameMode     One of the COLUMN_RENAMING_* constants or array for BC reasons (CUSTOM).
114
     *
115
     * @return void
116
     */
117 View Code Duplication
    public function addJoinedEntityFromClassMetadata(
118
        string $class,
119
        string $alias,
120
        string $parentAlias,
121
        string $relation,
122
        array $renamedColumns = [],
123 12
        int $renameMode = null
124
    )
125 12
    {
126 12
        $renameMode = $renameMode ?: (empty($renamedColumns) ? $this->defaultRenameMode : self::COLUMN_RENAMING_CUSTOM);
127
128 12
        $this->addJoinedEntityResult($class, $alias, $parentAlias, $relation);
129 12
        $this->addAllClassFields($class, $alias, $renamedColumns, $renameMode);
130 11
    }
131
132
    /**
133
     * Adds all fields of the given class to the result set mapping (columns and meta fields).
134
     *
135
     * @param string $class
136
     * @param string $alias
137
     * @param array  $customRenameColumns
138
     *
139
     * @return void
140
     *
141
     * @throws \InvalidArgumentException
142
     */
143 38
    protected function addAllClassFields(string $class, string $alias, array $customRenameColumns, int $renameMode) : void
144
    {
145 38
        /** @var ClassMetadata $classMetadata */
146 38
        $classMetadata = $this->em->getClassMetadata($class);
147
        $platform      = $this->em->getConnection()->getDatabasePlatform();
148 38
149 1
        if (! $this->isInheritanceSupported($classMetadata)) {
150
            throw new \InvalidArgumentException(
151
                'ResultSetMapping builder does not currently support your inheritance scheme.'
152
            );
153 37
        }
154 37
155 37
        foreach ($classMetadata->getDeclaredPropertiesIterator() as $property) {
156
            switch (true) {
157 37 View Code Duplication
                case ($property instanceof FieldMetadata):
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...
158 1
                    $columnName  = $property->getColumnName();
159
                    $columnAlias = $platform->getSQLResultCasing(
160
                        $this->getColumnAlias($columnName, $renameMode, $customRenameColumns)
161 37
                    );
162
163
                    if (isset($this->fieldMappings[$columnAlias])) {
164 37
                        throw new \InvalidArgumentException(
165 28
                            sprintf("The column '%s' conflicts with another column in the mapper.", $columnName)
166 22
                        );
167 22
                    }
168
169 22
                    $this->addFieldResult($alias, $columnAlias, $property->getName());
170 22
                    break;
171 22
172 22 View Code Duplication
                case ($property instanceof ToOneAssociationMetadata && $property->isOwningSide()):
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...
173
                    $targetClass = $this->em->getClassMetadata($property->getTargetEntity());
174 22
175
                    foreach ($property->getJoinColumns() as $joinColumn) {
176
                        /** @var JoinColumnMetadata $joinColumn */
177
                        $columnName           = $joinColumn->getColumnName();
178 28
                        $referencedColumnName = $joinColumn->getReferencedColumnName();
179
                        $columnAlias          = $platform->getSQLResultCasing(
180
                            $this->getColumnAlias($columnName, $renameMode, $customRenameColumns)
181
                        );
182 37
183
                        if (isset($this->metaMappings[$columnAlias])) {
184 38
                            throw new \InvalidArgumentException(
185
                                sprintf("The column '%s' conflicts with another column in the mapper.", $columnName)
186 38
                            );
187 38
                        }
188 3
189
                        if (! $joinColumn->getType()) {
190
                            $joinColumn->setType(PersisterHelper::getTypeOfColumn($referencedColumnName, $targetClass, $this->em));
0 ignored issues
show
Documentation introduced by
$targetClass is of type object<Doctrine\Common\P...\Mapping\ClassMetadata>, but the function expects a object<Doctrine\ORM\Mapping\ClassMetadata>.

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...
191 36
                        }
192
193
                        $this->addMetaResult($alias, $columnAlias, $columnName, $property->isPrimaryKey(), $joinColumn->getType());
0 ignored issues
show
Bug introduced by
It seems like $joinColumn->getType() can be null; however, addMetaResult() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
194
                    }
195
                    break;
196
            }
197
        }
198
    }
199
200
    /**
201
     * Checks if inheritance if supported.
202
     *
203 38
     * @param ClassMetadata $metadata
204
     *
205
     * @return boolean
206 38
     */
207 3
    private function isInheritanceSupported(ClassMetadata $metadata)
208
    {
209 35
        if ($metadata->inheritanceType === InheritanceType::SINGLE_TABLE
210 11
            && in_array($metadata->getClassName(), $metadata->discriminatorMap, true)) {
211 11
            return true;
212
        }
213 34
214 34
        return ! in_array($metadata->inheritanceType, [InheritanceType::SINGLE_TABLE, InheritanceType::JOINED]);
215
    }
216
217
    /**
218
     * Gets column alias for a given column.
219
     *
220
     * @param string $columnName
221
     * @param int    $mode
222
     * @param array  $customRenameColumns
223
     *
224
     * @return string
225
     */
226
    private function getColumnAlias($columnName, $mode, array $customRenameColumns)
227
    {
228
        switch ($mode) {
229
            case self::COLUMN_RENAMING_INCREMENT:
230 38
                return $columnName . $this->sqlCounter++;
231
232 38
            case self::COLUMN_RENAMING_CUSTOM:
233 11
                return $customRenameColumns[$columnName] ?? $columnName;
234
235
            case self::COLUMN_RENAMING_NONE:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
236 38
                return $columnName;
237 38
238
        }
239 38
    }
240 38
241
    /**
242
     * Adds the mappings of the results of native SQL queries to the result set.
243 38
     *
244 29
     * @param ClassMetadata $class
245 23
     * @param array         $queryMapping
246 23
     *
247 29
     * @return ResultSetMappingBuilder
248
     */
249
    public function addNamedNativeQueryMapping(ClassMetadata $class, array $queryMapping)
250
    {
251
        if (isset($queryMapping['resultClass'])) {
252 38
            $entityClass = ($queryMapping['resultClass'] === '__CLASS__')
253
                ? $class
254
                : $this->em->getClassMetadata($queryMapping['resultClass'])
255
            ;
256
257
            $this->addEntityResult($entityClass->getClassName(), 'e0');
0 ignored issues
show
Bug introduced by
The method getClassName does only exist in Doctrine\ORM\Mapping\ClassMetadata, but not in Doctrine\Common\Persistence\Mapping\ClassMetadata.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
258
            $this->addNamedNativeQueryEntityResultMapping($entityClass, [], 'e0');
0 ignored issues
show
Bug introduced by
It seems like $entityClass defined by $queryMapping['resultCla...Mapping['resultClass']) on line 252 can also be of type object<Doctrine\Common\P...\Mapping\ClassMetadata>; however, Doctrine\ORM\Query\Resul...ryEntityResultMapping() does only seem to accept object<Doctrine\ORM\Mapping\ClassMetadata>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
259
260
            return $this;
261
        }
262
263 10
        return $this->addNamedNativeQueryResultSetMapping($class, $queryMapping['resultSetMapping']);
264
    }
265 10
266 3
    /**
267
     * Adds the result set mapping of the results of native SQL queries to the result set.
268
     *
269 8
     * @param ClassMetadata $class
270
     * @param string        $resultSetMappingName
271
     *
272
     * @return ResultSetMappingBuilder
273
     */
274
    public function addNamedNativeQueryResultSetMapping(ClassMetadata $class, $resultSetMappingName)
275
    {
276
        $counter        = 0;
277
        $resultMapping  = $class->getSqlResultSetMapping($resultSetMappingName);
278
        $rootAlias      = 'e' . $counter;
279
280 3
        if (isset($resultMapping['entities'])) {
281
            foreach ($resultMapping['entities'] as $key => $entityMapping) {
282 3
                $entityMapping['entityClass'] = ($entityMapping['entityClass'] === '__CLASS__')
283 3
                    ? $class->getClassName()
284 3
                    : $entityMapping['entityClass']
285
                ;
286 3
287
                $classMetadata = $this->em->getClassMetadata($entityMapping['entityClass']);
288 3
289 1
                if ($class->getClassName() === $classMetadata->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...
290 1
                    $this->addEntityResult($classMetadata->getClassName(), $rootAlias);
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...
291 1
                    $this->addNamedNativeQueryEntityResultMapping($classMetadata, $entityMapping, $rootAlias);
0 ignored issues
show
Documentation introduced by
$classMetadata is of type object<Doctrine\Common\P...\Mapping\ClassMetadata>, but the function expects a object<Doctrine\ORM\Mapping\ClassMetadata>.

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...
292
                } else {
293 1
                    $joinAlias = 'e' . ++$counter;
294 1
295
                    $this->addNamedNativeQueryEntityResultMapping($classMetadata, $entityMapping, $joinAlias);
0 ignored issues
show
Documentation introduced by
$classMetadata is of type object<Doctrine\Common\P...\Mapping\ClassMetadata>, but the function expects a object<Doctrine\ORM\Mapping\ClassMetadata>.

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...
296
297 3
                    foreach ($class->getDeclaredPropertiesIterator() as $fieldName => $association) {
298 3
                        if (! ($association instanceof AssociationMetadata)) {
299
                            continue;
300 3
                        }
301
302
                        if ($association->getTargetEntity() !== $classMetadata->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...
303 3
                            continue;
304 3
                        }
305 3
306
                        $this->addJoinedEntityResult($association->getTargetEntity(), $joinAlias, $rootAlias, $fieldName);
307 3
                    }
308 3
                }
309 3
310
            }
311 3
        }
312
313
        if (isset($resultMapping['columns'])) {
314
            foreach ($resultMapping['columns'] as $entityMapping) {
315
                // @todo guilhermeblanco Collect type information from mapped column
316 3
                $this->addScalarResult($entityMapping['name'], $entityMapping['name'], Type::getType('string'));
317
            }
318
        }
319
320
        return $this;
321
    }
322
323
    /**
324
     * Adds the entity result mapping of the results of native SQL queries to the result set.
325
     *
326
     * @param ClassMetadata $classMetadata
327 8
     * @param array         $entityMapping
328
     * @param string        $alias
329 8
     *
330 8
     * @return ResultSetMappingBuilder
331 8
     *
332 8
     * @throws MappingException
333
     * @throws \InvalidArgumentException
334 8
     */
335 8
    public function addNamedNativeQueryEntityResultMapping(ClassMetadata $classMetadata, array $entityMapping, $alias)
336 8
    {
337
        $platform = $this->em->getConnection()->getDatabasePlatform();
338 8
339 8
        // Always fetch discriminator column. It's required for Proxy loading. We only adjust naming if provided
340 8
        if ($classMetadata->discriminatorColumn) {
341
            $discrColumn     = $classMetadata->discriminatorColumn;
342 2
            $discrColumnName = $entityMapping['discriminatorColumn'] ?? $discrColumn->getColumnName();
343 2
            $discrColumnType = $discrColumn->getType();
344 2
345
            $this->setDiscriminatorColumn($alias, $discrColumnName);
346 2
            $this->addMetaResult($alias, $discrColumnName, $discrColumnName, false, $discrColumnType);
0 ignored issues
show
Bug introduced by
It seems like $discrColumnType defined by $discrColumn->getType() on line 343 can be null; however, Doctrine\ORM\Query\Resul...apping::addMetaResult() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
347
        }
348 2
349 8
        if (isset($entityMapping['fields']) && ! empty($entityMapping['fields'])) {
350
            foreach ($entityMapping['fields'] as $field) {
351
                $fieldName = $field['name'];
352
                $relation  = null;
353
354
                if (strpos($fieldName, '.') !== false) {
355
                    list($relation, $fieldName) = explode('.', $fieldName);
356 8
                }
357 8
358 4
                $property = $classMetadata->getProperty($fieldName);
359
360 4
                if (! $relation && $property instanceof FieldMetadata) {
361
                    $this->addFieldResult($alias, $field['column'], $fieldName, $classMetadata->getClassName());
362 4
363
                    continue;
364
                }
365
366 8
                $property = $classMetadata->getProperty($relation);
367
368
                if (! $property) {
369
                    throw new \InvalidArgumentException(
370
                        "Entity '".$classMetadata->getClassName()."' has no field '".$relation."'. "
371
                    );
372
                }
373
374
                if ($property instanceof AssociationMetadata) {
375
                    if (! $relation) {
376
                        $this->addFieldResult($alias, $field['column'], $fieldName, $classMetadata->getClassName());
377
378
                        continue;
379
                    }
380
381 8
                    $joinAlias   = $alias.$relation;
382
                    $parentAlias = $alias;
383 8
384 1
                    $this->addJoinedEntityResult($property->getTargetEntity(), $joinAlias, $parentAlias, $relation);
385 1
                    $this->addFieldResult($joinAlias, $field['column'], $fieldName);
386 1
                }
387
            }
388 1
        } else {
389 1
            foreach ($classMetadata->getDeclaredPropertiesIterator() as $property) {
390
                switch (true) {
391 View Code Duplication
                    case ($property instanceof FieldMetadata):
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...
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
392 8
                        $columnName  = $property->getColumnName();
393 7
                        $columnAlias = $platform->getSQLResultCasing($columnName);
394 7
395 7
                        if (isset($this->fieldMappings[$columnAlias])) {
396
                            throw new \InvalidArgumentException(
397 7
                                sprintf("The column '%s' conflicts with another column in the mapper.", $columnName)
398 2
                            );
399
                        }
400
401 7
                        $this->addFieldResult($alias, $columnAlias, $property->getName());
402 2
                        break;
403 2
404 2 View Code Duplication
                    case ($property instanceof ToOneAssociationMetadata && $property->isOwningSide()):
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...
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
405 2
                        $targetClass = $this->em->getClassMetadata($property->getTargetEntity());
406
407 2
                        foreach ($property->getJoinColumns() as $joinColumn) {
408 2
                            /** @var JoinColumnMetadata $joinColumn */
409
                            $columnName           = $joinColumn->getColumnName();
410 2
                            $referencedColumnName = $joinColumn->getReferencedColumnName();
411
                            $columnAlias          = $platform->getSQLResultCasing($columnName);
412
413 7
                            if (isset($this->metaMappings[$columnAlias])) {
414
                                throw new \InvalidArgumentException(
415
                                    sprintf("The column '%s' conflicts with another column in the mapper.", $columnName)
416
                                );
417 7
                            }
418
419
                            if (! $joinColumn->getType()) {
420
                                $joinColumn->setType(PersisterHelper::getTypeOfColumn($referencedColumnName, $targetClass, $this->em));
0 ignored issues
show
Documentation introduced by
$targetClass is of type object<Doctrine\Common\P...\Mapping\ClassMetadata>, but the function expects a object<Doctrine\ORM\Mapping\ClassMetadata>.

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...
421
                            }
422 1
423 1
                            $this->addMetaResult($alias, $columnAlias, $columnName, $property->isPrimaryKey(), $joinColumn->getType());
0 ignored issues
show
Bug introduced by
It seems like $joinColumn->getType() can be null; however, addMetaResult() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
424
                        }
425 1
                        break;
426
                }
427
            }
428
        }
429 8
430
        return $this;
431
    }
432
433
    /**
434
     * Generates the Select clause from this ResultSetMappingBuilder.
435
     *
436
     * Works only for all the entity results. The select parts for scalar
437
     * expressions have to be written manually.
438
     *
439
     * @param array $tableAliases
440
     *
441
     * @return string
442 13
     */
443
    public function generateSelectClause($tableAliases = [])
444 13
    {
445
        $sql = "";
446 13
447 13
        foreach ($this->columnOwnerMap as $columnName => $dqlAlias) {
448 13
            $tableAlias = isset($tableAliases[$dqlAlias])
449
                ? $tableAliases[$dqlAlias] : $dqlAlias;
450 13
451 13
            if ($sql) {
452
                $sql .= ", ";
453
            }
454 13
455
            $sql .= $tableAlias . ".";
456 13
457 13
            if (isset($this->fieldMappings[$columnName])) {
458 13
                $class = $this->em->getClassMetadata($this->declaringClasses[$columnName]);
459 7
                $field = $this->fieldMappings[$columnName];
460 6
                $sql  .= $class->getProperty($field)->getColumnName();
0 ignored issues
show
Bug introduced by
The method getProperty() 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...
461 1
            } else if (isset($this->metaMappings[$columnName])) {
462 1
                $sql .= $this->metaMappings[$columnName];
463
            } else if (isset($this->discriminatorColumns[$dqlAlias])) {
464
                $sql .= $this->discriminatorColumns[$dqlAlias];
465 13
            }
466
467
            $sql .= " AS " . $columnName;
468 13
        }
469
470
        return $sql;
471
    }
472
473
    /**
474 1
     * @return string
475
     */
476 1
    public function __toString()
477
    {
478
        return $this->generateSelectClause([]);
479
    }
480
}
481