Completed
Push — master ( 771644...bbe480 )
by Michael
01:09
created

Repository::validateQurey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Mblarsen\LaravelRepository;
4
5
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Model;
8
use InvalidArgumentException;
9
use Mblarsen\LaravelRepository\Traits\Filters;
10
use Mblarsen\LaravelRepository\Traits\IncludesRelations;
11
use Mblarsen\LaravelRepository\Traits\Sorts;
12
13
class Repository
14
{
15
    use Filters;
16
    use IncludesRelations;
17
    use Sorts;
18
19
    const WITH_ALLOW_ALL = ['*'];
20
    const WITH_ALLOW_NONE = [];
21
22
    /** @var string */
23
    protected $model;
24
25
    /** @var ResourceContext $resource_context */
26
    protected $resource_context;
27
28
    /** @var array $allowed_with */
29
    protected $allowed_with = self::WITH_ALLOW_NONE;
30
31
    /** @var array $default_with */
32
    protected $default_with = [];
33
34
    /** @var string $default_sort_by */
35
    protected $default_sort_by;
36
37
    /** @var string $default_sort_order */
38
    protected $default_sort_order = 'asc';
39
40
    public function __construct(ResourceContext $resource_context)
41
    {
42
        $this->resource_context = $resource_context;
43
    }
44
45
    /**
46
     * Creates a new repository for a model.
47
     */
48
    public static function for(string $model, ResourceContext $context = null): self
49
    {
50
        $repository = resolve(static::class);
51
        $repository->setModel($model);
52
        if ($context) {
53
            $repository->setContext($context);
54
        }
55
        return $repository;
56
    }
57
58
    /**
59
     * Get the currenct resource context
60
     */
61
    public function getContext(): ResourceContext
62
    {
63
        return $this->resource_context;
64
    }
65
66
    /**
67
     * Set or replace the resource context
68
     */
69
    public function setContext(ResourceContext $resource_context)
70
    {
71
        $this->resource_context = $resource_context;
72
73
        return $this;
74
    }
75
76
    /**
77
     * Set the model
78
     */
79
    public function setModel(string $model)
80
    {
81
        $this->model = $model;
82
83
        return $this;
84
    }
85
86
    /**
87
     * Return all models based on resource context and query
88
     *
89
     * The ResourceContext determines if the result is a Collection or a
90
     * Paginator.
91
     *
92
     * @return LengthAwarePaginator|Collection
93
     */
94
    public function all($query = null)
95
    {
96
        $query = $this->modelQuery($query);
97
98
        return $this
99
            ->validateQurey($query)
100
            ->applyWith($query)
101
            ->applySort($query)
102
            ->applyFilters($query)
103
            ->paginate($query);
104
    }
105
106
    public function find($id, $query = null): Model
107
    {
108
        $query = $this->modelQuery($query);
109
110
        $this
111
            ->validateQurey($query)
112
            ->applyWith($query);
113
114
        $query->whereId($id);
115
116
        return $query->firstOrFail();
117
    }
118
119
    public function create(array $data): Model
120
    {
121
        return $this->model::create($data);
0 ignored issues
show
Bug introduced by
The method create cannot be called on $this->model (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
122
    }
123
124
    public function update(Model $model, array $data): Model
125
    {
126
        $model->update($data);
127
        return $model;
128
    }
129
130
    public function destroy(Model $model)
131
    {
132
        $model->delete();
133
    }
134
135
    protected function modelQuery($query = null)
136
    {
137
        return $query ?? $this->model::query();
0 ignored issues
show
Bug introduced by
The method query cannot be called on $this->model (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
138
    }
139
140
    protected function validateQurey(Builder $query)
141
    {
142
        $model = $this->model;
143
        $query_model = get_class($query->getModel());
144
145
        if ($model !== $query_model) {
146
            throw new InvalidArgumentException("The input query and model does not match");
147
        }
148
149
        return $this;
150
    }
151
152
    /**
153
     * @param Builder $query
154
     * @return LengthAwarePaginator|Collection
155
     */
156
    private function paginate($query)
157
    {
158
        $page = $this->resource_context->page();
159
        $per_page = $this->resource_context->perPage();
160
        $should_paginate = $this->resource_context->paginate();
161
162
        return $should_paginate
163
            ? $query->paginate($per_page, ['*'], 'page', $page)
164
            : $query->get();
165
    }
166
}
167