Completed
Push — master ( 8c953e...7fbcf6 )
by Thomas
37s
created

ManyToMany::getTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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