1 | <?php |
||||
2 | |||||
3 | namespace JPNut\Versioning; |
||||
4 | |||||
5 | use Carbon\Carbon; |
||||
6 | use Illuminate\Database\Eloquent\Builder; |
||||
7 | use Illuminate\Database\Eloquent\Model; |
||||
8 | use Illuminate\Database\Eloquent\Scope; |
||||
9 | use Illuminate\Database\Query\JoinClause; |
||||
10 | |||||
11 | class VersioningScope implements Scope |
||||
12 | { |
||||
13 | /** |
||||
14 | * All of the extensions to be added to the builder. |
||||
15 | * |
||||
16 | * @var array |
||||
17 | */ |
||||
18 | protected array $extensions = ['AtVersion', 'AtTime']; |
||||
19 | |||||
20 | /** |
||||
21 | * Apply the scope to a given Eloquent query builder. |
||||
22 | * |
||||
23 | * @param \Illuminate\Database\Eloquent\Builder $builder |
||||
24 | * @param \Illuminate\Database\Eloquent\Model|\JPNut\Versioning\Versionable $model |
||||
25 | * |
||||
26 | * @return void |
||||
27 | */ |
||||
28 | public function apply(Builder $builder, Model $model) |
||||
29 | { |
||||
30 | // |
||||
31 | } |
||||
32 | |||||
33 | /** |
||||
34 | * Extend the query builder with the needed functions. |
||||
35 | * |
||||
36 | * @param \Illuminate\Database\Eloquent\Builder $builder |
||||
37 | * |
||||
38 | * @return void |
||||
39 | */ |
||||
40 | public function extend(Builder $builder) |
||||
41 | { |
||||
42 | foreach ($this->extensions as $extension) { |
||||
43 | $this->{"add{$extension}"}($builder); |
||||
44 | } |
||||
45 | } |
||||
46 | |||||
47 | /** |
||||
48 | * @param \Illuminate\Database\Eloquent\Builder $builder |
||||
49 | * |
||||
50 | * @return void |
||||
51 | */ |
||||
52 | protected function addAtVersion(Builder $builder) |
||||
53 | { |
||||
54 | $builder->macro( |
||||
55 | 'atVersion', |
||||
56 | function (Builder $builder, $version) { |
||||
57 | /** @var \Illuminate\Database\Eloquent\Model|\JPNut\Versioning\Versionable $model */ |
||||
58 | $model = $builder->getModel(); |
||||
59 | |||||
60 | $this->remove($builder, $builder->getModel()); |
||||
61 | |||||
62 | $builder |
||||
63 | ->join( |
||||
64 | $model->getVersionTable(), |
||||
65 | function ($join) use ($model, $version) { |
||||
66 | $join->on( |
||||
67 | $model->getQualifiedKeyName(), '=', $model->getQualifiedVersionTableForeignKeyName() |
||||
0 ignored issues
–
show
|
|||||
68 | ) |
||||
69 | ->where($model->getQualifiedVersionTableKeyName(), '=', $version); |
||||
70 | } |
||||
71 | ) |
||||
72 | ->select( |
||||
73 | $model->defaultVersionSelect() |
||||
74 | ); |
||||
75 | |||||
76 | return $builder; |
||||
77 | } |
||||
78 | ); |
||||
79 | } |
||||
80 | |||||
81 | /** |
||||
82 | * Remove the scope from the given Eloquent query builder. |
||||
83 | * |
||||
84 | * @param \Illuminate\Database\Eloquent\Builder $builder |
||||
85 | * @param \Illuminate\Database\Eloquent\Model|\JPNut\Versioning\Versionable $model |
||||
86 | * |
||||
87 | * @return void |
||||
88 | */ |
||||
89 | public function remove(Builder $builder, Model $model) |
||||
90 | { |
||||
91 | $table = $model->getVersionTable(); |
||||
92 | |||||
93 | $query = $builder->getQuery(); |
||||
94 | |||||
95 | $query->joins = collect($query->joins)->reject( |
||||
96 | function ($join) use ($table) { |
||||
97 | return $this->isVersionJoinConstraint($join, $table); |
||||
0 ignored issues
–
show
It seems like
$table can also be of type Illuminate\Database\Eloquent\Builder ; however, parameter $table of JPNut\Versioning\Version...VersionJoinConstraint() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
98 | } |
||||
99 | )->values()->all(); |
||||
100 | } |
||||
101 | |||||
102 | /** |
||||
103 | * Determine if the given join clause is a version constraint. |
||||
104 | * |
||||
105 | * @param \Illuminate\Database\Query\JoinClause $join |
||||
106 | * @param string $table |
||||
107 | * |
||||
108 | * @return bool |
||||
109 | */ |
||||
110 | protected function isVersionJoinConstraint(JoinClause $join, string $table) |
||||
111 | { |
||||
112 | return $join->type === 'inner' && $join->table === $table; |
||||
113 | } |
||||
114 | |||||
115 | /** |
||||
116 | * @param \Illuminate\Database\Eloquent\Builder $builder |
||||
117 | * |
||||
118 | * @return void |
||||
119 | */ |
||||
120 | protected function addAtTime(Builder $builder) |
||||
121 | { |
||||
122 | $builder->macro( |
||||
123 | 'atTime', |
||||
124 | function (Builder $builder, Carbon $moment) { |
||||
125 | /** @var \Illuminate\Database\Eloquent\Model|\JPNut\Versioning\Versionable $model */ |
||||
126 | $model = $builder->getModel(); |
||||
127 | |||||
128 | $this->remove($builder, $builder->getModel()); |
||||
129 | |||||
130 | $createdAt = $model->getQualifiedVersionTableCreatedAtName(); |
||||
131 | |||||
132 | $builder |
||||
133 | ->join( |
||||
134 | $model->getVersionTable(), |
||||
135 | function ($join) use ($model, $moment, $createdAt) { |
||||
136 | $join->on( |
||||
137 | $model->getQualifiedKeyName(), '=', $model->getQualifiedVersionTableForeignKeyName() |
||||
138 | ) |
||||
139 | ->where($createdAt, '<=', $moment) |
||||
140 | ->orderBy($createdAt, 'desc') |
||||
141 | ->limit(1); |
||||
142 | } |
||||
143 | ) |
||||
144 | ->orderBy($createdAt, 'desc') |
||||
0 ignored issues
–
show
It seems like
$createdAt can also be of type Illuminate\Database\Eloquent\Builder ; however, parameter $column of Illuminate\Database\Query\Builder::orderBy() does only seem to accept Closure|Illuminate\Database\Query\Builder|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
145 | ->limit(1) |
||||
146 | ->select( |
||||
147 | $model->defaultVersionSelect() |
||||
148 | ); |
||||
149 | |||||
150 | return $builder; |
||||
151 | } |
||||
152 | ); |
||||
153 | } |
||||
154 | } |
||||
155 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.