Skip to content

Commit e18a181

Browse files
committed
Update QueryBuilderRelationsWithTrait.php
1 parent e446dde commit e18a181

1 file changed

Lines changed: 101 additions & 0 deletions

File tree

src/Traits/QueryBuilderRelationsWithTrait.php

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,88 @@ trait QueryBuilderRelationsWithTrait
6060
// return $this;
6161
// }
6262

63+
protected $withs = [];
64+
6365
// public function with(...$props)
6466
// {
6567
// $this->withs = array_merge($this->withs, $props);
6668
// echo dumpOrm($this->withs);
6769
// return $this;
6870
// }
6971

72+
public function with(...$props)
73+
{
74+
// echo dumpOrm($props);
75+
$withs = [];
76+
foreach ($props as &$prop) {
77+
if (is_string($prop)) {
78+
$withs[] = $this->levels(explode('.', $prop));
79+
} else if (is_array($prop)) {
80+
$withs[] = $this->recursiveArrayWith($prop);
81+
}
82+
}
83+
$this->withs = array_merge_recursive(...$withs);
84+
// echo dumpOrm($this->withs);
85+
return $this;
86+
}
87+
88+
protected function levels($levels, $value = [])
89+
{
90+
$levels = array_reverse($levels);
91+
$with = $value;
92+
foreach ($levels as $level) {
93+
$with = [$level => $with];
94+
}
95+
return $with;
96+
}
97+
98+
protected function recursiveArrayWith(array $props)
99+
{
100+
$withs = [];
101+
foreach ($props as $i => $prop) {
102+
$key = is_string($i) ? $i : $prop;
103+
$val = is_string($i) ? $prop : [];
104+
105+
if (is_array($val)) $val = $this->recursiveArrayWith($val);
106+
else if (is_string($val)) $val = [$val => []];
107+
108+
// вложенность связей в ключе
109+
if (is_string($key)) {
110+
$levels = explode('.', $key);
111+
if (count($levels) > 1) {
112+
$key = array_shift($levels);
113+
$val = $this->levels($levels, $val);
114+
}
115+
}
116+
// слияние значений уже существующего ключа
117+
if (isset($withs[$key]) && is_array($withs[$key])) {
118+
if (is_numeric($val)) return;
119+
if (is_string($val)) $val = [$val];
120+
$val = array_merge($withs[$key], $val);
121+
}
122+
$withs[$key] = $val;
123+
}
124+
return $withs;
125+
}
126+
127+
// protected function recursiveArrayWith(array $props)
128+
// {
129+
// $withs = [];
130+
// foreach ($props as $i => $prop) {
131+
// $names = is_string($i) ? explode('.', $i) : [];
132+
// if (is_string($prop)) {
133+
// $withs[] = array_merge($names, explode('.', $prop));
134+
// } else if (is_array($prop)) {
135+
// $subs = $this->recursiveArrayWith($prop);
136+
// foreach ($subs as $sub) {
137+
// $withs[] = array_merge($names, $sub);
138+
// }
139+
// }
140+
// }
141+
// return $withs;
142+
// }
143+
144+
70145
protected function applyWiths(array $ids, array &$models)
71146
{
72147
// // $withOne = array_filter($this->withOne, fn($with) => $with->isOne());
@@ -77,6 +152,32 @@ protected function applyWiths(array $ids, array &$models)
77152
// foreach ($this->withOne as [$relation, $columns, $query]) {
78153
// $this->applyWith($relation, $columns, $query);
79154
// }
155+
// return;
156+
if (1 > count($this->withs)) return;
157+
$keys = array_keys($this->withs);
158+
foreach ($keys as $key) {
159+
$this->applyWith($key, $this->withs[$key], $ids, $models);
160+
}
161+
}
162+
163+
protected function applyWith($key, $val, array $ids, array &$models)
164+
{
165+
$relation = $this->getRelation($key);
166+
$qb = (new static($this->db, $relation->foreignModel));
167+
$qb->whereIn($relation->foreignKey, $ids);
168+
if (!empty($val)) $qb->with($val);
169+
$subModels = $qb->get();
170+
if (!$subModels) return;
171+
$idsLocal = [];
172+
foreach ($subModels as $subModel) {
173+
$idsLocal[] = $subModel->primaryValue();
174+
foreach ($models as $model) {
175+
if ($model->{$relation->localKey} == $subModel->{$relation->foreignKey}) {
176+
$model->addRelated($relation->name, $subModel);
177+
break;
178+
}
179+
}
180+
}
80181
}
81182

82183
// protected function applyWith(

0 commit comments

Comments
 (0)