Passed
Push — main ( 2ceb1b...d116ca )
by Mohammad
03:09
created

AbstractRepository::update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
/** @noinspection PhpUndefinedMethodInspection */
4
/** @noinspection DuplicatedCode */
5
/** @noinspection PhpMultipleClassDeclarationsInspection */
6
7
namespace Shamaseen\Repository\Utility;
8
9
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
10
use Illuminate\Contracts\Pagination\Paginator;
11
use Illuminate\Database\Eloquent\Builder;
12
use Illuminate\Database\Eloquent\Collection;
13
use Illuminate\Database\Eloquent\Model as EloquentModel;
14
use Illuminate\Support\Facades\App;
15
use Shamaseen\Repository\Interfaces\CriteriableModelInterface;
16
17
/**
18
 * Class Database.
19
 *
20
 * @template TModel of EloquentModel&CriteriableModelInterface
21
 */
22
abstract class AbstractRepository implements RepositoryInterface
23
{
24
    /** @var TModel */
25
    public EloquentModel&CriteriableModelInterface $model;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected '&', expecting T_VARIABLE on line 25 at column 24
Loading history...
26
27
    protected ?string $order = null;
28
29
    protected string $direction = 'desc';
30
31
    public array $with = [];
32
33
    private array $scopes = [];
34
35
    public function __construct()
36
    {
37
        $this->model = App::make($this->getModelClass());
38
    }
39
40
    /** @return class-string<TModel> */
41
    abstract public function getModelClass(): string;
42
43
    /** @return LengthAwarePaginator<TModel> */
44
    public function paginate(int $limit = 10, array $criteria = []): LengthAwarePaginator
45
    {
46
        $this->injectDefaultCriteria($criteria);
47
48
        return $this->getNewBuilderWithScope()
49
            ->with($this->with)
50
            ->orderByCriteria($criteria)
51
            ->searchByCriteria($criteria)
52
            ->filterByCriteria($criteria)
53
            ->paginate($limit);
54
    }
55
56
    /** @return Paginator<TModel> */
57
    public function simplePaginate(int $limit = 10, array $criteria = []): Paginator
58
    {
59
        return $this->getNewBuilderWithScope()
60
            ->with($this->with)
61
            ->orderByCriteria($criteria)
62
            ->searchByCriteria($criteria)
63
            ->filterByCriteria($criteria)
64
            ->simplePaginate($limit);
65
    }
66
67
    /** @return TModel */
68
    public function findOrFail(int $id, array $columns = ['*']): EloquentModel
69
    {
70
        return $this->getNewBuilderWithScope()
71
            ->with($this->with)
72
            ->findOrFail($id, $columns);
73
    }
74
75
    /** @return TModel */
76
    public function create(array $data = []): EloquentModel
77
    {
78
        return $this->getNewBuilderWithScope()->create($data);
79
    }
80
81
    /** @return TModel|int|bool */
82
    public function update(int $id, array $data = []): int|bool|EloquentModel
83
    {
84
        return $this->getNewBuilderWithScope()->where('id', $id)->update($data);
85
    }
86
87
    public function delete(int $id = 0): int|bool
88
    {
89
        return $this->getNewBuilderWithScope()->where('id', $id)->delete();
90
    }
91
92
    /**
93
     * @return Builder<TModel>[]|Collection<int, TModel>
94
     */
95
    public function get(array $criteria = [], array $columns = ['*']): Collection|array
96
    {
97
        return $this->getNewBuilderWithScope()
98
            ->with($this->with)
99
            ->orderByCriteria($criteria)
100
            ->searchByCriteria($criteria)
101
            ->filterByCriteria($criteria)
102
            ->get($columns);
103
    }
104
105
    /** @return ?TModel */
106
    public function find(int $id, array $columns = ['*']): ?EloquentModel
107
    {
108
        return $this->getNewBuilderWithScope()
109
            ->with($this->with)
110
            ->find($id, $columns);
111
    }
112
113
    /** @return ?TModel */
114
    public function first(array $criteria = [], array $columns = ['*']): ?EloquentModel
115
    {
116
        return $this->getNewBuilderWithScope()
117
            ->with($this->with)
118
            ->orderByCriteria($criteria)
119
            ->searchByCriteria($criteria)
120
            ->filterByCriteria($criteria)
121
            ->first($columns);
122
    }
123
124
    /** @return ?TModel */
125
    public function last(string $key = 'id', array $criteria = [], array $columns = ['*']): ?EloquentModel
126
    {
127
        return $this->getNewBuilderWithScope()
128
            ->with($this->with)
129
            ->searchByCriteria($criteria)
130
            ->filterByCriteria($criteria)
131
            ->orderBy($key, 'desc')
132
            ->first($columns);
133
    }
134
135
    public function injectDefaultCriteria(array &$criteria): void
136
    {
137
        $criteria['order'] = $criteria['order'] ?? $this->order;
138
        $criteria['direction'] = $criteria['direction'] ?? $this->direction;
139
    }
140
141
    public function scope(callable $callable): static
142
    {
143
        $this->scopes[] = $callable;
144
145
        return $this;
146
    }
147
148
    /**
149
     * @return Builder<TModel>
150
     */
151
    private function getNewBuilderWithScope(): Builder
152
    {
153
        /** @var Builder<TModel> $newQuery */
154
        $newQuery = $this->model->newQuery();
155
156
        foreach ($this->scopes as $scope) {
157
            $scope($newQuery);
158
        }
159
160
        $this->scopes = [];
161
162
        return $newQuery;
163
    }
164
}
165