ManyToMany::deleteRelated()   B
last analyzed

Complexity

Conditions 8
Paths 12

Size

Total Lines 43

Duplication

Lines 20
Ratio 46.51 %

Code Coverage

Tests 26
CRAP Score 8

Importance

Changes 0
Metric Value
dl 20
loc 43
rs 7.9875
c 0
b 0
f 0
ccs 26
cts 26
cp 1
cc 8
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\Exception\IncompletePrimaryKey;
9
use ORM\Exception\InvalidRelation;
10
use ORM\QueryBuilder\QueryBuilder;
11
use ORM\Relation;
12
use PDO;
13
14
/**
15
 * ManyToMany Relation
16
 *
17
 * @package ORM\Relation
18
 * @author  Thomas Flori <[email protected]>
19
 */
20
class ManyToMany extends Relation
21
{
22
    /** The table that holds the foreign keys
23
     * @var string'categories */
24
    protected $table;
25
26
    /**
27
     * ManyToMany constructor.
28
     *
29
     * @param string $name
30
     * @param string $class
31
     * @param array  $reference
32
     * @param string $opponent
33
     * @param string $table
34 2
     */
35
    public function __construct($name, $class, array $reference, $opponent, $table)
36 2
    {
37 2
        $this->name      = $name;
38 2
        $this->class     = $class;
39 2
        $this->opponent  = $opponent;
40 2
        $this->reference = $reference;
41 2
        $this->table     = $table;
42
    }
43
44
    /**
45
     * @return string
46 2
     */
47
    public function getTable()
48 2
    {
49
        return $this->table;
50
    }
51
52 7
    /** {@inheritdoc} */
53
    public function fetch(Entity $self, EntityManager $entityManager)
54
    {
55 7
56
        $foreignKey = $this->getForeignKey($self, $this->reference);
57 6
        /** @var EntityFetcher $fetcher */
58 6
        $fetcher = $entityManager->fetch($this->class);
59
        $table   = $entityManager->escapeIdentifier($this->table);
60 6
61 6
        $expression = [];
62 6
        foreach ($this->getOpponent()->getReference() as $t0Var => $fkCol) {
63
            $expression[] = $table . '.' . $entityManager->escapeIdentifier($fkCol) . ' = t0.' . $t0Var;
64
        }
65 6
66
        $fetcher->join($table, implode(' AND ', $expression));
67 6
68 6
        foreach ($foreignKey as $col => $value) {
69
            $fetcher->where($table . '.' . $entityManager->escapeIdentifier($col), $value);
70 6
        }
71
        return $fetcher;
72
    }
73
74 1
    /** {@inheritdoc} */
75
    public function fetchAll(Entity $self, EntityManager $entityManager)
76 1
    {
77 1
        $foreignKey = $this->getForeignKey($self, $this->reference);
78
        $table      = $entityManager->escapeIdentifier($this->table);
79 1
80
        $query = new QueryBuilder($table, '', $entityManager);
81 1
82 1
        foreach ($this->getOpponent()->getReference() as $t0Var => $fkCol) {
83
            $query->column($entityManager->escapeIdentifier($fkCol));
84
        }
85 1
86 1
        foreach ($foreignKey as $col => $value) {
87
            $query->where($entityManager->escapeIdentifier($col), $value);
88
        }
89 1
90 1
        $result      = $entityManager->getConnection()->query($query->getQuery());
91
        $primaryKeys = $result->fetchAll(PDO::FETCH_NUM);
92
93 1
        /** @var Entity[] $result */
94 1
        $result = [];
95 1
        foreach ($primaryKeys as $primaryKey) {
96 1
            if ($self = $entityManager->fetch($this->class, $primaryKey)) {
97
                $result[] = $self;
98
            }
99
        }
100 1
101
        return $result;
102
    }
103
104 7
    /** {@inheritdoc}
105
     * @throws IncompletePrimaryKey
106 7
     * @throws InvalidRelation
107 1
     * @throws IncompletePrimaryKey
108
     */
109
    public function addRelated(Entity $self, array $entities, EntityManager $entityManager)
110 6
    {
111
        if (empty($entities)) {
112 6
            return;
113 6
        }
114 6
115 6
        $table = $entityManager->escapeIdentifier($this->table);
116 6
117
        $cols            = [];
118 6
        $baseAssociation = [];
119 1
        foreach ($this->reference as $myVar => $fkCol) {
120
            $cols[] = $entityManager->escapeIdentifier($fkCol);
121
            $value  = $self->__get($myVar);
122 5
123
            if ($value === null) {
124
                throw new IncompletePrimaryKey('Key incomplete to save foreign key');
125 5
            }
126 5
127 5
            $baseAssociation[] = $entityManager->escapeValue($value);
128 1
        }
129
130
        $associations = [];
131 5
        foreach ($entities as $entity) {
132 5
            if (!$entity instanceof $this->class) {
133 5
                throw new InvalidRelation('Invalid entity for relation ' . $this->name);
134 5
            }
135
136 5
            $association = $baseAssociation;
137
            foreach ($this->getOpponent()->getReference() as $hisVar => $fkCol) {
138 5
                if (empty($associations)) {
139 1
                    $cols[] = $entityManager->escapeIdentifier($fkCol);
140
                }
141
                $value = $entity->__get($hisVar);
142 5
143
                if ($value === null) {
144 5
                    throw new IncompletePrimaryKey('Key incomplete to save foreign key');
145
                }
146
147 3
                $association[] = $entityManager->escapeValue($value);
148 3
            }
149 3
            $associations[] = implode(',', $association);
150 3
        }
151
152
        $statement = 'INSERT INTO ' . $table . ' (' . implode(',', $cols) . ') ' .
153 7
                     'VALUES (' . implode('),(', $associations) . ')';
154
        $entityManager->getConnection()->query($statement);
155 7
    }
156 1
157
    /** {@inheritdoc}
158
     * @throws IncompletePrimaryKey
159 6
     * @throws InvalidRelation
160 6
     * @throws IncompletePrimaryKey
161
     */
162 6
    public function deleteRelated(Entity $self, array $entities, EntityManager $entityManager)
163 6
    {
164
        if (empty($entities)) {
165 6
            return;
166 1
        }
167
168
        $table = $entityManager->escapeIdentifier($this->table);
169 5
        $where = [];
170 5
171 View Code Duplication
        foreach ($this->reference as $myVar => $fkCol) {
172
            $value = $self->__get($myVar);
173 5
174 5
            if ($value === null) {
175 1
                throw new IncompletePrimaryKey('Key incomplete to save foreign key');
176
            }
177
178 5
            $where[] = $entityManager->escapeIdentifier($fkCol) . ' = ' .
179 5
                       $entityManager->escapeValue($value);
180 5
        }
181
182 5
        foreach ($entities as $entity) {
183 1
            if (!$entity instanceof $this->class) {
184
                throw new InvalidRelation('Invalid entity for relation ' . $this->name);
185
            }
186 5
187 5
            $condition = [];
188 View Code Duplication
            foreach ($this->getOpponent()->getReference() as $hisVar => $fkCol) {
189 5
                $value = $entity->__get($hisVar);
190
191
                if ($value === null) {
192 3
                    throw new IncompletePrimaryKey('Key incomplete to save foreign key');
193 3
                }
194 3
195 3
                $condition[] = $entityManager->escapeIdentifier($fkCol) . ' = ' .
196
                               $entityManager->escapeValue($value);
197
            }
198 2
            $where[] = implode(' AND ', $condition);
199
        }
200 2
201
        $statement = 'DELETE FROM ' . $table . ' WHERE ' . array_shift($where) . ' ' .
202 2
                     'AND (' . implode(' OR ', $where) . ')';
203 2
        $entityManager->getConnection()->query($statement);
204 2
    }
205 2
206
    /** {@inheritdoc} */
207
    public function addJoin(EntityFetcher $fetcher, $join, $alias)
208 2
    {
209
        $table = $fetcher->getEntityManager()->escapeIdentifier($this->table);
210 2
211 2
        $expression = [];
212 2
        foreach ($this->reference as $myVar => $col) {
213 2
            $expression[] = $alias . '.' . $myVar . ' = ' .
214
                            $table . '.' . $fetcher->getEntityManager()->escapeIdentifier($col);
215
        }
216 2
217 2
        call_user_func([ $fetcher, $join ], $table, implode(' AND ', $expression), null, [], true);
218
219
        $expression = [];
220
        foreach ($this->getOpponent()->getReference() as $hisVar => $col) {
221
            $expression[] = $table . '.' . $fetcher->getEntityManager()->escapeIdentifier($col) .
222
                            ' = ' . $this->name . '.' . $hisVar;
223
        }
224
225
        call_user_func([ $fetcher, $join ], $this->class, implode(' AND ', $expression), $this->name, [], true);
226
    }
227
}
228