Passed
Branch testing (099eea)
by Roman
08:02
created

Collection::only()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace lroman242\LaravelCassandra;
4
5
use \Cassandra\Rows;
6
use lroman242\LaravelCassandra\Eloquent\Model;
7
use Illuminate\Support\Arr;
8
use Illuminate\Contracts\Support\Arrayable;
9
use Illuminate\Database\Eloquent\Collection as BaseCollection;
10
11
class Collection extends BaseCollection
12
{
13
    /**
14
     * Cassandra rows instance
15
     *
16
     * @var \Cassandra\Rows
17
     */
18
    private $rows;
19
20
    /**
21
     * Items model
22
     *
23
     * @var Model
24
     */
25
    private $model;
26
27
    /**
28
     * Create a new collection.
29
     *
30
     * @param  mixed  $items
31
     * @param  Model  $model
32
     */
33 43
    public function __construct($items = [], Model $model = null)
34
    {
35 43
        if ($items instanceof Rows) {
0 ignored issues
show
Bug introduced by
The class Cassandra\Rows does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
36 43
            $this->rows = $items;
37
        }
38 43
        $this->model = $model;
39
40 43
        parent::__construct($this->prepareItems($items));
41 43
    }
42
43
    /**
44
     * Prepare items for collection
45
     *
46
     * @return array|Model[]
47
     */
48 43
    protected function prepareItems($items)
49
    {
50 43
        if ($this->model !== null && ($items instanceof Rows || is_array($items))) {
0 ignored issues
show
Bug introduced by
The class Cassandra\Rows does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
51 37
            $models = [];
52
53 37
            foreach ($items as $row) {
54 34
                if (!$row instanceof $this->model) {
55 34
                    $models[] = $this->model->newFromBuilder($row);
56
                } else {
57 34
                    $models[] = $row;
58
                }
59
            }
60
61 37
            return $models;
62
        } else {
63 43
            return $items;
64
        }
65
    }
66
67
    /**
68
     * Next page token
69
     *
70
     * @return mixed
71
     */
72 2
    public function getNextPageToken()
73
    {
74 2
        return $this->rows->pagingStateToken();
75
    }
76
77
    /**
78
     * Last page indicator
79
     * @return bool
80
     */
81 39
    public function isLastPage()
82
    {
83 39
        if ($this->rows === null) {
84 2
            return true;
85
        }
86
87 38
        return $this->rows->isLastPage();
88
    }
89
90
    /**
91
     * Get next page
92
     *
93
     * @return Collection
94
     */
95 3
    public function nextPage()
96
    {
97 3
        if (!$this->isLastPage()) {
98 3
            return new self($this->rows->nextPage(), $this->model);
99
        }
100 1
    }
101
102
    /**
103
     * Get rows instance
104
     *
105
     * @return \Cassandra\Rows
106
     */
107 37
    public function getRows()
108
    {
109 37
        return $this->rows;
110
    }
111
112
    /**
113
     * Update current collection with results from
114
     * the next page
115
     *
116
     * @return Collection
117
     */
118 2
    public function appendNextPage()
119
    {
120 2
        $nextPage = $this->nextPage();
121
122 2
        if ($nextPage) {
123 2
            $this->items = array_merge($this->items, $nextPage->toArray());
124 2
            $this->rows = $nextPage->getRows();
125
        }
126
127 2
        return $this;
128
    }
129
130
    /**
131
     * Find a model in the collection by key.
132
     *
133
     * @param  mixed  $key
134
     * @param  mixed  $default
135
     *
136
     * @return \Illuminate\Database\Eloquent\Model|static
137
     */
138 7
    public function find($key, $default = null)
139
    {
140 7
        if ($key instanceof Model) {
141 1
            $key = $key->getKey();
142
        }
143
144 7
        if ($key instanceof Arrayable) {
145 3
            $key = $key->toArray();
146
        }
147
148 7
        if (is_array($key)) {
149 3
            if ($this->isEmpty()) {
150 1
                return new static([], $this->model);
151
            }
152
153 2
            return $this->whereIn($this->first()->getKeyName(), $key);
154
        }
155
156 4
        return Arr::first($this->items, function ($model) use ($key) {
157 4
            return $model->getKey() == $key;
158 4
        }, $default);
159
    }
160
161
    /**
162
     * Merge the collection with the given items.
163
     *
164
     * @param  \ArrayAccess|array  $items
165
     * @return static
166
     */
167
    public function merge($items)
168
    {
169
        $dictionary = $this->getDictionary();
170
171
        foreach ($items as $item) {
172
            $dictionary[(string) $item->getKey()] = $item;
173
        }
174
175
        return new static(array_values($dictionary), $this->model);
176
    }
177
178
    /**
179
     * Reload a fresh model instance from the database for all the entities.
180
     *
181
     * @param  array|string  $with
182
     * @return static
183
     */
184
    public function fresh($with = [])
185
    {
186
        if ($this->isEmpty()) {
187
            return new static([], $this->model);
188
        }
189
190
        $model = $this->first();
191
192
        $freshModels = $model->newQueryWithoutScopes()
193
            ->with(is_string($with) ? func_get_args() : $with)
194
            ->whereIn($model->getKeyName(), $this->modelKeys())
195
            ->get()
196
            ->getDictionary();
197
198
        return $this->map(function ($model) use ($freshModels) {
199
            return $model->exists && isset($freshModels[(string) $model->getKey()])
200
                ? $freshModels[(string) $model->getKey()] : null;
201
        });
202
    }
203
204
    /**
205
     * Diff the collection with the given items.
206
     *
207
     * @param  \ArrayAccess|array  $items
208
     * @return static
209
     */
210 View Code Duplication
    public function diff($items)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
211
    {
212
        $diff = new static([], $this->model);
213
214
        $dictionary = $this->getDictionary($items);
215
216
        foreach ($this->items as $item) {
217
            if (!isset($dictionary[(string) $item->getKey()])) {
218
                $diff->add($item);
219
            }
220
        }
221
222
        return $diff;
223
    }
224
225
    /**
226
     * Intersect the collection with the given items.
227
     *
228
     * @param  \ArrayAccess|array  $items
229
     * @return static
230
     */
231 View Code Duplication
    public function intersect($items)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
232
    {
233
        $intersect = new static([], $this->model);
234
235
        $dictionary = $this->getDictionary($items);
236
237
        foreach ($this->items as $item) {
238
            if (isset($dictionary[(string) $item->getKey()])) {
239
                $intersect->add($item);
240
            }
241
        }
242
243
        return $intersect;
244
    }
245
246
    /**
247
     * Return only unique items from the collection.
248
     *
249
     * @param  string|callable|null  $key
250
     * @param  bool  $strict
251
     * @return static|\Illuminate\Support\Collection
252
     */
253 2
    public function unique($key = null, $strict = false)
254
    {
255 2
        if (!is_null($key)) {
256 2
            return parent::unique($key, $strict);
257
        }
258
259
        return new static(array_values($this->getDictionary()), $this->model);
260
    }
261
262
    /**
263
     * Returns only the models from the collection with the specified keys.
264
     *
265
     * @param  mixed  $keys
266
     * @return static
267
     */
268 2
    public function only($keys)
269
    {
270 2
        if (is_null($keys)) {
271 1
            return new static($this->items, $this->model);
272
        }
273
274 1
        $dictionary = Arr::only($this->getDictionary(), $keys);
275
276 1
        return new static(array_values($dictionary), $this->model);
277
    }
278
279
    /**
280
     * Returns all models in the collection except the models with specified keys.
281
     *
282
     * @param  mixed  $keys
283
     * @return static
284
     */
285 1
    public function except($keys)
286
    {
287 1
        $dictionary = Arr::except($this->getDictionary(), $keys);
288
289 1
        return new static(array_values($dictionary), $this->model);
290
    }
291
292
293
    /**
294
     * Get a dictionary keyed by primary keys.
295
     *
296
     * @param  \ArrayAccess|array|null  $items
297
     * @return array
298
     */
299 3
    public function getDictionary($items = null)
300
    {
301 3
        $items = is_null($items) ? $this->items : $items;
302
303 3
        $dictionary = [];
304
305 3
        foreach ($items as $value) {
306 3
            $dictionary[(string) $value->getKey()] = $value;
307
        }
308
309 3
        return $dictionary;
310
    }
311
}
312