1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
namespace Suricate; |
3
|
|
|
|
4
|
|
|
class PivotTable extends DBObject |
5
|
|
|
{ |
6
|
|
|
protected $references = []; |
7
|
|
|
protected $collectionClass = DBCollection::class; |
8
|
|
|
|
9
|
|
|
public function __construct() |
10
|
|
|
{ |
11
|
|
|
parent::__construct(); |
12
|
|
|
|
13
|
|
|
foreach ($this->references as $referenceName => $referenceData) { |
14
|
|
|
$this->relations[$referenceName] = [ |
15
|
|
|
'type' => self::RELATION_ONE_ONE, |
16
|
|
|
'source' => $referenceData['key'], |
17
|
|
|
'target' => $referenceData['type'] |
18
|
|
|
]; |
19
|
|
|
} |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
public function getCollectionClass() |
23
|
|
|
{ |
24
|
|
|
return $this->collectionClass; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
public static function loadFor( |
28
|
|
|
$relation, |
29
|
|
|
$parentId, |
30
|
|
|
$target = null, |
31
|
|
|
$validate = null |
32
|
|
|
) { |
33
|
|
|
$pivot = new static(); |
34
|
|
|
$pivot->connectDB(); |
35
|
|
|
|
36
|
|
|
$items = []; |
37
|
|
|
if ($target !== null) { |
38
|
|
|
$className = $pivot->getTargetForRelation($target); |
39
|
|
|
$targetClass = $className; |
40
|
|
|
$sourceField = $pivot->getSourceFieldForRelation($target); |
41
|
|
|
|
42
|
|
|
$query = "SELECT t.* FROM " . $className::tableName() . " t"; |
43
|
|
|
$query .= " LEFT JOIN " . $pivot->getTableName() . " p"; |
44
|
|
|
$query .= |
45
|
|
|
" ON p.`" . |
46
|
|
|
$sourceField . |
47
|
|
|
"`=t." . |
48
|
|
|
$className::tableIndex(); |
49
|
|
|
$query .= " WHERE"; |
50
|
|
|
$query .= |
51
|
|
|
" `" . |
52
|
|
|
$pivot->getSourceFieldForRelation($relation) . |
53
|
|
|
"` = :id"; |
54
|
|
|
$query .= " GROUP BY t." . $targetClass::tableIndex(); |
55
|
|
|
} else { |
56
|
|
|
$query = "SELECT *"; |
57
|
|
|
$query .= " FROM `" . $pivot->getTableName() . "`"; |
58
|
|
|
$query .= " WHERE"; |
59
|
|
|
$query .= |
60
|
|
|
" `" . |
61
|
|
|
$pivot->getSourceFieldForRelation($relation) . |
62
|
|
|
"` = :id"; |
63
|
|
|
|
64
|
|
|
$targetClass = $pivot; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
$params = ['id' => $parentId]; |
68
|
|
|
|
69
|
|
|
$results = $pivot->dbLink |
70
|
|
|
->query($query, $params) |
71
|
|
|
->fetchAll(\PDO::FETCH_ASSOC); |
72
|
|
|
|
73
|
|
|
foreach ($results as $result) { |
74
|
|
|
$add = true; |
75
|
|
|
|
76
|
|
|
$itemToAdd = $targetClass::instanciate($result); |
77
|
|
|
|
78
|
|
|
if ($validate !== null && is_callable($validate)) { |
79
|
|
|
$add = $validate($itemToAdd); |
80
|
|
|
} |
81
|
|
|
if ($add) { |
82
|
|
|
$items[] = $itemToAdd; |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
$collectionClass = $pivot->getCollectionClass(); |
87
|
|
|
return new $collectionClass($items); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
public function getSourceFieldForRelation($relationName) |
91
|
|
|
{ |
92
|
|
|
if (isset($this->relations[$relationName])) { |
93
|
|
|
return $this->relations[$relationName]['source']; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
throw new \InvalidArgumentException( |
97
|
|
|
'Cannot get field for relation "' . |
98
|
|
|
$relationName . |
99
|
|
|
'" : Unknown relation' |
100
|
|
|
); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
public function getTargetForRelation($relationName) |
104
|
|
|
{ |
105
|
|
|
if (isset($this->relations[$relationName])) { |
106
|
|
|
return $this->relations[$relationName]['target']; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
throw new \InvalidArgumentException( |
110
|
|
|
'Cannot get target for relation "' . |
111
|
|
|
$relationName . |
112
|
|
|
'" : Unknown relation' |
113
|
|
|
); |
114
|
|
|
} |
115
|
|
|
} |
116
|
|
|
|