Passed
Push — main ( 0a0d57...b7c40f )
by Mohammad
13:52
created

AbstractRepository::getNewBuilderWithScope()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 12
rs 10
c 0
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 */
0 ignored issues
show
Bug introduced by
The type Shamaseen\Repository\Utility\TModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
    public EloquentModel&CriteriableModelInterface $model;
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> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TModel> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TModel>.
Loading history...
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|string $id, array $columns = ['*']): EloquentModel
69
    {
70
        return $this->getNewBuilderWithScope()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getNewBuil...ndOrFail($id, $columns) returns the type Illuminate\Database\Eloq...iteriableModelInterface which is incompatible with the documented return type Shamaseen\Repository\Utility\TModel.
Loading history...
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);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getNewBuil...hScope()->create($data) returns the type Illuminate\Database\Eloq...iteriableModelInterface which is incompatible with the documented return type Shamaseen\Repository\Utility\TModel.
Loading history...
79
    }
80
81
    /** @return TModel|int|bool */
82
    public function update(int|string $id, array $data = []): int|bool|EloquentModel
83
    {
84
        return $this->getNewBuilderWithScope()->where('id', $id)->update($data);
85
    }
86
87
    public function delete(int|string $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()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getNewBuil...riteria)->get($columns) returns the type Illuminate\Database\Eloquent\Collection which is incompatible with the documented return type Illuminate\Database\Eloquent\Builder.
Loading history...
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|string $id, array $columns = ['*']): ?EloquentModel
107
    {
108
        return $this->getNewBuilderWithScope()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getNewBuil...h)->find($id, $columns) also could return the type Illuminate\Database\Eloq...iteriableModelInterface which is incompatible with the documented return type Shamaseen\Repository\Utility\TModel|null.
Loading history...
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()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getNewBuil...teria)->first($columns) also could return the type Illuminate\Database\Eloq...iteriableModelInterface which is incompatible with the documented return type Shamaseen\Repository\Utility\TModel|null.
Loading history...
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()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getNewBuil...desc')->first($columns) also could return the type Illuminate\Database\Eloq...iteriableModelInterface which is incompatible with the documented return type Shamaseen\Repository\Utility\TModel|null.
Loading history...
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
    public 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