1 | <?php |
||||
2 | |||||
3 | namespace SoliDry\Extension; |
||||
4 | |||||
5 | use Illuminate\Database\Eloquent\Collection; |
||||
6 | use Illuminate\Database\Query\Builder; |
||||
7 | use Illuminate\Support\Facades\DB; |
||||
8 | use SoliDry\Types\ModelsInterface; |
||||
9 | use SoliDry\Types\PhpInterface; |
||||
10 | use SoliDry\Types\ApiInterface; |
||||
11 | use SoliDry\Helpers\SqlOptions; |
||||
12 | |||||
13 | /** |
||||
14 | * Class BaseModelTrait |
||||
15 | * @package SoliDry\Extension |
||||
16 | * |
||||
17 | * @property ApiController modelEntity |
||||
18 | * @property CustomSql customSql |
||||
19 | */ |
||||
20 | trait BaseModelTrait |
||||
21 | { |
||||
22 | /** |
||||
23 | * @var bool |
||||
24 | */ |
||||
25 | private bool $pagination = false; |
||||
26 | |||||
27 | /** |
||||
28 | * @param bool $pagination |
||||
29 | */ |
||||
30 | public function setPagination(bool $pagination): void |
||||
31 | { |
||||
32 | $this->pagination = $pagination; |
||||
33 | } |
||||
34 | |||||
35 | /** |
||||
36 | * @param int|string $id |
||||
37 | * @param array $data |
||||
38 | * |
||||
39 | * @return mixed |
||||
40 | */ |
||||
41 | private function getEntity($id, array $data = ModelsInterface::DEFAULT_DATA) |
||||
42 | { |
||||
43 | $obj = \call_user_func_array( |
||||
44 | PhpInterface::BACKSLASH . $this->modelEntity . PhpInterface::DOUBLE_COLON |
||||
45 | . ModelsInterface::MODEL_METHOD_WHERE, [ApiInterface::RAML_ID, $id] |
||||
46 | ); |
||||
47 | |||||
48 | if ($data[0] !== PhpInterface::ASTERISK) { |
||||
49 | // add id to output it in json-api entity |
||||
50 | $data[] = ModelsInterface::ID; |
||||
51 | } |
||||
52 | |||||
53 | return $obj->first($data); |
||||
54 | } |
||||
55 | |||||
56 | /** |
||||
57 | * Gets all or custom entities |
||||
58 | * |
||||
59 | * @param SqlOptions $sqlOptions |
||||
60 | * @return \Illuminate\Support\Collection|mixed |
||||
61 | */ |
||||
62 | private function getEntities(SqlOptions $sqlOptions) |
||||
63 | { |
||||
64 | /** @var CustomSql $customSql */ |
||||
65 | if ($this->customSql->isEnabled()) { |
||||
66 | return $this->getCustomSqlEntities($this->customSql); |
||||
67 | } |
||||
68 | |||||
69 | return $this->getAllEntities($sqlOptions); |
||||
70 | } |
||||
71 | |||||
72 | /** |
||||
73 | * @param string $modelEntity |
||||
74 | * @param int|string $id |
||||
75 | * |
||||
76 | * @return mixed |
||||
77 | */ |
||||
78 | private function getModelEntity($modelEntity, $id) |
||||
79 | { |
||||
80 | $obj = \call_user_func_array( |
||||
81 | PhpInterface::BACKSLASH . $modelEntity . PhpInterface::DOUBLE_COLON |
||||
82 | . ModelsInterface::MODEL_METHOD_WHERE, [ApiInterface::RAML_ID, $id] |
||||
83 | ); |
||||
84 | |||||
85 | return $obj->first(); |
||||
86 | } |
||||
87 | |||||
88 | /** |
||||
89 | * @param string $modelEntity |
||||
90 | * @param array $params |
||||
91 | * |
||||
92 | * @return mixed |
||||
93 | */ |
||||
94 | private function getModelEntities($modelEntity, array $params) |
||||
95 | { |
||||
96 | return \call_user_func_array( |
||||
97 | PhpInterface::BACKSLASH . $modelEntity . PhpInterface::DOUBLE_COLON |
||||
98 | . ModelsInterface::MODEL_METHOD_WHERE, $params |
||||
99 | ); |
||||
100 | } |
||||
101 | |||||
102 | /** |
||||
103 | * Get rows from particular Entity |
||||
104 | * |
||||
105 | * @param SqlOptions $sqlOptions |
||||
106 | * |
||||
107 | * @return mixed |
||||
108 | */ |
||||
109 | private function getAllEntities(SqlOptions $sqlOptions) |
||||
110 | { |
||||
111 | $limit = $sqlOptions->getLimit(); |
||||
112 | $page = $sqlOptions->getPage(); |
||||
113 | $data = $sqlOptions->getData(); |
||||
114 | $orderBy = $sqlOptions->getOrderBy(); |
||||
115 | $filter = $sqlOptions->getFilter(); |
||||
116 | |||||
117 | $defaultOrder = []; |
||||
118 | $order = []; |
||||
119 | |||||
120 | $first = true; |
||||
121 | foreach ($orderBy as $column => $value) { |
||||
122 | if ($first === true) { |
||||
123 | $defaultOrder = [$column, $value]; |
||||
124 | } else { |
||||
125 | $order[] = [ModelsInterface::COLUMN => $column, |
||||
126 | ModelsInterface::DIRECTION => $value]; |
||||
127 | } |
||||
128 | $first = false; |
||||
129 | } |
||||
130 | $from = ($limit * $page) - $limit; |
||||
131 | $to = $limit * $page; |
||||
132 | |||||
133 | /** @var Builder $obj */ |
||||
134 | $obj = \call_user_func_array( |
||||
135 | PhpInterface::BACKSLASH . $this->modelEntity . PhpInterface::DOUBLE_COLON . |
||||
136 | ModelsInterface::MODEL_METHOD_ORDER_BY, |
||||
137 | $defaultOrder |
||||
138 | ); |
||||
139 | |||||
140 | // it can be empty if nothing more then 1st passed |
||||
141 | $obj->order = $order; |
||||
142 | |||||
143 | if ($this->pagination === true) { |
||||
144 | return $obj->where($filter)->paginate($limit, $data, 'page', $page); |
||||
145 | } |
||||
146 | |||||
147 | return $obj->where($filter)->take($to)->skip($from)->get($data); |
||||
148 | } |
||||
149 | |||||
150 | /** |
||||
151 | * Selects a collection of items based on custom sql |
||||
152 | * |
||||
153 | * @param CustomSql $customSql |
||||
154 | * @return \Illuminate\Support\Collection |
||||
155 | */ |
||||
156 | private function getCustomSqlEntities(CustomSql $customSql): \Illuminate\Support\Collection |
||||
157 | { |
||||
158 | $result = DB::select($customSql->getQuery(), $customSql->getBindings()); |
||||
159 | $collection = []; |
||||
160 | foreach ($result as $item) { |
||||
161 | $class = PhpInterface::BACKSLASH . $this->modelEntity; |
||||
162 | $collection[] = (new $class())->fill((array)$item); |
||||
163 | } |
||||
164 | return collect($collection); |
||||
165 | } |
||||
166 | |||||
167 | /** |
||||
168 | * Collects all tree elements |
||||
169 | * |
||||
170 | * @param SqlOptions $sqlOptions |
||||
171 | * @return Collection |
||||
172 | */ |
||||
173 | public function getAllTreeEntities(SqlOptions $sqlOptions) : Collection |
||||
174 | { |
||||
175 | return Collection::make($this->buildTree($this->getAllEntities($sqlOptions))); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
176 | } |
||||
177 | |||||
178 | /** |
||||
179 | * Builds the tree based on children/parent axiom |
||||
180 | * |
||||
181 | * @param Collection $data |
||||
182 | * @param int|string $id |
||||
183 | * @return array |
||||
184 | */ |
||||
185 | private function buildTree(Collection $data, $id = 0): array |
||||
186 | { |
||||
187 | $tree = []; |
||||
188 | foreach ($data as $k => $child) { |
||||
189 | if ($child->parent_id === $id) { // child found |
||||
190 | // clear found children to free stack |
||||
191 | unset($data[$k]); |
||||
192 | $child->children = $this->buildTree($data, $child->id); |
||||
193 | $tree[] = $child; |
||||
194 | } |
||||
195 | } |
||||
196 | |||||
197 | return $tree; |
||||
198 | } |
||||
199 | |||||
200 | /** |
||||
201 | * Collects all tree elements |
||||
202 | * |
||||
203 | * @param SqlOptions $sqlOptions |
||||
204 | * @param int|string $id |
||||
205 | * @return array |
||||
206 | */ |
||||
207 | public function getSubTreeEntities(SqlOptions $sqlOptions, $id) : array |
||||
208 | { |
||||
209 | return $this->buildSubTree($this->getAllEntities($sqlOptions), $id); |
||||
0 ignored issues
–
show
It seems like
$this->getAllEntities($sqlOptions) can also be of type Illuminate\Pagination\LengthAwarePaginator ; however, parameter $data of SoliDry\Extension\BaseModelTrait::buildSubTree() does only seem to accept Illuminate\Database\Eloquent\Collection , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
210 | } |
||||
211 | |||||
212 | /** |
||||
213 | * Builds the sub-tree for top most ancestor |
||||
214 | * |
||||
215 | * @param Collection $data |
||||
216 | * @param int|string $searchId |
||||
217 | * @param int|string $id |
||||
218 | * @param bool $isParentFound |
||||
219 | * @return array |
||||
220 | */ |
||||
221 | private function buildSubTree(Collection $data, $searchId, $id = 0, bool $isParentFound = false) : array |
||||
222 | { |
||||
223 | $tree = []; |
||||
224 | foreach ($data as $k => $child) { |
||||
225 | if ($searchId === $child->id) { |
||||
226 | $isParentFound = true; |
||||
227 | } |
||||
228 | if ($child->parent_id === $id && $isParentFound === true) { // child found |
||||
229 | // clear found children to free stack |
||||
230 | unset($data[$k]); |
||||
231 | $child->children = $this->buildSubTree($data, $searchId, $child->id, $isParentFound); |
||||
232 | $tree[] = $child; |
||||
233 | } |
||||
234 | if ($isParentFound === true && 0 === $id) { |
||||
235 | return $tree; |
||||
236 | } |
||||
237 | } |
||||
238 | |||||
239 | return $tree; |
||||
240 | } |
||||
241 | } |