Completed
Pull Request — master (#8105)
by
unknown
10:29
created

getSelectConditionDiscriminatorValueSQL()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3.0026

Importance

Changes 0
Metric Value
cc 3
eloc 14
c 0
b 0
f 0
nc 4
nop 0
dl 0
loc 23
ccs 14
cts 15
cp 0.9333
crap 3.0026
rs 9.7998
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\ToOneAssociationMetadata;
12
use function array_flip;
13
use function implode;
14
use function sprintf;
15
16
/**
17
 * Persister for entities that participate in a hierarchy mapped with the
18
 * SINGLE_TABLE strategy.
19
 *
20
 * @link https://martinfowler.com/eaaCatalog/singleTableInheritance.html
21
 */
22
class SingleTablePersister extends AbstractEntityInheritancePersister
23
{
24
    /**
25
     * {@inheritdoc}
26
     */
27 1
    protected function getSelectColumnsSQL()
28
    {
29 1
        if ($this->currentPersisterContext->selectColumnListSql !== null) {
30
            return $this->currentPersisterContext->selectColumnListSql;
31
        }
32
33 1
        $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...
34
35
        // Append discriminator column
36 1
        $discrColumn      = $this->class->discriminatorColumn;
37 1
        $discrTableAlias  = $this->getSQLTableAlias($discrColumn->getTableName());
38 1
        $discrColumnName  = $discrColumn->getColumnName();
39 1
        $discrColumnType  = $discrColumn->getType();
40 1
        $resultColumnName = $this->platform->getSQLResultCasing($discrColumnName);
41 1
        $quotedColumnName = $this->platform->quoteIdentifier($discrColumn->getColumnName());
42
43 1
        $this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
44 1
        $this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumnName, false, $discrColumnType);
0 ignored issues
show
Bug introduced by
It seems like $discrColumnType can also be of type null; however, parameter $type of Doctrine\ORM\Query\Resul...apping::addMetaResult() does only seem to accept Doctrine\DBAL\Types\Type, maybe add an additional type check? ( Ignorable by Annotation )

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

44
        $this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumnName, false, /** @scrutinizer ignore-type */ $discrColumnType);
Loading history...
45
46 1
        $columnList[] = $discrColumnType->convertToDatabaseValueSQL($discrTableAlias . '.' . $quotedColumnName, $this->platform);
47
48
        // Append subclass columns
49 1
        foreach ($this->class->getSubClasses() as $subClassName) {
50
            $subClass = $this->em->getClassMetadata($subClassName);
51
52
            // Subclass columns
53
            foreach ($subClass->getPropertiesIterator() as $fieldName => $property) {
0 ignored issues
show
Bug introduced by
The method getPropertiesIterator() does not exist on Doctrine\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

53
            foreach ($subClass->/** @scrutinizer ignore-call */ getPropertiesIterator() 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...
54
                if ($subClass->isInheritedProperty($fieldName)) {
0 ignored issues
show
Bug introduced by
The method isInheritedProperty() does not exist on Doctrine\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

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