Skip to content

Commit d5e875a

Browse files
committed
fix: skip more scope methods that aren't scopes based on types
1 parent 10b6882 commit d5e875a

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;
@@ -142,12 +144,36 @@ private function isAttributeMethod(ClassMethod $classMethod): bool
142144

143145
private function isScopeMethod(ClassMethod $classMethod): bool
144146
{
147+
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'Illuminate\Database\Eloquent\Attributes\Scope')) {
148+
return true;
149+
}
150+
145151
$name = $this->getName($classMethod);
146152

147-
if ((bool) preg_match('/^scope.+$/', $name)) {
153+
if (! (bool) preg_match('/^scope.+$/', $name)) {
154+
return false;
155+
}
156+
157+
// Skip if method has no parameters
158+
if (! isset($classMethod->params[0])) {
159+
return false;
160+
}
161+
162+
// Process if return type or first parameter has no type specified
163+
if (
164+
!$classMethod->returnType instanceof Node
165+
|| ($classMethod->params[0] instanceof Param && !$classMethod->params[0]->type instanceof Node)
166+
) {
148167
return true;
149168
}
150169

151-
return $this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'Illuminate\Database\Eloquent\Attributes\Scope');
170+
// Skip if the first parameter is not eloquent builder
171+
if (! $this->isObjectType($classMethod->params[0], new ObjectType('Illuminate\Database\Eloquent\Builder'))) {
172+
return false;
173+
}
174+
175+
// Process if return type is void or eloquent builder
176+
return ($classMethod->returnType instanceof Identifier && $classMethod->returnType->toString() === 'void')
177+
|| $this->isObjectType($classMethod->returnType, new ObjectType('Illuminate\Database\Eloquent\Builder'));
152178
}
153179
}

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)