Skip to content

Commit 1a5b619

Browse files
committed
fix: skip more scope methods that aren't scopes based on types
1 parent 06b5c1d commit 1a5b619

File tree

5 files changed

+153
-17
lines changed

5 files changed

+153
-17
lines changed

src/Rector/ClassMethod/MakeModelAttributesAndScopesProtectedRector.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace RectorLaravel\Rector\ClassMethod;
66

77
use PhpParser\Node;
8+
use PhpParser\Node\Identifier;
9+
use PhpParser\Node\Param;
810
use PhpParser\Node\Stmt\ClassMethod;
911
use PHPStan\Analyser\Scope;
1012
use PHPStan\Reflection\ClassReflection;
@@ -136,12 +138,36 @@ private function isAttributeMethod(ClassMethod $classMethod): bool
136138

137139
private function isScopeMethod(ClassMethod $classMethod): bool
138140
{
141+
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'Illuminate\Database\Eloquent\Attributes\Scope')) {
142+
return true;
143+
}
144+
139145
$name = $this->getName($classMethod);
140146

141-
if ((bool) preg_match('/^scope.+$/', $name)) {
147+
if (! (bool) preg_match('/^scope.+$/', $name)) {
148+
return false;
149+
}
150+
151+
// Skip if method has no parameters
152+
if (! isset($classMethod->params[0])) {
153+
return false;
154+
}
155+
156+
// Process if return type or first parameter has no type specified
157+
if (
158+
! $classMethod->returnType instanceof Node
159+
|| ($classMethod->params[0] instanceof Param && ! $classMethod->params[0]->type instanceof Node)
160+
) {
142161
return true;
143162
}
144163

145-
return $this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'Illuminate\Database\Eloquent\Attributes\Scope');
164+
// Skip if the first parameter is not eloquent builder
165+
if (! $this->isObjectType($classMethod->params[0], new ObjectType('Illuminate\Database\Eloquent\Builder'))) {
166+
return false;
167+
}
168+
169+
// Process if return type is void or eloquent builder
170+
return ($classMethod->returnType instanceof Identifier && $classMethod->returnType->toString() === 'void')
171+
|| $this->isObjectType($classMethod->returnType, new ObjectType('Illuminate\Database\Eloquent\Builder'));
146172
}
147173
}

tests/Rector/ClassMethod/MakeModelAttributesAndScopesProtectedRector/Fixture/final_model.php.inc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ final class User extends Model
2323
return $query;
2424
}
2525

26+
private function scopeInactive(Builder $query): void
27+
{
28+
$query->where('active', false);
29+
}
30+
31+
private function scopeParam($query): void
32+
{
33+
$query->where('active', false);
34+
}
35+
36+
private function scopeNone($query)
37+
{
38+
$query->where('active', false);
39+
}
40+
41+
private function scopeReturn(Builder $query)
42+
{
43+
$query->where('active', false);
44+
}
45+
2646
#[Scope]
2747
private function verified(Builder $query): Builder
2848
{
@@ -57,6 +77,26 @@ final class User extends Model
5777
return $query;
5878
}
5979

80+
protected function scopeInactive(Builder $query): void
81+
{
82+
$query->where('active', false);
83+
}
84+
85+
protected function scopeParam($query): void
86+
{
87+
$query->where('active', false);
88+
}
89+
90+
protected function scopeNone($query)
91+
{
92+
$query->where('active', false);
93+
}
94+
95+
protected function scopeReturn(Builder $query)
96+
{
97+
$query->where('active', false);
98+
}
99+
60100
#[Scope]
61101
protected function verified(Builder $query): Builder
62102
{

tests/Rector/ClassMethod/MakeModelAttributesAndScopesProtectedRector/Fixture/fixture.php.inc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ class User extends Model
2323
return $query;
2424
}
2525

26+
public function scopeInactive(Builder $query): void
27+
{
28+
$query->where('active', false);
29+
}
30+
31+
public function scopeParam($query): void
32+
{
33+
$query->where('active', false);
34+
}
35+
36+
public function scopeNone($query)
37+
{
38+
$query->where('active', false);
39+
}
40+
41+
public function scopeReturn(Builder $query)
42+
{
43+
$query->where('active', false);
44+
}
45+
2646
#[Scope]
2747
public function verified(Builder $query): Builder
2848
{
@@ -64,6 +84,26 @@ class User extends Model
6484
return $query;
6585
}
6686

87+
protected function scopeInactive(Builder $query): void
88+
{
89+
$query->where('active', false);
90+
}
91+
92+
protected function scopeParam($query): void
93+
{
94+
$query->where('active', false);
95+
}
96+
97+
protected function scopeNone($query)
98+
{
99+
$query->where('active', false);
100+
}
101+
102+
protected function scopeReturn(Builder $query)
103+
{
104+
$query->where('active', false);
105+
}
106+
67107
#[Scope]
68108
protected function verified(Builder $query): Builder
69109
{

tests/Rector/ClassMethod/MakeModelAttributesAndScopesProtectedRector/Fixture/skip_scope_method_not_scope.php.inc

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\ClassMethod\MakeModelAttributesAndScopesProtectedRector\Fixture;
4+
5+
use Illuminate\Database\Eloquent\Builder;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
8+
use Illuminate\Database\Eloquent\Relations\HasMany;
9+
10+
class SkipScopeMethodsNotScope extends Model
11+
{
12+
public function scope(): string
13+
{
14+
return 'foo';
15+
}
16+
17+
public function scopeItem(): BelongsTo
18+
{
19+
return $this->belongsTo(ScopeItem::class);
20+
}
21+
22+
public function scopedItems(): HasMany
23+
{
24+
return $this->hasMany(ScopedItem::class);
25+
}
26+
27+
public function scopeQuery(): Builder
28+
{
29+
return $this->where('foo', true);
30+
}
31+
32+
public function scopeParam(string $param): Builder
33+
{
34+
return $this->where('foo', true);
35+
}
36+
37+
public function scopeString(Builder $builder): string
38+
{
39+
return 'foo';
40+
}
41+
42+
public function scopeVoid(): void {}
43+
}
44+
45+
?>

0 commit comments

Comments
 (0)