Completed
Push — develop ( 36f41e...c17836 )
by Nicolas
02:57
created

EloquentBaseRepository::catchByAttributes()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
rs 9.2
cc 4
eloc 9
nc 8
nop 3
1
<?php namespace Modules\Core\Repositories\Eloquent;
2
3
use Illuminate\Database\Eloquent\Builder;
4
use Modules\Core\Repositories\BaseRepository;
5
6
/**
7
 * Class EloquentCoreRepository
8
 *
9
 * @package Modules\Core\Repositories\Eloquent
10
 */
11
abstract class EloquentBaseRepository implements BaseRepository
12
{
13
    /**
14
     * @var Model An instance of the Eloquent Model
15
     */
16
    protected $model;
17
18
    /**
19
     * @param Model $model
20
     */
21
    public function __construct($model)
22
    {
23
        $this->model = $model;
24
    }
25
26
    /**
27
     * @param  int    $id
28
     * @return object
29
     */
30
    public function find($id)
31
    {
32
        if (method_exists($this->model, 'translations')) {
33
            return $this->model->with('translations')->find($id);
34
        }
35
36
        return $this->model->find($id);
37
    }
38
39
    /**
40
     * @return \Illuminate\Database\Eloquent\Collection
41
     */
42
    public function all()
43
    {
44
        if (method_exists($this->model, 'translations')) {
45
            return $this->model->with('translations')->orderBy('created_at', 'DESC')->get();
46
        }
47
48
        return $this->model->orderBy('created_at', 'DESC')->get();
49
    }
50
51
    /**
52
     * @param  mixed  $data
53
     * @return object
54
     */
55
    public function create($data)
56
    {
57
        return $this->model->create($data);
58
    }
59
60
    /**
61
     * @param $model
62
     * @param  array  $data
63
     * @return object
64
     */
65
    public function update($model, $data)
66
    {
67
        $model->update($data);
68
69
        return $model;
70
    }
71
72
    /**
73
     * @param  Model $model
74
     * @return bool
75
     */
76
    public function destroy($model)
77
    {
78
        return $model->delete();
79
    }
80
81
    /**
82
     * Return all resources in the given language
83
     *
84
     * @param  string                                   $lang
85
     * @return \Illuminate\Database\Eloquent\Collection
86
     */
87
    public function allTranslatedIn($lang)
88
    {
89
        return $this->model->whereHas('translations', function (Builder $q) use ($lang) {
90
            $q->where('locale', "$lang");
91
        })->with('translations')->orderBy('created_at', 'DESC')->get();
92
    }
93
94
    /**
95
     * Find a resource by the given slug
96
     *
97
     * @param  string $slug
98
     * @return object
99
     */
100
    public function findBySlug($slug)
101
    {
102
        if (method_exists($this->model, 'translations')) {
103
            return $this->model->whereHas('translations', function (Builder $q) use ($slug) {
104
                $q->where('slug', $slug);
105
            })->with('translations')->first();
106
        }
107
108
        return $this->model->where('slug', $slug)->first();
109
    }
110
111
    /**
112
     * Find a resource by an array of attributes
113
     * @param  array  $attributes
114
     * @return object
115
     */
116
    public function findByAttributes(array $attributes)
117
    {
118
        $query = $this->buildQueryByAttributes($attributes);
119
120
        return $query->first();
121
    }
122
123
    /**
124
     * Get resources by an array of attributes
125
     * @param array $attributes
126
     * @param null|string $orderBy
127
     * @param string $sortOrder
128
     * @return \Illuminate\Database\Eloquent\Collection
129
     */
130
    public function getByAttributes(array $attributes, $orderBy = null, $sortOrder = 'asc')
131
    {
132
        $query = $this->buildQueryByAttributes($attributes, $orderBy, $sortOrder);
133
134
        return $query->get();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $query->get(); (array) is incompatible with the return type declared by the interface Modules\Core\Repositorie...sitory::getByAttributes of type Illuminate\Database\Eloquent\Collection.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
135
    }
136
137
    /**
138
     * Build Query to catch resources by an array of attributes and params
139
     * @param array $attributes
140
     * @param null|string $orderBy
141
     * @param string $sortOrder
142
     * @return \Illuminate\Database\Query\Builder object
143
     */
144
    private function buildQueryByAttributes(array $attributes, $orderBy = null, $sortOrder = 'asc')
145
    {
146
        $query = $this->model->query();
147
148
        if (method_exists($this->model, 'translations')) {
149
            $query = $query->with('translations');
150
        }
151
152
        foreach ($attributes as $field => $value) {
153
            $query = $query->where($field, $value);
154
        }
155
156
        if (null !== $orderBy) {
157
            $query->orderBy($orderBy, $sortOrder);
158
        }
159
160
        return $query;
161
    }
162
163
    /**
164
     * Return a collection of elements who's ids match
165
     * @param array $ids
166
     * @return mixed
167
     */
168
    public function findByMany(array $ids)
169
    {
170
        $query = $this->model->query();
171
172
        if (method_exists($this->model, 'translations')) {
173
            $query = $query->with('translations');
174
        }
175
176
        return $query->whereIn("id", $ids)->get();
177
    }
178
179
    /**
180
     * Clear the cache for this Repositories' Entity
181
     * @return bool
182
     */
183
    public function clearCache()
184
    {
185
        return true;
186
    }
187
}
188