Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ba45518

Browse filesBrowse files
committed
Use Twig environment loader
1 parent d366e51 commit ba45518
Copy full SHA for ba45518
Expand file treeCollapse file tree

13 files changed

+84
-108
lines changed

‎composer.json

Copy file name to clipboardExpand all lines: composer.json
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"symfony/messenger": "^5.4",
3737
"symfony/polyfill-php80": "^1.24",
3838
"symfony/serializer": "^5.4",
39-
"symfony/service-contracts": "^2.2.0"
39+
"symfony/service-contracts": "^2.2.0",
40+
"twig/twig": "^3.0"
4041
},
4142
"config": {
4243
"sort-packages": true

‎extension.neon

Copy file name to clipboardExpand all lines: extension.neon
+4-6Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ parameters:
1111
constantHassers: true
1212
console_application_loader: null
1313
consoleApplicationLoader: null
14-
twigTemplateDirectories: []
14+
twigEnvironmentLoader: null
1515
featureToggles:
1616
skipCheckGenericClasses:
1717
- Symfony\Component\Form\AbstractType
@@ -116,7 +116,7 @@ parametersSchema:
116116
constantHassers: bool()
117117
console_application_loader: schema(string(), nullable())
118118
consoleApplicationLoader: schema(string(), nullable())
119-
twigTemplateDirectories: arrayOf(schema(string(), nullable()))
119+
twigEnvironmentLoader: schema(string(), nullable())
120120
])
121121

122122
services:
@@ -369,8 +369,6 @@ services:
369369
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
370370

371371
-
372-
class: PHPStan\Rules\Symfony\TwigTemplateExistsRule
372+
class: PHPStan\Symfony\TwigEnvironmentResolver
373373
arguments:
374-
twigTemplateDirectories: %symfony.twigTemplateDirectories%
375-
tags:
376-
- phpstan.rules.rule
374+
twigEnvironmentLoader: %symfony.twigEnvironmentLoader%

‎rules.neon

Copy file name to clipboardExpand all lines: rules.neon
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ rules:
55
- PHPStan\Rules\Symfony\InvalidArgumentDefaultValueRule
66
- PHPStan\Rules\Symfony\UndefinedOptionRule
77
- PHPStan\Rules\Symfony\InvalidOptionDefaultValueRule
8+
- PHPStan\Rules\Symfony\TwigTemplateExistsRule
89

‎src/Rules/Symfony/TwigTemplateExistsRule.php

Copy file name to clipboardExpand all lines: src/Rules/Symfony/TwigTemplateExistsRule.php
+10-38Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
namespace PHPStan\Rules\Symfony;
44

5+
use PHPStan\Analyser\Scope;
6+
use PHPStan\Rules\Rule;
7+
use PHPStan\Rules\RuleErrorBuilder;
8+
use PHPStan\Symfony\TwigEnvironmentResolver;
9+
use PHPStan\Type\ObjectType;
510
use PhpParser\Node;
611
use PhpParser\Node\Arg;
712
use PhpParser\Node\Expr\MethodCall;
813
use PhpParser\Node\Expr\Variable;
914
use PhpParser\Node\Identifier;
1015
use PhpParser\Node\Scalar\String_;
11-
use PHPStan\Analyser\Scope;
12-
use PHPStan\Rules\Rule;
13-
use PHPStan\Rules\RuleErrorBuilder;
14-
use PHPStan\Type\ObjectType;
1516
use function count;
1617
use function file_exists;
1718
use function in_array;
@@ -25,13 +26,12 @@
2526
final class TwigTemplateExistsRule implements Rule
2627
{
2728

28-
/** @var array<string, string|null> */
29-
private $twigTemplateDirectories;
29+
/** @var TwigEnvironmentResolver */
30+
private $twigEnvironmentResolver;
3031

31-
/** @param array<string, string|null> $twigTemplateDirectories */
32-
public function __construct(array $twigTemplateDirectories)
32+
public function __construct(TwigEnvironmentResolver $twigEnvironmentResolver)
3333
{
34-
$this->twigTemplateDirectories = $twigTemplateDirectories;
34+
$this->twigEnvironmentResolver = $twigEnvironmentResolver;
3535
}
3636

3737
public function getNodeType(): string
@@ -41,10 +41,6 @@ public function getNodeType(): string
4141

4242
public function processNode(Node $node, Scope $scope): array
4343
{
44-
if (count($this->twigTemplateDirectories) === 0) {
45-
return [];
46-
}
47-
4844
$templateArg = $this->getTwigTemplateArg($node, $scope);
4945

5046
if ($templateArg === null) {
@@ -70,7 +66,7 @@ public function processNode(Node $node, Scope $scope): array
7066
$errors = [];
7167

7268
foreach ($templateNames as $templateName) {
73-
if ($this->twigTemplateExists($templateName)) {
69+
if ($this->twigEnvironmentResolver->templateExists($templateName)) {
7470
continue;
7571
}
7672

@@ -107,28 +103,4 @@ private function getTwigTemplateArg(MethodCall $node, Scope $scope): ?Arg
107103
return null;
108104
}
109105

110-
private function twigTemplateExists(string $templateName): bool
111-
{
112-
if (preg_match('#^@(.+)\/(.+)$#', $templateName, $matches) === 1) {
113-
$templateNamespace = $matches[1];
114-
$templateName = $matches[2];
115-
} else {
116-
$templateNamespace = null;
117-
}
118-
119-
foreach ($this->twigTemplateDirectories as $twigTemplateDirectory => $namespace) {
120-
if ($namespace !== $templateNamespace) {
121-
continue;
122-
}
123-
124-
$templatePath = $twigTemplateDirectory . '/' . $templateName;
125-
126-
if (file_exists($templatePath)) {
127-
return true;
128-
}
129-
}
130-
131-
return false;
132-
}
133-
134106
}
+53Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace PHPStan\Symfony;
4+
5+
use PHPStan\ShouldNotHappenException;
6+
use Twig\Environment;
7+
use Twig\Loader\LoaderInterface;
8+
9+
final class TwigEnvironmentResolver
10+
{
11+
12+
/** @var string|null */
13+
private $twigEnvironmentLoader;
14+
15+
/** @var Environment|null */
16+
private $twigEnvironment;
17+
18+
public function __construct(?string $twigEnvironmentLoader)
19+
{
20+
$this->twigEnvironmentLoader = $twigEnvironmentLoader;
21+
}
22+
23+
private function getTwigEnvironment(): ?Environment
24+
{
25+
if ($this->twigEnvironmentLoader === null) {
26+
return null;
27+
}
28+
29+
if ($this->twigEnvironment !== null) {
30+
return $this->twigEnvironment;
31+
}
32+
33+
if (!file_exists($this->twigEnvironmentLoader)
34+
|| !is_readable($this->twigEnvironmentLoader)
35+
) {
36+
throw new ShouldNotHappenException(sprintf('Cannot load Twig environment. Check the parameters.symfony.twigEnvironmentLoader setting in PHPStan\'s config. The offending value is "%s".', $this->twigEnvironmentLoader));
37+
}
38+
39+
return $this->twigEnvironment = require $this->twigEnvironmentLoader;
40+
}
41+
42+
public function templateExists(string $name): bool
43+
{
44+
$twigEnvironment = $this->getTwigEnvironment();
45+
46+
if ($twigEnvironment === null) {
47+
return true;
48+
}
49+
50+
return $twigEnvironment->getLoader()->exists($name);
51+
}
52+
53+
}

‎tests/Rules/Symfony/ExampleTwigController.php

Copy file name to clipboardExpand all lines: tests/Rules/Symfony/ExampleTwigController.php
-4Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ public function foo(): void
6161
$this->render($name);
6262

6363
$this->render($this->getName());
64-
65-
$this->render('@admin/backend.html.twig');
66-
$this->render('@admin/foo.html.twig');
67-
$this->render('backend.html.twig');
6864
}
6965

7066
private function getName(): string

‎tests/Rules/Symfony/TwigTemplateExistsRuleMoreTemplatesTest.php

Copy file name to clipboardExpand all lines: tests/Rules/Symfony/TwigTemplateExistsRuleMoreTemplatesTest.php
-46Lines changed: 0 additions & 46 deletions
This file was deleted.

‎tests/Rules/Symfony/TwigTemplateExistsRuleNoTemplatesTest.php

Copy file name to clipboardExpand all lines: tests/Rules/Symfony/TwigTemplateExistsRuleNoTemplatesTest.php
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Rules\Symfony;
44

55
use PHPStan\Rules\Rule;
6+
use PHPStan\Symfony\TwigEnvironmentResolver;
67
use PHPStan\Testing\RuleTestCase;
78

89
/**
@@ -13,7 +14,7 @@ final class TwigTemplateExistsRuleNoTemplatesTest extends RuleTestCase
1314

1415
protected function getRule(): Rule
1516
{
16-
return new TwigTemplateExistsRule([]);
17+
return new TwigTemplateExistsRule(new TwigEnvironmentResolver(null));
1718
}
1819

1920
public function testGetArgument(): void

‎tests/Rules/Symfony/TwigTemplateExistsRuleTest.php

Copy file name to clipboardExpand all lines: tests/Rules/Symfony/TwigTemplateExistsRuleTest.php
+2-12Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Rules\Symfony;
44

55
use PHPStan\Rules\Rule;
6+
use PHPStan\Symfony\TwigEnvironmentResolver;
67
use PHPStan\Testing\RuleTestCase;
78

89
/**
@@ -13,10 +14,7 @@ final class TwigTemplateExistsRuleTest extends RuleTestCase
1314

1415
protected function getRule(): Rule
1516
{
16-
return new TwigTemplateExistsRule([
17-
__DIR__ . '/twig/templates' => null,
18-
__DIR__ . '/twig/admin' => 'admin',
19-
]);
17+
return new TwigTemplateExistsRule(new TwigEnvironmentResolver(__DIR__ . '/twig_environment_loader.php'));
2018
}
2119

2220
public function testGetArgument(): void
@@ -86,14 +84,6 @@ public function testGetArgument(): void
8684
'Twig template "baz.html.twig" does not exist.',
8785
61,
8886
],
89-
[
90-
'Twig template "@admin/foo.html.twig" does not exist.',
91-
66,
92-
],
93-
[
94-
'Twig template "backend.html.twig" does not exist.',
95-
67,
96-
],
9787
]
9888
);
9989
}

‎tests/Rules/Symfony/twig/admin/backend.html.twig

Copy file name to clipboardExpand all lines: tests/Rules/Symfony/twig/admin/backend.html.twig
Whitespace-only changes.

‎tests/Rules/Symfony/twig/templates/foo.html.twig

Copy file name to clipboardExpand all lines: tests/Rules/Symfony/twig/templates/foo.html.twig
Whitespace-only changes.

‎tests/Rules/Symfony/twig/user/bar.html.twig

Copy file name to clipboardExpand all lines: tests/Rules/Symfony/twig/user/bar.html.twig
Whitespace-only changes.
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types = 1);
2+
3+
use Twig\Environment;
4+
use Twig\Loader\ArrayLoader;
5+
6+
require_once __DIR__ . '/../../../vendor/autoload.php';
7+
8+
$loader = new ArrayLoader(['foo.html.twig' => 'foo']);
9+
10+
return new Environment($loader);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.