Failed Conditions
Pull Request — master (#7242)
by Gabriel
08:46
created

SingleTablePersister::getSelectColumnsSQL()   C

Complexity

Conditions 10
Paths 9

Size

Total Lines 58
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 23.7467

Importance

Changes 0
Metric Value
cc 10
eloc 31
nc 9
nop 0
dl 0
loc 58
rs 6.6515
c 0
b 0
f 0
ccs 15
cts 31
cp 0.4839
crap 23.7467

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\Persisters\Entity;
6
7
use Doctrine\Common\Collections\Criteria;
8
use Doctrine\ORM\Mapping\AssociationMetadata;
9
use Doctrine\ORM\Mapping\ClassMetadata;
10
use Doctrine\ORM\Mapping\FieldMetadata;
11
use Doctrine\ORM\Mapping\JoinColumnMetadata;
12
use Doctrine\ORM\Mapping\ToOneAssociationMetadata;
13
use Doctrine\ORM\Utility\PersisterHelper;
14
use function array_flip;
15
use function implode;
16
use function sprintf;
17
18
/**
19
 * Persister for entities that participate in a hierarchy mapped with the
20
 * SINGLE_TABLE strategy.
21
 *
22
 * @link https://martinfowler.com/eaaCatalog/singleTableInheritance.html
23
 */
24
class SingleTablePersister extends AbstractEntityInheritancePersister
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29 2
    protected function getSelectColumnsSQL()
30
    {
31 2
        if ($this->currentPersisterContext->selectColumnListSql !== null) {
32
            return $this->currentPersisterContext->selectColumnListSql;
33
        }
34
35 2
        $columnList[] = parent::getSelectColumnsSQL();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$columnList was never initialized. Although not strictly required by PHP, it is generally a good practice to add $columnList = array(); before regardless.
Loading history...
36
37
        // Append discriminator column
38 2
        $discrColumn      = $this->class->discriminatorColumn;
39 2
        $discrTableAlias  = $this->getSQLTableAlias($discrColumn->getTableName());
40 2
        $discrColumnName  = $discrColumn->getColumnName();
41 2
        $discrColumnType  = $discrColumn->getType();
42 2
        $resultColumnName = $this->platform->getSQLResultCasing($discrColumnName);
43 2
        $quotedColumnName = $this->platform->quoteIdentifier($discrColumn->getColumnName());
44
45 2
        $this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
46 2
        $this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumnName, false, $discrColumnType);
47
48 2
        $columnList[] = $discrColumnType->convertToDatabaseValueSQL($discrTableAlias . '.' . $quotedColumnName, $this->platform);
49
50
        // Append subclass columns
51 2
        foreach ($this->class->getSubClasses() as $subClassName) {
52
            $subClass = $this->em->getClassMetadata($subClassName);
53
54
            // Subclass columns
55
            foreach ($subClass->getDeclaredPropertiesIterator() as $fieldName => $property) {
0 ignored issues
show
Bug introduced by
The method getDeclaredPropertiesIterator() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

55
            foreach ($subClass->/** @scrutinizer ignore-call */ getDeclaredPropertiesIterator() as $fieldName => $property) {

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...
56
                if ($subClass->isInheritedProperty($fieldName)) {
0 ignored issues
show
Bug introduced by
The method isInheritedProperty() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
                if ($subClass->/** @scrutinizer ignore-call */ isInheritedProperty($fieldName)) {

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...
57
                    continue;
58
                }
59
60
                switch (true) {
61
                    case ($property instanceof FieldMetadata):
62
                        $columnList[] = $this->getSelectColumnSQL($fieldName, $subClass);
63
                        break;
64
65
                    case ($property instanceof ToOneAssociationMetadata && $property->isOwningSide()):
66
                        $targetClass = $this->em->getClassMetadata($property->getTargetEntity());
67
68
                        foreach ($property->getJoinColumns() as $joinColumn) {
69
                            /** @var JoinColumnMetadata $joinColumn */
70
                            $referencedColumnName = $joinColumn->getReferencedColumnName();
71
72
                            if (! $joinColumn->getType()) {
73
                                $joinColumn->setType(PersisterHelper::getTypeOfColumn($referencedColumnName, $targetClass, $this->em));
74
                            }
75
76
                            $columnList[] = $this->getSelectJoinColumnSQL($joinColumn);
77
                        }
78
79
                        break;
80
                }
81
            }
82
        }
83
84 2
        $this->currentPersisterContext->selectColumnListSql = implode(', ', $columnList);
85
86 2
        return $this->currentPersisterContext->selectColumnListSql;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92 4
    protected function getInsertColumnList()
93
    {
94 4
        $columns = parent::getInsertColumnList();
95
96
        // Add discriminator column to the INSERT SQL
97 4
        $discrColumn     = $this->class->discriminatorColumn;
98 4
        $discrColumnName = $discrColumn->getColumnName();
99
100 4
        $columns[] = $discrColumnName;
101
102 4
        $this->columns[$discrColumnName] = $discrColumn;
103
104 4
        return $columns;
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 2
    protected function getSQLTableAlias($tableName, $assocName = '')
111
    {
112 2
        return parent::getSQLTableAlias($this->class->getTableName(), $assocName);
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 2
    protected function getSelectConditionSQL(array $criteria, ?AssociationMetadata $association = null)
119
    {
120 2
        $conditionSql = parent::getSelectConditionSQL($criteria, $association);
121
122 2
        if ($conditionSql) {
123 2
            $conditionSql .= ' AND ';
124
        }
125
126 2
        return $conditionSql . $this->getSelectConditionDiscriminatorValueSQL();
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    protected function getSelectConditionCriteriaSQL(Criteria $criteria)
133
    {
134
        $conditionSql = parent::getSelectConditionCriteriaSQL($criteria);
135
136
        if ($conditionSql) {
137
            $conditionSql .= ' AND ';
138
        }
139
140
        return $conditionSql . $this->getSelectConditionDiscriminatorValueSQL();
141
    }
142
143
    /**
144
     * @return string
145
     */
146 2
    protected function getSelectConditionDiscriminatorValueSQL()
147
    {
148 2
        $values = [];
149
150 2
        if ($this->class->discriminatorValue !== null) { // discriminators can be 0
151 2
            $values[] = $this->conn->quote($this->class->discriminatorValue);
152
        }
153
154 2
        $discrValues = array_flip($this->class->discriminatorMap);
155
156 2
        foreach ($this->class->getSubClasses() as $subclassName) {
157
            $values[] = $this->conn->quote($discrValues[$subclassName]);
158
        }
159
160 2
        $discrColumn      = $this->class->discriminatorColumn;
161 2
        $discrColumnType  = $discrColumn->getType();
162 2
        $tableAlias       = $this->getSQLTableAlias($discrColumn->getTableName());
163 2
        $quotedColumnName = $this->platform->quoteIdentifier($discrColumn->getColumnName());
164
165 2
        return sprintf(
166 2
            '%s IN (%s)',
167 2
            $discrColumnType->convertToDatabaseValueSQL($tableAlias . '.' . $quotedColumnName, $this->platform),
168 2
            implode(', ', $values)
169
        );
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175 2
    protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias)
176
    {
177
        // Ensure that the filters are applied to the root entity of the inheritance tree
178 2
        $targetEntity = $this->em->getClassMetadata($targetEntity->getRootClassName());
179
        // we don't care about the $targetTableAlias, in a STI there is only one table.
180
181 2
        return parent::generateFilterConditionSQL($targetEntity, $targetTableAlias);
182
    }
183
}
184