Skip to content

Commit dedd89e

Browse files
authored
Fix interpolation processing in ValidationRuleArrayStringValueToArrayRector (#396)
1 parent bd65479 commit dedd89e

File tree

3 files changed

+28
-33
lines changed

3 files changed

+28
-33
lines changed

src/Rector/MethodCall/ValidationRuleArrayStringValueToArrayRector.php

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use PhpParser\Node\Expr\Array_;
99
use PhpParser\Node\Expr\MethodCall;
1010
use PhpParser\Node\Expr\StaticCall;
11-
use PhpParser\Node\Expr\Variable;
1211
use PhpParser\Node\InterpolatedStringPart;
1312
use PhpParser\Node\Scalar\InterpolatedString;
1413
use PhpParser\Node\Scalar\String_;
@@ -99,50 +98,34 @@ private function processStringRule(String_ $string): Array_
9998

10099
private function processInterpolatedStringRule(InterpolatedString $interpolatedString): Array_
101100
{
102-
$intermediateRules = [];
101+
// Build rule parts by splitting on pipes while preserving variables
102+
$allRuleParts = [];
103+
$currentParts = [];
103104

104105
foreach ($interpolatedString->parts as $part) {
105106
if ($part instanceof InterpolatedStringPart) {
106-
$newParts = explode('|', $part->value);
107-
$intermediateRules[] = new InterpolatedString(array_map(static fn ($part) => new InterpolatedStringPart($part), $newParts));
108-
} elseif ($part instanceof Variable) {
109-
$intermediateRules[] = $part;
110-
}
111-
}
112-
113-
$finalRules = [];
114-
foreach ($intermediateRules as $key => $rulePart) {
115-
$nextRule = $intermediateRules[$key + 1] ?? null;
116-
$prevRule = $intermediateRules[$key - 1] ?? null;
117-
118-
if ($rulePart instanceof Variable) {
119-
$finalRule = new InterpolatedString([$rulePart]);
120-
121-
if ($prevRule instanceof InterpolatedString) {
122-
$lastPart = array_pop($prevRule->parts);
123-
if ($lastPart instanceof InterpolatedStringPart) {
124-
array_unshift($finalRule->parts, $lastPart);
107+
$segments = explode('|', $part->value);
108+
foreach ($segments as $index => $segment) {
109+
// Complete current rule and start new one
110+
if ($index !== 0 && $currentParts !== []) {
111+
$allRuleParts[] = $currentParts;
112+
$currentParts = [];
125113
}
126-
$intermediateRules[$key - 1] = $prevRule;
127-
}
128114

129-
if ($nextRule instanceof InterpolatedString) {
130-
$firstPart = array_shift($nextRule->parts);
131-
if ($firstPart instanceof InterpolatedStringPart) {
132-
$finalRule->parts[] = $firstPart;
115+
if ($segment !== '') {
116+
$currentParts[] = new InterpolatedStringPart($segment);
133117
}
134-
$intermediateRules[$key + 1] = $nextRule;
135118
}
136-
137-
$finalRules[] = $finalRule;
138119
} else {
139-
$finalRules[] = $rulePart;
120+
$currentParts[] = $part; // Variables and other parts
140121
}
141122
}
142123

143-
$finalRules = array_filter($finalRules, fn (InterpolatedString $interpolatedString) => count($interpolatedString->parts) > 0);
124+
if ($currentParts !== []) {
125+
$allRuleParts[] = $currentParts;
126+
}
144127

145-
return new Array_(array_map(static fn (InterpolatedString $interpolatedString) => new ArrayItem($interpolatedString), $finalRules));
128+
return new Array_(array_map(fn ($parts) => new ArrayItem(new InterpolatedString($parts)), $allRuleParts));
146129
}
147130

148131
private function refactorCall(StaticCall|MethodCall $node): StaticCall|MethodCall|null

tests/Rector/MethodCall/ValidationRuleArrayStringValueToArrayRector/Fixture/applies_to_http_requests.php.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ namespace RectorLaravel\Tests\Rector\MethodCall\ValidationRuleArrayStringValueTo
44

55
class AppliesToHttpRequests
66
{
7+
private int $size = 500;
8+
79
public function store(\Illuminate\Http\Request $request)
810
{
911
$request->validate([
1012
'name' => 'required|string',
13+
'layout' => "required|mimes:png|dimensions:width={$this->size},height={$this->size}",
1114
]);
1215
}
1316
}
@@ -20,10 +23,13 @@ namespace RectorLaravel\Tests\Rector\MethodCall\ValidationRuleArrayStringValueTo
2023

2124
class AppliesToHttpRequests
2225
{
26+
private int $size = 500;
27+
2328
public function store(\Illuminate\Http\Request $request)
2429
{
2530
$request->validate([
2631
'name' => ['required', 'string'],
32+
'layout' => ["required", "mimes:png", "dimensions:width={$this->size},height={$this->size}"],
2733
]);
2834
}
2935
}

tests/Rector/MethodCall/ValidationRuleArrayStringValueToArrayRector/Fixture/applies_to_string_interpolation.php.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ namespace RectorLaravel\Tests\Rector\MethodCall\ValidationRuleArrayStringValueTo
55
function something(\Illuminate\Validation\Factory $validator) {
66
$usersTable = 'users';
77
$required = 'required';
8+
$size = 500;
89

910
$validator->make(['user_id' => 1], [
1011
'user_id' => "required|exists:{$usersTable},id|integer",
1112
'user_other_id' => "{$required}|exists:{$usersTable},id|{$required}",
13+
'layout' => "required|mimes:png|dimensions:width={$size},height={$size}",
14+
'layouts' => "required|mimes:png|dimensions:width={$validator->size},height={$validator->size}",
1215
]);
1316
}
1417

@@ -21,10 +24,13 @@ namespace RectorLaravel\Tests\Rector\MethodCall\ValidationRuleArrayStringValueTo
2124
function something(\Illuminate\Validation\Factory $validator) {
2225
$usersTable = 'users';
2326
$required = 'required';
27+
$size = 500;
2428

2529
$validator->make(['user_id' => 1], [
2630
'user_id' => ["required", "exists:{$usersTable},id", "integer"],
2731
'user_other_id' => ["{$required}", "exists:{$usersTable},id", "{$required}"],
32+
'layout' => ["required", "mimes:png", "dimensions:width={$size},height={$size}"],
33+
'layouts' => ["required", "mimes:png", "dimensions:width={$validator->size},height={$validator->size}"],
2834
]);
2935
}
3036

0 commit comments

Comments
 (0)