GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 637663...b3b3ba )
by butschster
12s
created

prepareDatatablesStructure()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 14
nc 3
nop 3
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0
1
<?php
2
3
namespace SleepingOwl\Admin\Display;
4
5
use Illuminate\Routing\Router;
6
use Request;
7
use Route;
8
use Illuminate\Support\Collection;
9
use Illuminate\Database\Eloquent\Builder;
10
use SleepingOwl\Admin\Contracts\ModelConfigurationInterface;
11
use SleepingOwl\Admin\Display\Column\Email;
12
use SleepingOwl\Admin\Display\Column\Link;
13
use SleepingOwl\Admin\Display\Column\Text;
14
use SleepingOwl\Admin\Display\Column\Custom;
15
use SleepingOwl\Admin\Display\Column\NamedColumn;
16
use SleepingOwl\Admin\Contracts\WithRoutesInterface;
17
18
class DisplayDatatablesAsync extends DisplayDatatables implements WithRoutesInterface
19
{
20
    /**
21
     * Register display routes.
22
     *
23
     * @param Router $router
24
     */
25
    public static function registerRoutes(Router $router)
26
    {
27
        $router->get('{adminModel}/async/{adminDisplayName?}', ['as' => 'admin.model.async',
28
            function (ModelConfigurationInterface $model, $name = null) {
29
                $display = $model->fireDisplay();
30
                if ($display instanceof DisplayTabbed) {
31
                    $display = static::findDatatablesAsyncByName($display, $name);
32
                }
33
34
                if ($display instanceof DisplayDatatablesAsync) {
35
                    return $display->renderAsync();
36
                }
37
38
                abort(404);
39
            },
40
        ]);
41
    }
42
43
    /**
44
     * Find DisplayDatatablesAsync in tabbed display by name.
45
     *
46
     * @param DisplayTabbed $display
47
     * @param string|null   $name
48
     *
49
     * @return DisplayDatatablesAsync|null
50
     */
51
    protected static function findDatatablesAsyncByName(DisplayTabbed $display, $name)
52
    {
53
        $tabs = $display->getTabs();
54
        foreach ($tabs as $tab) {
55
            $content = $tab->getContent();
56
            if ($content instanceof self && $content->getName() === $name) {
57
                return $content;
58
            }
59
        }
60
    }
61
62
    /**
63
     * @var string
64
     */
65
    protected $name;
66
67
    /**
68
     * @param string|null $name
69
     */
70
    protected $distinct;
71
72
    /**
73
     * @var array
74
     */
75
    protected $searchableColumns = [
76
        Text::class,
77
        Link::class,
78
        Email::class,
79
    ];
80
81
    /**
82
     * DisplayDatatablesAsync constructor.
83
     *
84
     * @param string|null $name
85
     * @param string|null $distinct
86
     */
87
    public function __construct($name = null, $distinct = null)
88
    {
89
        parent::__construct();
90
91
        $this->setName($name);
92
        $this->setDistinct($distinct);
93
94
        $this->getColumns()->setView('display.extensions.columns_async');
95
    }
96
97
    /**
98
     * Initialize display.
99
     */
100
    public function initialize()
101
    {
102
        parent::initialize();
103
104
        $attributes = Request::all();
105
        array_unshift($attributes, $this->getName());
106
        array_unshift($attributes, $this->getModelConfiguration()->getAlias());
107
108
        $this->setHtmlAttribute('data-url', route('admin.model.async', $attributes));
109
    }
110
111
    /**
112
     * @return string
113
     */
114
    public function getName()
115
    {
116
        return $this->name;
117
    }
118
119
    /**
120
     * @param string $name
121
     *
122
     * @return $this
123
     */
124
    public function setName($name)
125
    {
126
        $this->name = $name;
127
128
        return $this;
129
    }
130
131
    /**
132
     * @return mixed
133
     */
134
    public function getDistinct()
135
    {
136
        return $this->distinct;
137
    }
138
139
    /**
140
     * @param mixed $distinct
141
     *
142
     * @return $this
143
     */
144
    public function setDistinct($distinct)
145
    {
146
        $this->distinct = $distinct;
147
148
        return $this;
149
    }
150
151
    /**
152
     * Render async request.
153
     * @return array
154
     */
155
    public function renderAsync()
156
    {
157
        $query = $this->getRepository()->getQuery();
158
        $totalCount = $query->count();
159
        $filteredCount = 0;
160
161
        if (! is_null($this->distinct)) {
162
            $filteredCount = $query->distinct()->count($this->getDistinct());
163
        }
164
165
        $this->modifyQuery($query);
166
        $this->applySearch($query);
167
        $this->applyColumnSearch($query);
168
169
        if (is_null($this->distinct)) {
170
            $filteredCount = $query->count();
171
        }
172
173
        $this->applyOrders($query);
174
        $this->applyOffset($query);
175
        $collection = $query->get();
176
177
        return $this->prepareDatatablesStructure($collection, $totalCount, $filteredCount);
0 ignored issues
show
Bug introduced by
It seems like $collection defined by $query->get() on line 175 can also be of type array<integer,object<Ill...base\Eloquent\Builder>>; however, SleepingOwl\Admin\Displa...reDatatablesStructure() does only seem to accept object<Illuminate\Support\Collection>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
178
    }
179
180
    /**
181
     * Apply offset and limit to the query.
182
     *
183
     * @param $query
184
     */
185
    protected function applyOffset($query)
186
    {
187
        $offset = Request::input('start', 0);
188
        $limit = Request::input('length', 10);
189
190
        if ($limit == -1) {
191
            return;
192
        }
193
194
        $query->offset($offset)->limit($limit);
195
    }
196
197
    /**
198
     * Apply orders to the query.
199
     *
200
     * @param $query
201
     */
202
    protected function applyOrders($query)
203
    {
204
        $orders = Request::input('order', []);
205
206
        foreach ($orders as $order) {
0 ignored issues
show
Bug introduced by
The expression $orders of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
207
            $columnIndex = $order['column'];
208
            $orderDirection = $order['dir'];
209
            $column = $this->getColumns()->all()->get($columnIndex);
210
211
            if ($column instanceof NamedColumn && $column->isOrderable()) {
212
                $name = $column->getName();
213
                $query->orderBy($name, $orderDirection);
214
            } elseif ($column instanceof Custom && $column->getOrderField()) {
215
                $name = $column->getOrderField();
216
                $query->orderBy($name, $orderDirection);
217
            }
218
        }
219
    }
220
221
    /**
222
     * Apply search to the query.
223
     *
224
     * @param Builder $query
225
     */
226
    protected function applySearch(Builder $query)
227
    {
228
        $search = Request::input('search.value');
229
        if (empty($search)) {
230
            return;
231
        }
232
233
        $query->where(function ($query) use ($search) {
234
            $columns = $this->getColumns()->all();
235
            foreach ($columns as $column) {
236
                if (in_array(get_class($column), $this->searchableColumns)) {
237
                    $name = $column->getName();
238
                    if ($this->repository->hasColumn($name)) {
239
                        $query->orWhere($name, 'like', '%'.$search.'%');
240
                    }
241
                }
242
            }
243
        });
244
    }
245
246
    /**
247
     * @param Builder $query
248
     */
249
    protected function applyColumnSearch(Builder $query)
250
    {
251
        $queryColumns = Request::input('columns', []);
252
253
        foreach ($queryColumns as $index => $queryColumn) {
0 ignored issues
show
Bug introduced by
The expression $queryColumns of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
254
            $search = array_get($queryColumn, 'search.value');
255
            $fullSearch = array_get($queryColumn, 'search');
256
            $column = $this->getColumns()->all()->get($index);
257
            $columnFilter = array_get($this->getColumnFilters()->all(), $index);
258
259
            if (! is_null($columnFilter) && ! is_null($column)) {
260
                $columnFilter->apply($this->repository, $column, $query, $search, $fullSearch);
261
            }
262
        }
263
    }
264
265
    /**
266
     * Convert collection to the datatables structure.
267
     *
268
     * @param array|Collection $collection
269
     * @param int $totalCount
270
     * @param int $filteredCount
271
     *
272
     * @return array
273
     */
274
    protected function prepareDatatablesStructure(Collection $collection, $totalCount, $filteredCount)
275
    {
276
        $columns = $this->getColumns();
277
278
        $result = [];
279
        $result['draw'] = Request::input('draw', 0);
280
        $result['recordsTotal'] = $totalCount;
281
        $result['recordsFiltered'] = $filteredCount;
282
        $result['data'] = [];
283
284
        foreach ($collection as $instance) {
285
            $_row = [];
286
287
            foreach ($columns->all() as $column) {
288
                $column->setModel($instance);
289
                $_row[] = (string) $column;
290
            }
291
292
            $result['data'][] = $_row;
293
        }
294
295
        return $result;
296
    }
297
}
298