Skip to content

Commit 76b6f4f

Browse files
committed
Validate all possible cases
1 parent 2bed45a commit 76b6f4f

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

src/Rules/Keywords/RequireFileExistsRule.php

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ public function getNodeType(): string
2727

2828
public function processNode(Node $node, Scope $scope): array
2929
{
30-
$filePath = $this->resolveFilePath($node, $scope);
31-
if (is_string($filePath) && !is_file($filePath)) {
32-
return [
33-
$this->getErrorMessage($node, $filePath),
34-
];
30+
$errors = [];
31+
$paths = $this->resolveFilePaths($node, $scope);
32+
33+
foreach ($paths as $path) {
34+
if (is_file($path)) {
35+
continue;
36+
}
37+
38+
$errors[] = $this->getErrorMessage($node, $path);
3539
}
3640

37-
return [];
41+
return $errors;
3842
}
3943

4044
private function getErrorMessage(Include_ $node, string $filePath): IdentifierRuleError
@@ -69,12 +73,20 @@ private function getErrorMessage(Include_ $node, string $filePath): IdentifierRu
6973
)->nonIgnorable()->identifier($identifier)->build();
7074
}
7175

72-
private function resolveFilePath(Include_ $node, Scope $scope): ?string
76+
/**
77+
* @return array<string>
78+
*/
79+
private function resolveFilePaths(Include_ $node, Scope $scope): array
7380
{
81+
$paths = [];
7482
$type = $scope->getType($node->expr);
75-
$paths = $type->getConstantStrings();
83+
$constantStrings = $type->getConstantStrings();
84+
85+
foreach ($constantStrings as $constantString) {
86+
$paths[] = $constantString->getValue();
87+
}
7688

77-
return isset($paths[0]) ? $paths[0]->getValue() : null;
89+
return $paths;
7890
}
7991

8092
}

tests/PHPStan/Rules/Keywords/RequireFileExistsRuleTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,28 @@ public function testFileExistsUsingVariables(): void
136136
$this->analyse([__DIR__ . '/data/file-exists-using-a-variable.php'], []);
137137
}
138138

139+
public function testFileDoesNotExistConditionally(): void
140+
{
141+
$this->analyse([__DIR__ . '/data/file-does-not-exist-conditionally.php'], [
142+
[
143+
'Path in include() "a-file-that-does-not-exist.php" is not a file or it does not exist.',
144+
9,
145+
],
146+
[
147+
'Path in include_once() "a-file-that-does-not-exist.php" is not a file or it does not exist.',
148+
10,
149+
],
150+
[
151+
'Path in require() "a-file-that-does-not-exist.php" is not a file or it does not exist.',
152+
11,
153+
],
154+
[
155+
'Path in require_once() "a-file-that-does-not-exist.php" is not a file or it does not exist.',
156+
12,
157+
],
158+
]);
159+
}
160+
139161
public function testFileDoesNotExistButUsesVariables(): void
140162
{
141163
$this->analyse([__DIR__ . '/data/file-does-not-exist-but-uses-a-variable.php'], [
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php declare(strict_types=1);
2+
3+
$path = __DIR__ . '/include-me-to-prove-you-work.txt';
4+
5+
if (rand(0,1)) {
6+
$path = 'a-file-that-does-not-exist.php';
7+
}
8+
9+
include $path;
10+
include_once $path;
11+
require $path;
12+
require_once $path;

0 commit comments

Comments
 (0)