Completed
Branch feature-relations (7f62b3)
by Thomas
03:51
created

ManyToMany::deleteRelated()   C

Complexity

Conditions 8
Paths 12

Size

Total Lines 43
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 8

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 43
ccs 26
cts 26
cp 1
rs 5.3846
cc 8
eloc 25
nc 12
nop 3
crap 8
1
<?php
2
3
namespace ORM\Relation;
4
5
use ORM\Entity;
6
use ORM\EntityFetcher;
7
use ORM\EntityManager;
8
use ORM\Exceptions\IncompletePrimaryKey;
9
use ORM\Exceptions\InvalidRelation;
10
use ORM\QueryBuilder\QueryBuilder;
11
use ORM\Relation;
12
13
class ManyToMany extends Relation
14
{
15
    /** The table that holds the foreign keys
16
     * @var string'categories */
17
    protected $table;
18
19
    /**
20
     * ManyToMany constructor.
21
     *
22
     * @param string $name
23
     * @param string $class
24
     * @param array  $reference
25
     * @param string $opponent
26
     * @param string $table
27
     * @codeCoverageIgnore don't know why this should be uncovered
28
     */
29
    public function __construct($name, $class, array $reference, $opponent, $table)
30
    {
31
        $this->name = $name;
32
        $this->class = $class;
33
        $this->opponent = $opponent;
34
        $this->reference = $reference;
35
        $this->table = $table;
36
    }
37
38
    /**
39
     * @return string
40
     */
41 2
    public function getTable()
42
    {
43 2
        return $this->table;
44
    }
45
46
    /** {@inheritdoc} */
47 5
    public function fetch(Entity $me, EntityManager $entityManager = null)
48
    {
49
50 5
        $foreignKey = $this->getForeignKey($me, $this->reference);
51
        /** @var EntityFetcher $fetcher */
52 4
        $fetcher = $entityManager->fetch($this->class);
0 ignored issues
show
Bug introduced by
It seems like $entityManager is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
53 4
        $table = $entityManager->escapeIdentifier($this->table);
54
55 4
        $expression = [];
56 4
        foreach ($this->getOpponent()->getReference() as $t0Var => $fkCol) {
57 4
            $expression[] = $table . '.' . $entityManager->escapeIdentifier($fkCol) . ' = t0.' . $t0Var;
58
        }
59
60 4
        $fetcher->join($table, implode(' AND ', $expression));
61
62 4
        foreach ($foreignKey as $col => $value) {
63 4
            $fetcher->where($table . '.' . $entityManager->escapeIdentifier($col), $value);
64
        }
65 4
        return $fetcher;
66
    }
67
68
    /** {@inheritdoc} */
69 1
    public function fetchAll(Entity $me, EntityManager $entityManager)
70
    {
71 1
        $foreignKey = $this->getForeignKey($me, $this->reference);
72 1
        $table = $entityManager->escapeIdentifier($this->table);
73
74 1
        $query = new QueryBuilder($table, '', $entityManager);
75
76 1
        foreach ($this->getOpponent()->getReference() as $t0Var => $fkCol) {
77 1
            $query->column($entityManager->escapeIdentifier($fkCol));
78
        }
79
80 1
        foreach ($foreignKey as $col => $value) {
81 1
            $query->where($entityManager->escapeIdentifier($col), $value);
82
        }
83
84 1
        $result = $entityManager->getConnection()->query($query->getQuery());
85 1
        $primaryKeys = $result->fetchAll(\PDO::FETCH_NUM);
86
87
        /** @var Entity[] $result */
88 1
        $result = [];
89 1
        foreach ($primaryKeys as $primaryKey) {
90 1
            if ($me = $entityManager->fetch($this->class, $primaryKey)) {
91 1
                $result[] = $me;
92
            }
93
        }
94
95 1
        return $result;
96
    }
97
98
    /** {@inheritdoc} */
99 6
    public function addRelated(Entity $me, array $entities, EntityManager $entityManager)
100
    {
101 6
        if (empty($entities)) {
102 1
            return;
103
        }
104
105 5
        $table = $entityManager->escapeIdentifier($this->table);
106
107 5
        $cols = [];
108 5
        $baseAssociation = [];
109 5
        foreach ($this->reference as $myVar => $fkCol) {
110 5
            $cols[]            = $entityManager->escapeIdentifier($fkCol);
111 5
            $value             = $me->__get($myVar);
112
113 5
            if ($value === null) {
114 1
                throw new IncompletePrimaryKey('Key incomplete to save foreign key');
115
            }
116
117 4
            $baseAssociation[] = $entityManager->escapeValue($value);
118
        }
119
120 4
        $associations = [];
121 4
        foreach ($entities as $entity) {
122 4
            if (!$entity instanceof $this->class) {
123 1
                throw new InvalidRelation('Invalid entity for relation ' . $this->name);
124
            }
125
126 4
            $association = $baseAssociation;
127 4
            foreach ($this->getOpponent()->getReference() as $hisVar => $fkCol) {
128 4
                if (empty($associations)) {
129 4
                    $cols[] = $entityManager->escapeIdentifier($fkCol);
130
                }
131 4
                $value = $entity->__get($hisVar);
132
133 4
                if ($value === null) {
134 1
                    throw new IncompletePrimaryKey('Key incomplete to save foreign key');
135
                }
136
137 4
                $association[] = $entityManager->escapeValue($value);
138
            }
139 4
            $associations[] = implode(',', $association);
140
        }
141
142 2
        $statement = 'INSERT INTO ' . $table . ' (' . implode(',', $cols) . ') ' .
143 2
                     'VALUES (' . implode('),(', $associations) . ')';
144 2
        $entityManager->getConnection()->query($statement);
145 2
    }
146
147
    /** {@inheritdoc} */
148 6
    public function deleteRelated(Entity $me, array $entities, EntityManager $entityManager)
149
    {
150 6
        if (empty($entities)) {
151 1
            return;
152
        }
153
154 5
        $table = $entityManager->escapeIdentifier($this->table);
155 5
        $where = [];
156
157 5
        foreach ($this->reference as $myVar => $fkCol) {
158 5
            $value = $me->__get($myVar);
159
160 5
            if ($value === null) {
161 1
                throw new IncompletePrimaryKey('Key incomplete to save foreign key');
162
            }
163
164 4
            $where[] = $entityManager->escapeIdentifier($fkCol) . ' = ' .
165 4
                       $entityManager->escapeValue($value);
166
        }
167
168 4
        foreach ($entities as $entity) {
169 4
            if (!$entity instanceof $this->class) {
170 1
                throw new InvalidRelation('Invalid entity for relation ' . $this->name);
171
            }
172
173 4
            $condition = [];
174 4
            foreach ($this->getOpponent()->getReference() as $hisVar => $fkCol) {
175 4
                $value = $entity->__get($hisVar);
176
177 4
                if ($value === null) {
178 1
                    throw new IncompletePrimaryKey('Key incomplete to save foreign key');
179
                }
180
181 4
                $condition[] = $entityManager->escapeIdentifier($fkCol) . ' = ' .
182 4
                               $entityManager->escapeValue($value);
183
            }
184 4
            $where[] = implode(' AND ', $condition);
185
        }
186
187 2
        $statement = 'DELETE FROM ' . $table . ' WHERE ' . array_shift($where) . ' ' .
188 2
                     'AND (' . implode(' OR ', $where) . ')';
189 2
        $entityManager->getConnection()->query($statement);
190 2
    }
191
192
    /** {@inheritdoc} */
193 2
    public function addJoin(EntityFetcher $fetcher, $join)
194
    {
195 2
        $table = $fetcher->getEntityManager()->escapeIdentifier($this->table);
196
197 2
        $expression = [];
198 2
        foreach ($this->reference as $myVar => $col) {
199 2
            $expression[] = 't0.' . $myVar . ' = ' .
200 2
                            $table . '.' . $fetcher->getEntityManager()->escapeIdentifier($col);
201
        }
202
203 2
        call_user_func([$fetcher, $join], $table, implode(' AND ', $expression), null, [], true);
204
205 2
        $expression = [];
206 2
        foreach ($this->getOpponent()->getReference() as $hisVar => $col) {
207 2
            $expression[] = $table . '.' . $fetcher->getEntityManager()->escapeIdentifier($col) .
208 2
                            ' = ' . $this->name . '.' . $hisVar;
209
        }
210
211 2
        call_user_func([$fetcher, $join], $this->class, implode(' AND ', $expression), $this->name, [], true);
212 2
    }
213
}
214