Skip to content

Commit 1d8f7ac

Browse files
committed
added Knp extractors
1 parent 8009cb4 commit 1d8f7ac

File tree

3 files changed

+252
-0
lines changed

3 files changed

+252
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Extractor\Visitor\Php\Knp\Menu;
13+
14+
use PhpParser\Node;
15+
use PhpParser\NodeVisitor;
16+
use Translation\Extractor\Model\SourceLocation;
17+
use Translation\Extractor\Visitor\Php\BasePHPVisitor;
18+
19+
/**
20+
* This class extracts knp menu item link titles:
21+
* - $menu['foo']->setLinkAttribute('title', 'my.title')
22+
*/
23+
abstract class AbstractKnpMenuVisitor extends BasePHPVisitor implements NodeVisitor
24+
{
25+
/**
26+
* @var bool
27+
*/
28+
private $isKnpMenuBuildingMethod = false;
29+
30+
/**
31+
* @var string|bool
32+
*/
33+
private $domain;
34+
35+
/**
36+
* @var SourceLocation[]
37+
*/
38+
private $sourceLocations = [];
39+
40+
public function beforeTraverse(array $nodes): ?Node
41+
{
42+
$this->sourceLocations = [];
43+
44+
return null;
45+
}
46+
47+
public function enterNode(Node $node): ?Node
48+
{
49+
if (!$this->isKnpMenuBuildingMethod($node)) {
50+
return null;
51+
}
52+
53+
if (!$node instanceof Node\Expr\MethodCall) {
54+
return null;
55+
}
56+
57+
if (!\is_string($node->name) && !$node->name instanceof Node\Identifier) {
58+
return null;
59+
}
60+
61+
$methodName = (string) $node->name;
62+
if ('setExtra' !== $methodName) {
63+
return null;
64+
}
65+
66+
$extraKey = $this->getStringArgument($node, 0);
67+
if ('translation_domain' === $extraKey) {
68+
if (
69+
$node->args[1]->value instanceof Node\Expr\ConstFetch
70+
&& 'false' === $node->args[1]->value->name->toString()
71+
) {
72+
// translation disabled
73+
$this->domain = false;
74+
} else {
75+
$extraValue = $this->getStringArgument($node, 1);
76+
if (null !== $extraValue) {
77+
$this->domain = $extraValue;
78+
}
79+
}
80+
}
81+
82+
return null;
83+
}
84+
85+
/**
86+
* Checks if the given node is a class method returning a knp menu.
87+
*/
88+
protected function isKnpMenuBuildingMethod(Node $node): bool
89+
{
90+
if ($node instanceof Node\Stmt\ClassMethod) {
91+
if (null === $node->returnType) {
92+
$this->isKnpMenuBuildingMethod = false;
93+
}
94+
if ($node->returnType instanceof Node\Identifier) {
95+
$this->isKnpMenuBuildingMethod = false;
96+
}
97+
98+
$returnType = $node->returnType;
99+
if ($returnType instanceof Node\NullableType) {
100+
$returnType = $returnType->type;
101+
}
102+
103+
if (!$returnType instanceof Node\Name) {
104+
$this->isKnpMenuBuildingMethod = false;
105+
} else {
106+
$this->isKnpMenuBuildingMethod = 'ItemInterface' === $returnType->toCodeString();
107+
}
108+
}
109+
110+
return $this->isKnpMenuBuildingMethod;
111+
}
112+
113+
protected function lateCollect(SourceLocation $location): void
114+
{
115+
$this->sourceLocations[] = $location;
116+
}
117+
118+
public function leaveNode(Node $node): ?Node
119+
{
120+
return null;
121+
}
122+
123+
public function afterTraverse(array $nodes): ?Node
124+
{
125+
if (false === $this->domain) {
126+
// translation disabled
127+
return null;
128+
}
129+
130+
/** @var SourceLocation $location */
131+
foreach ($this->sourceLocations as $location) {
132+
if (null !== $this->domain) {
133+
$context = $location->getContext();
134+
$context['domain'] = $this->domain;
135+
$location = new SourceLocation($location->getMessage(), $location->getPath(), $location->getLine(), $context);
136+
}
137+
$this->collection->addLocation($location);
138+
}
139+
$this->sourceLocations = [];
140+
141+
return null;
142+
}
143+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Extractor\Visitor\Php\Knp\Menu;
13+
14+
use PhpParser\Node;
15+
use PhpParser\NodeVisitor;
16+
17+
/**
18+
* This class extracts knp menu item labels:
19+
* - $menu->addChild('foo')
20+
* - $menu['foo']->setLabel('bar')
21+
*/
22+
final class ItemLabel extends AbstractKnpMenuVisitor implements NodeVisitor
23+
{
24+
public function enterNode(Node $node): ?Node
25+
{
26+
if (!$this->isKnpMenuBuildingMethod($node)) {
27+
return null;
28+
}
29+
30+
parent::enterNode($node);
31+
32+
if (!$node instanceof Node\Expr\MethodCall) {
33+
return null;
34+
}
35+
36+
if (!\is_string($node->name) && !$node->name instanceof Node\Identifier) {
37+
return null;
38+
}
39+
40+
$methodName = (string) $node->name;
41+
if (!\in_array($methodName, ['addChild', 'setLabel'], true)) {
42+
return null;
43+
}
44+
45+
if (null !== $label = $this->getStringArgument($node, 0)) {
46+
$line = $node->getAttribute('startLine');
47+
if (null !== $location = $this->getLocation($label, $line, $node)) {
48+
$this->lateCollect($location);
49+
}
50+
}
51+
52+
return null;
53+
}
54+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Extractor\Visitor\Php\Knp\Menu;
13+
14+
use PhpParser\Node;
15+
use PhpParser\NodeVisitor;
16+
17+
/**
18+
* This class extracts knp menu item link titles:
19+
* - $menu['foo']->setLinkAttribute('title', 'my.title')
20+
*/
21+
final class LinkTitle extends AbstractKnpMenuVisitor implements NodeVisitor
22+
{
23+
public function enterNode(Node $node): ?Node
24+
{
25+
if (!$this->isKnpMenuBuildingMethod($node)) {
26+
return null;
27+
}
28+
29+
parent::enterNode($node);
30+
31+
if (!$node instanceof Node\Expr\MethodCall) {
32+
return null;
33+
}
34+
35+
if (!\is_string($node->name) && !$node->name instanceof Node\Identifier) {
36+
return null;
37+
}
38+
39+
$methodName = (string) $node->name;
40+
if ('setLinkAttribute' !== $methodName) {
41+
return null;
42+
}
43+
44+
$attributeKey = $this->getStringArgument($node, 0);
45+
$attributeValue = $this->getStringArgument($node, 1);
46+
if ('title' === $attributeKey && null !== $attributeValue) {
47+
$line = $node->getAttribute('startLine');
48+
if (null !== $location = $this->getLocation($attributeValue, $line, $node)) {
49+
$this->lateCollect($location);
50+
}
51+
}
52+
53+
return null;
54+
}
55+
}

0 commit comments

Comments
 (0)