1 | <?php |
||||
2 | |||||
3 | namespace SleepingOwl\Admin\Display; |
||||
4 | |||||
5 | use Exception; |
||||
6 | use Illuminate\Database\Eloquent\Builder; |
||||
7 | use Illuminate\Pagination\LengthAwarePaginator; |
||||
8 | use Illuminate\Support\Collection; |
||||
9 | use Illuminate\Support\Facades\Request; |
||||
10 | use SleepingOwl\Admin\Contracts\Display\ColumnInterface; |
||||
11 | use SleepingOwl\Admin\Contracts\Display\ColumnMetaInterface; |
||||
12 | use SleepingOwl\Admin\Contracts\Display\Extension\ColumnFilterInterface; |
||||
13 | use SleepingOwl\Admin\Display\Extension\ColumnFilters; |
||||
14 | use SleepingOwl\Admin\Display\Extension\Columns; |
||||
15 | use SleepingOwl\Admin\Display\Extension\ColumnsTotal; |
||||
16 | use SleepingOwl\Admin\Traits\PanelControl; |
||||
17 | |||||
18 | /** |
||||
19 | * Class DisplayTable. |
||||
20 | * |
||||
21 | * @method Columns getColumns() |
||||
22 | * @method $this setColumns(ColumnInterface|ColumnInterface[] $column) |
||||
23 | * |
||||
24 | * @method ColumnFilters getColumnFilters() |
||||
25 | * @method $this setColumnFilters(ColumnFilterInterface|ColumnFilterInterface[] $filters = null, ...$filters) |
||||
26 | */ |
||||
27 | class DisplayTable extends Display |
||||
28 | { |
||||
29 | use PanelControl; |
||||
30 | |||||
31 | /** |
||||
32 | * @var string |
||||
33 | */ |
||||
34 | protected $view = 'display.table'; |
||||
35 | |||||
36 | /** |
||||
37 | * @var array |
||||
38 | */ |
||||
39 | protected $parameters = []; |
||||
40 | |||||
41 | /** |
||||
42 | * @var int|null |
||||
43 | */ |
||||
44 | protected $paginate = 25; |
||||
45 | |||||
46 | /** |
||||
47 | * @var string |
||||
48 | */ |
||||
49 | protected $pageName = 'page'; |
||||
50 | |||||
51 | /** |
||||
52 | * @var bool|null |
||||
53 | */ |
||||
54 | protected $creatable = null; |
||||
55 | |||||
56 | /** |
||||
57 | * @var Collection |
||||
58 | */ |
||||
59 | protected $collection; |
||||
60 | |||||
61 | /** |
||||
62 | * @var string|null |
||||
63 | */ |
||||
64 | protected $newEntryButtonText; |
||||
65 | |||||
66 | /** |
||||
67 | * Display constructor. |
||||
68 | */ |
||||
69 | public function __construct() |
||||
70 | { |
||||
71 | parent::__construct(); |
||||
72 | |||||
73 | $this->extend('columns', new Columns()); |
||||
74 | $this->extend('column_filters', new ColumnFilters()); |
||||
75 | $this->extend('columns_total', new ColumnsTotal()); |
||||
76 | } |
||||
77 | |||||
78 | /** |
||||
79 | * @throws \Exception |
||||
80 | */ |
||||
81 | public function initialize() |
||||
82 | { |
||||
83 | parent::initialize(); |
||||
84 | |||||
85 | if ($this->getModelConfiguration()->isRestorableModel()) { |
||||
86 | $this->setApply(function (Builder $q) { |
||||
87 | return $q->withTrashed(); |
||||
88 | }); |
||||
89 | } |
||||
90 | |||||
91 | $this->setHtmlAttribute('class', 'table table-striped'); |
||||
92 | } |
||||
93 | |||||
94 | /** |
||||
95 | * @return array|\Illuminate\Contracts\Translation\Translator|null|string |
||||
96 | */ |
||||
97 | public function getNewEntryButtonText() |
||||
98 | { |
||||
99 | if (is_null($this->newEntryButtonText)) { |
||||
100 | $this->newEntryButtonText = trans('sleeping_owl::lang.table.new-entry'); |
||||
0 ignored issues
–
show
|
|||||
101 | } |
||||
102 | |||||
103 | return $this->newEntryButtonText; |
||||
104 | } |
||||
105 | |||||
106 | /** |
||||
107 | * @param string $newEntryButtonText |
||||
108 | * |
||||
109 | * @return $this |
||||
110 | */ |
||||
111 | public function setNewEntryButtonText($newEntryButtonText) |
||||
112 | { |
||||
113 | $this->newEntryButtonText = $newEntryButtonText; |
||||
114 | |||||
115 | return $this; |
||||
116 | } |
||||
117 | |||||
118 | /** |
||||
119 | * @return array |
||||
120 | */ |
||||
121 | public function getParameters() |
||||
122 | { |
||||
123 | return $this->parameters; |
||||
124 | } |
||||
125 | |||||
126 | /** |
||||
127 | * @param array $parameters |
||||
128 | * |
||||
129 | * @return $this |
||||
130 | */ |
||||
131 | public function setParameters($parameters) |
||||
132 | { |
||||
133 | $this->parameters = $parameters; |
||||
134 | |||||
135 | return $this; |
||||
136 | } |
||||
137 | |||||
138 | /** |
||||
139 | * @param string $key |
||||
140 | * @param mixed $value |
||||
141 | * |
||||
142 | * @return $this |
||||
143 | */ |
||||
144 | public function setParameter($key, $value) |
||||
145 | { |
||||
146 | $this->parameters[$key] = $value; |
||||
147 | |||||
148 | return $this; |
||||
149 | } |
||||
150 | |||||
151 | /** |
||||
152 | * @param int $perPage |
||||
153 | * @param string $pageName |
||||
154 | * |
||||
155 | * @return $this |
||||
156 | */ |
||||
157 | public function paginate($perPage = 25, $pageName = 'page') |
||||
158 | { |
||||
159 | $this->paginate = (int) $perPage; |
||||
160 | $this->pageName = $pageName; |
||||
161 | |||||
162 | return $this; |
||||
163 | } |
||||
164 | |||||
165 | /** |
||||
166 | * @return $this |
||||
167 | */ |
||||
168 | public function disablePagination() |
||||
169 | { |
||||
170 | $this->paginate = 0; |
||||
171 | |||||
172 | return $this; |
||||
173 | } |
||||
174 | |||||
175 | /** |
||||
176 | * @return bool |
||||
177 | */ |
||||
178 | public function usePagination() |
||||
179 | { |
||||
180 | return $this->paginate > 0; |
||||
181 | } |
||||
182 | |||||
183 | /** |
||||
184 | * @return bool|null |
||||
185 | */ |
||||
186 | public function getCreatable() |
||||
187 | { |
||||
188 | return $this->creatable; |
||||
189 | } |
||||
190 | |||||
191 | /** |
||||
192 | * @param bool|null $creatable |
||||
193 | * |
||||
194 | * @return $this |
||||
195 | */ |
||||
196 | public function setCreatable($creatable) |
||||
197 | { |
||||
198 | $this->creatable = $creatable; |
||||
199 | |||||
200 | return $this; |
||||
201 | } |
||||
202 | |||||
203 | /** |
||||
204 | * @return array |
||||
205 | * @throws \Exception |
||||
206 | */ |
||||
207 | public function toArray() |
||||
208 | { |
||||
209 | $model = $this->getModelConfiguration(); |
||||
210 | |||||
211 | $params = parent::toArray(); |
||||
212 | |||||
213 | $params['creatable'] = $this->getCreatable() !== null ? $this->getCreatable() : $model->isCreatable(); |
||||
214 | $params['createUrl'] = $model->getCreateUrl($this->getParameters() + Request::all()); |
||||
215 | $params['collection'] = $this->getCollection(); |
||||
216 | |||||
217 | $params['extensions'] = $this->getExtensions()->renderable()->sortByOrder(); |
||||
218 | $params['newEntryButtonText'] = $this->getNewEntryButtonText(); |
||||
219 | $params['panel_class'] = $this->getPanelClass(); |
||||
220 | |||||
221 | return $params; |
||||
222 | } |
||||
223 | |||||
224 | /** |
||||
225 | * $collection Collection|LengthAwarePaginator|Builder. |
||||
226 | */ |
||||
227 | public function setCollection($collection) |
||||
228 | { |
||||
229 | $this->collection = $collection; |
||||
230 | } |
||||
231 | |||||
232 | /** |
||||
233 | * Apply offset and limit to the query. |
||||
234 | * |
||||
235 | * @param $query |
||||
236 | * @param \Illuminate\Http\Request $request |
||||
237 | */ |
||||
238 | public function applyOffset($query, \Illuminate\Http\Request $request) |
||||
239 | { |
||||
240 | $offset = $request->input('start', 0); |
||||
241 | $limit = $request->input('length', 10); |
||||
242 | |||||
243 | if ($limit == -1) { |
||||
244 | return; |
||||
245 | } |
||||
246 | |||||
247 | $query->offset((int) $offset)->limit((int) $limit); |
||||
248 | } |
||||
249 | |||||
250 | /** |
||||
251 | * Apply search to the query. |
||||
252 | * |
||||
253 | * @param Builder $query |
||||
254 | * @param \Illuminate\Http\Request $request |
||||
255 | */ |
||||
256 | public function applySearch(Builder $query, \Illuminate\Http\Request $request) |
||||
257 | { |
||||
258 | $search = $request->input('search.value'); |
||||
259 | if (empty($search)) { |
||||
260 | return; |
||||
261 | } |
||||
262 | |||||
263 | $query->where(function (Builder $query) use ($search) { |
||||
264 | $columns = $this->getColumns()->all(); |
||||
265 | |||||
266 | foreach ($columns as $column) { |
||||
267 | if ($column->isSearchable()) { |
||||
268 | if ($column instanceof ColumnInterface) { |
||||
269 | if (($metaInstance = $column->getMetaData()) instanceof ColumnMetaInterface) { |
||||
0 ignored issues
–
show
The method
getMetaData() does not exist on SleepingOwl\Admin\Contra...Display\ColumnInterface . It seems like you code against a sub-type of said class. However, the method does not exist in SleepingOwl\Admin\Contra...ColumnEditableInterface . Are you sure you never get one of those?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
270 | if (method_exists($metaInstance, 'onSearch')) { |
||||
271 | $metaInstance->onSearch($column, $query, $search); |
||||
272 | continue; |
||||
273 | } |
||||
274 | } |
||||
275 | |||||
276 | if (is_callable($callback = $column->getSearchCallback())) { |
||||
0 ignored issues
–
show
The method
getSearchCallback() does not exist on SleepingOwl\Admin\Contra...Display\ColumnInterface . It seems like you code against a sub-type of said class. However, the method does not exist in SleepingOwl\Admin\Contra...ColumnEditableInterface . Are you sure you never get one of those?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
277 | $callback($column, $query, $search); |
||||
278 | continue; |
||||
279 | } |
||||
280 | } |
||||
281 | |||||
282 | $query->orWhere($column->getName(), 'like', '%'.$search.'%'); |
||||
0 ignored issues
–
show
The method
getName() does not exist on SleepingOwl\Admin\Contra...Display\ColumnInterface . It seems like you code against a sub-type of SleepingOwl\Admin\Contra...Display\ColumnInterface such as SleepingOwl\Admin\Display\Column\NamedColumn or SleepingOwl\Admin\Display\Column\Editable\DateTime or SleepingOwl\Admin\Display\Column\Editable\Select or SleepingOwl\Admin\Display\Column\Editable\Textarea or SleepingOwl\Admin\Display\Column\Editable\Checkbox or SleepingOwl\Admin\Display\Column\Editable\Text .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
283 | } |
||||
284 | } |
||||
285 | }); |
||||
286 | } |
||||
287 | |||||
288 | /** |
||||
289 | * @return Collection|LengthAwarePaginator|Builder |
||||
290 | * @throws \Exception |
||||
291 | */ |
||||
292 | public function getCollection() |
||||
293 | { |
||||
294 | if (! $this->isInitialized()) { |
||||
295 | throw new Exception('Display is not initialized'); |
||||
296 | } |
||||
297 | |||||
298 | if (! is_null($this->collection)) { |
||||
299 | return $this->collection; |
||||
300 | } |
||||
301 | |||||
302 | $query = $this->getRepository()->getQuery(); |
||||
303 | |||||
304 | $this->modifyQuery($query); |
||||
305 | |||||
306 | return $this->collection = $this->usePagination() |
||||
0 ignored issues
–
show
It seems like
$this->usePagination() ?...eName)) : $query->get() can also be of type Illuminate\Pagination\LengthAwarePaginator . However, the property $collection is declared as type Illuminate\Support\Collection . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
307 | ? $query->paginate($this->paginate, ['*'], $this->pageName)->appends(request()->except($this->pageName)) |
||||
308 | : $query->get(); |
||||
309 | } |
||||
310 | |||||
311 | /** |
||||
312 | * @param \Illuminate\Database\Eloquent\Builder|Builder $query |
||||
313 | */ |
||||
314 | protected function modifyQuery(Builder $query) |
||||
315 | { |
||||
316 | $this->extensions->modifyQuery($query); |
||||
317 | } |
||||
318 | } |
||||
319 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.