Completed
Push — master ( 1e376d...b0060a )
by Changwan
05:50
created

EloquentRepository::insertItems()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 5
nop 1
dl 0
loc 19
ccs 0
cts 16
cp 0
crap 30
rs 8.8571
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Bridges\Eloquent;
3
4
use Illuminate\Database\Eloquent\Builder;
5
use Illuminate\Database\Eloquent\Collection;
6
use Illuminate\Database\Eloquent\Model;
7
use InvalidArgumentException;
8
9
class EloquentRepository
10
{
11
    /** @var string */
12
    protected $model;
13
14
    /**
15
     * @todo get default orders from model's primaryKey.
16
     * @var array
17
     */
18
    protected $orders = [
19
        'id' => false,
20
    ];
21
22
    /** @var array */
23
    protected $cached = [];
24
25
    /** @var bool */
26
    protected $cacheEnabled = true;
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function countAll()
32
    {
33
        return $this->createQuery()->count();
34
    }
35
36
    /**
37
     * @todo data filter
38
     * {@inheritdoc}
39
     */
40
    public function insertItems(array $items)
41
    {
42
        if ($items !== array_values($items)) {
43
            throw new InvalidArgumentException('first parameter must be array of array.');
44
        }
45
        if (count($items) === 0) {
46
            return;
47
        }
48
49
        if (count($items) <= 10) {
50
            $this->createQuery()->insert($items);
51
            return;
52
        }
53
54
        // more than 10, chunk insert items.
55
        foreach (array_chunk($items, 10) as $chunkedItems) {
56
            $this->createQuery()->insert($chunkedItems);
57
        }
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function findItems(array $where)
64
    {
65
        $query = $this->createQuery();
66
        foreach ($this->filterWhere($where) as $key => $value) {
67
            $query = $query->where($key, $value);
68
        }
69
        return $this->cacheItems($query->get());
0 ignored issues
show
Bug introduced by
It seems like $query->get() targeting Illuminate\Database\Eloquent\Builder::get() can also be of type array<integer,object<Ill...base\Eloquent\Builder>>; however, Wandu\Bridges\Eloquent\E...epository::cacheItems() does only seem to accept object<Illuminate\Database\Eloquent\Collection>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function getAllItems()
76
    {
77
        return $this->cacheItems($this->applyScopeOrders($this->createQuery())->get());
0 ignored issues
show
Bug introduced by
It seems like $this->applyScopeOrders(...->createQuery())->get() targeting Illuminate\Database\Eloquent\Builder::get() can also be of type array<integer,object<Ill...base\Eloquent\Builder>>; however, Wandu\Bridges\Eloquent\E...epository::cacheItems() does only seem to accept object<Illuminate\Database\Eloquent\Collection>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function getItem($id)
84
    {
85
        if (!isset($this->cached[$id])) {
86
            $item = $this->createQuery()->find($id);
87
            if (isset($item)) {
88
                $this->cacheItem($item);
0 ignored issues
show
Bug introduced by
It seems like $item defined by $this->createQuery()->find($id) on line 86 can also be of type object<Illuminate\Database\Eloquent\Builder> or object<Illuminate\Database\Eloquent\Collection>; however, Wandu\Bridges\Eloquent\E...Repository::cacheItem() does only seem to accept object<Illuminate\Database\Eloquent\Model>, 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...
89
            }
90
        }
91
        return isset($this->cached[$id]) ? $this->cached[$id] : null;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function getItemsById(array $arrayOfId)
98
    {
99
        $keyName = $this->getKeyName();
100
        $items = $this->createQuery()->whereIn($keyName, $arrayOfId)->get();
101
        return $this->cacheItems($items);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function updateItem($id, array $dataSet)
108
    {
109
        $item = $this->getItem($id)->fill($this->filterDataSet($dataSet));
110
        $item->save();
111
        return $item;
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117
    public function createItem(array $dataSet)
118
    {
119
        return $this->cacheItem(
120
            forward_static_call(([$this->getAttributeModel(), 'create']), $this->filterDataSet($dataSet))
121
        );
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function deleteItem($id)
128
    {
129
        $this->createQuery()->where($this->createModel()->getKeyName(), $id)->delete();
130
        $this->flushItem($id);
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function cacheItem(Model $item)
137
    {
138
        if ($this->cacheEnabled) {
139
            $this->cached[$item->getKey()] = $item;
140
        }
141
        return $item;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    public function cacheItems(Collection $items)
148
    {
149
        if ($this->cacheEnabled) {
150
            foreach ($items as $item) {
151
                $this->cacheItem($item);
152
            }
153
        }
154
        return $items;
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160
    public function flushItem($id)
161
    {
162
        unset($this->cached[$id]);
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168
    public function flushAllItems()
169
    {
170
        $this->cached = [];
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176
    public function cacheEnable($cacheEnabled = true)
177
    {
178
        $lastCacheEnabled = $this->cacheEnabled;
179
        $this->cacheEnabled = $cacheEnabled;
180
        return $lastCacheEnabled;
181
    }
182
183
    /**
184
     * @param array $dataSet
185
     * @return array
186
     */
187
    public function filterDataSet(array $dataSet)
188
    {
189
        return $dataSet;
190
    }
191
192
    /**
193
     * @param array $where
194
     * @return array
195
     */
196
    public function filterWhere(array $where)
197
    {
198
        return $where;
199
    }
200
201
    /**
202
     * @param \Illuminate\Database\Eloquent\Builder $query
203
     * @param bool $reversed
204
     * @return \Illuminate\Database\Eloquent\Builder
205
     */
206
    protected function applyScopeOrders(Builder $query, $reversed = false)
207
    {
208
        foreach ($this->orders as $key => $asc) {
209
            $query = $query->orderBy($key, $asc ^ $reversed ? 'ASC' : 'DESC');
210
        }
211
        return $query;
212
    }
213
214
    /**
215
     * @return string
216
     */
217
    protected function getKeyName()
218
    {
219
        static $keyName;
220
        if (!isset($keyName)) {
221
            $keyName = $this->createModel()->getKeyName();
222
        }
223
        return $keyName;
224
    }
225
226
    /**
227
     * @return \Illuminate\Database\Eloquent\Builder
228
     */
229
    protected function createQuery()
230
    {
231
        return $this->createModel()->newQuery();
232
    }
233
234
    /**
235
     * @return \Illuminate\Database\Eloquent\Model
236
     */
237
    protected function createModel()
238
    {
239
        $model = $this->getAttributeModel();
240
        return new $model;
241
    }
242
243
    /**
244
     * @return string
245
     */
246
    protected function getAttributeModel()
247
    {
248
        if (isset($this->model) && class_exists($this->model)) {
249
            return $this->model;
250
        }
251
        throw new NotDefinedModelException;
252
    }
253
}
254