Completed
Push — develop ( 883dc0...f892f9 )
by Abdelrahman
11:46 queued 12s
created

EloquentRepository::findFirst()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Rinvex Repository Package.
7
 *
8
 * This source file is subject to The MIT License (MIT)
9
 * that is bundled with this package in the LICENSE file.
10
 *
11
 * Package: Rinvex Repository Package
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
namespace Rinvex\Repository\Repositories;
17
18
use Illuminate\Database\Eloquent\Model;
19
use Illuminate\Pagination\Paginator;
20
use Rinvex\Repository\Exceptions\RepositoryException;
21
22
class EloquentRepository extends BaseRepository
23
{
24
    /**
25
     * Create a new repository model instance.
26
     *
27
     * @throws \Rinvex\Repository\Exceptions\RepositoryException
28
     *
29
     * @return \Illuminate\Database\Eloquent\Model
30
     */
31
    public function createModel()
32
    {
33
        if (is_string($model = $this->getModel())) {
34
            if (! class_exists($class = '\\'.ltrim($model, '\\'))) {
35
                throw new RepositoryException("Class {$model} does NOT exist!");
36
            }
37
38
            $model = $this->getContainer()->make($class);
39
        }
40
41
        if (! $model instanceof Model) {
42
            throw new RepositoryException("Class {$model} must be an instance of \\Illuminate\\Database\\Eloquent\\Model");
43
        }
44
45
        return $model;
46
    }
47
48
    /**
49
     * Find an entity by it's primary key.
50
     *
51
     * @param int   $id
52
     * @param array $attributes
53
     *
54
     * @return \Illuminate\Database\Eloquent\Model
55
     */
56
    public function find($id, $attributes = ['*'])
57
    {
58
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($id, $attributes) {
59
            return $this->prepareQuery($this->createModel())->find($id, $attributes);
60
        });
61
    }
62
63
    /**
64
     * Find an entity by one of it's attributes.
65
     *
66
     * @param string $attribute
67
     * @param string $value
68
     * @param array  $attributes
69
     *
70
     * @return \Illuminate\Database\Eloquent\Model
71
     */
72
    public function findBy($attribute, $value, $attributes = ['*'])
73
    {
74
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attribute, $value, $attributes) {
75
            return $this->prepareQuery($this->createModel())->where($attribute, '=', $value)->first($attributes);
76
        });
77
    }
78
79
    /**
80
     * Find the first entity.
81
     *
82
     * @param array $attributes
83
     *
84
     * @return \Illuminate\Database\Eloquent\Model
85
     */
86
    public function findFirst($attributes = ['*'])
87
    {
88
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attributes) {
89
            return $this->prepareQuery($this->createModel())->first($attributes);
90
        });
91
    }
92
93
    /**
94
     * Find all entities.
95
     *
96
     * @param array $attributes
97
     *
98
     * @return \Illuminate\Support\Collection
99
     */
100
    public function findAll($attributes = ['*'])
101
    {
102
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attributes) {
103
            return $this->prepareQuery($this->createModel())->get($attributes);
104
        });
105
    }
106
107
    /**
108
     * Paginate all entities.
109
     *
110
     * @param int|null $perPage
111
     * @param array    $attributes
112
     * @param string   $pageName
113
     * @param int|null $page
114
     *
115
     * @throws \InvalidArgumentException
116
     *
117
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
118
     */
119
    public function paginate($perPage = null, $attributes = ['*'], $pageName = 'page', $page = null)
120
    {
121
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
122
123
        return $this->executeCallback(get_called_class(), __FUNCTION__, array_merge(func_get_args(), compact('page')), function () use ($perPage, $attributes, $pageName, $page) {
124
            return $this->prepareQuery($this->createModel())->paginate($perPage, $attributes, $pageName, $page);
125
        });
126
    }
127
128
    /**
129
     * Paginate all entities into a simple paginator.
130
     *
131
     * @param int|null $perPage
132
     * @param array    $attributes
133
     * @param string   $pageName
134
     * @param int|null $page
135
     *
136
     * @return \Illuminate\Contracts\Pagination\Paginator
137
     */
138
    public function simplePaginate($perPage = null, $attributes = ['*'], $pageName = 'page', $page = null)
139
    {
140
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
141
142
        return $this->executeCallback(get_called_class(), __FUNCTION__, array_merge(func_get_args(), compact('page')), function () use ($perPage, $attributes, $pageName, $page) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 178 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
143
            return $this->prepareQuery($this->createModel())->simplePaginate($perPage, $attributes, $pageName, $page);
144
        });
145
    }
146
147
    /**
148
     * Find all entities matching where conditions.
149
     *
150
     * @param array $where
151
     * @param array $attributes
152
     *
153
     * @return \Illuminate\Support\Collection
154
     */
155
    public function findWhere(array $where, $attributes = ['*'])
156
    {
157
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
158
            list($attribute, $operator, $value, $boolean) = array_pad($where, 4, null);
159
160
            $this->where($attribute, $operator, $value, $boolean);
161
162
            return $this->prepareQuery($this->createModel())->get($attributes);
163
        });
164
    }
165
166
    /**
167
     * Find all entities matching whereIn conditions.
168
     *
169
     * @param array $where
170
     * @param array $attributes
171
     *
172
     * @return \Illuminate\Support\Collection
173
     */
174
    public function findWhereIn(array $where, $attributes = ['*'])
175
    {
176
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
177
            list($attribute, $values, $boolean, $not) = array_pad($where, 4, null);
178
179
            $this->whereIn($attribute, $values, $boolean, $not);
180
181
            return $this->prepareQuery($this->createModel())->get($attributes);
182
        });
183
    }
184
185
    /**
186
     * Find all entities matching whereNotIn conditions.
187
     *
188
     * @param array $where
189
     * @param array $attributes
190
     *
191
     * @return \Illuminate\Support\Collection
192
     */
193
    public function findWhereNotIn(array $where, $attributes = ['*'])
194
    {
195
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
196
            list($attribute, $values, $boolean) = array_pad($where, 3, null);
197
198
            $this->whereNotIn($attribute, $values, $boolean);
199
200
            return $this->prepareQuery($this->createModel())->get($attributes);
201
        });
202
    }
203
204
    /**
205
     * Create a new entity with the given attributes.
206
     *
207
     * @param array $attributes
208
     *
209
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be Model|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
210
     */
211
    public function create(array $attributes = [])
212
    {
213
        // Create a new instance
214
        $instance = $this->createModel();
215
216
        // Fire the created event
217
        $this->getContainer('events')->fire($this->getRepositoryId().'.entity.creating', [$this, $instance]);
218
219
        // Fill instance with data
220
        $instance->fill($attributes);
221
222
        // Save the instance
223
        $created = $instance->save();
224
225
        // Fire the created event
226
        $this->getContainer('events')->fire($this->getRepositoryId().'.entity.created', [$this, $instance]);
227
228
        // Return instance
229
        return $created ? $instance : $created;
230
    }
231
232
    /**
233
     * Update an entity with the given attributes.
234
     *
235
     * @param mixed $id
236
     * @param array $attributes
237
     *
238
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be Model|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
239
     */
240
    public function update($id, array $attributes = [])
241
    {
242
        // Find the given instance
243
        $instance = $id instanceof Model ? $id : $this->find($id);
244
245
        if ($instance) {
246
            // Fire the updated event
247
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.updating', [$this, $instance]);
248
249
            // Fill instance with data
250
            $instance->fill($attributes);
251
252
            // Update the instance
253
            $updated = $instance->save();
254
255
            // Fire the updated event
256
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.updated', [$this, $instance]);
257
        }
258
259
        return $updated ? $instance : $updated;
0 ignored issues
show
Bug introduced by
The variable $updated does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
260
    }
261
262
    /**
263
     * Delete an entity with the given id.
264
     *
265
     * @param mixed $id
266
     *
267
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null|Model?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
268
     */
269
    public function delete($id)
270
    {
271
        // Find the given instance
272
        $deleted  = false;
273
274
        // Find the given instance
275
        $instance = $id instanceof Model ? $id : $this->find($id);
276
277
        if ($instance) {
278
            // Fire the deleted event
279
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.deleting', [$this, $instance]);
280
281
            // Delete the instance
282
            $deleted = $instance->delete();
283
284
            // Fire the deleted event
285
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.deleted', [$this, $instance]);
286
        }
287
288
        return $deleted ? $instance : $deleted;
289
    }
290
}
291