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