Skip to content

Commit a31f38c

Browse files
noofaqNyholm
authored andcommitted
@translate annotation: allows to add any string to dictionary (#107)
* @translate annotation: allows to add any string to dictionary * applying styleci * php5.x compatibility * weird behavior of ValidatorAnnotation (which affects usage of "@translate" annotation in some use cases) * removal of test files related to ValidatorAnnotation issues
1 parent 6c8b2fe commit a31f38c

File tree

5 files changed

+191
-0
lines changed

5 files changed

+191
-0
lines changed

src/Annotation/Translate.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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\Annotation;
13+
14+
/**
15+
* @Annotation
16+
*/
17+
class Translate
18+
{
19+
/** @var string */
20+
private $domain = 'messages';
21+
22+
/**
23+
* Translate constructor.
24+
*
25+
* @param array $values
26+
*/
27+
public function __construct($values)
28+
{
29+
if (isset($values['domain'])) {
30+
$this->domain = $values['domain'];
31+
}
32+
}
33+
34+
/**
35+
* @return string
36+
*/
37+
public function getDomain()
38+
{
39+
return $this->domain;
40+
}
41+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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;
13+
14+
use Doctrine\Common\Annotations\DocParser;
15+
use PhpParser\Comment;
16+
use PhpParser\Node;
17+
use PhpParser\NodeVisitor;
18+
use Translation\Extractor\Annotation\Translate;
19+
20+
/**
21+
* Class TranslationAnnotationVisitor.
22+
*
23+
* Supports using @Translate annotation for marking string nodes to be added to the dictionary
24+
*/
25+
class TranslateAnnotationVisitor extends BasePHPVisitor implements NodeVisitor
26+
{
27+
/** @var DocParser */
28+
protected $translateDocParser;
29+
30+
/**
31+
* @return DocParser
32+
*/
33+
private function getTranslateDocParser()
34+
{
35+
if (null === $this->translateDocParser) {
36+
$this->translateDocParser = new DocParser();
37+
38+
$this->translateDocParser->setImports([
39+
'translate' => Translate::class,
40+
]);
41+
$this->translateDocParser->setIgnoreNotImportedAnnotations(true);
42+
}
43+
44+
return $this->translateDocParser;
45+
}
46+
47+
public function enterNode(Node $node)
48+
{
49+
// look for strings
50+
if (!$node instanceof Node\Scalar\String_) {
51+
return null;
52+
}
53+
54+
//look for string with comment
55+
$comments = $node->getAttribute('comments', []);
56+
if (!count($comments)) {
57+
return null;
58+
}
59+
60+
foreach ($comments as $comment) {
61+
if (!$comment instanceof Comment\Doc) {
62+
return null;
63+
}
64+
65+
foreach ($this->getTranslateDocParser()->parse($comment->getText()) as $annotation) {
66+
//add phrase to dictionary
67+
$this->addLocation($node->value, $node->getAttribute('startLine'), $node, ['domain' => $annotation->getDomain()]);
68+
69+
break;
70+
}
71+
}
72+
}
73+
74+
public function leaveNode(Node $node)
75+
{
76+
}
77+
78+
public function beforeTraverse(array $nodes)
79+
{
80+
}
81+
82+
public function afterTraverse(array $nodes)
83+
{
84+
}
85+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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\Tests\Functional\Visitor\Php;
13+
14+
use Translation\Extractor\Tests\Resources\Php\TestTranslateAnnotationFile;
15+
use Translation\Extractor\Visitor\Php\TranslateAnnotationVisitor;
16+
17+
final class TranslateAnnotationVisitorTest extends BasePHPVisitorTest
18+
{
19+
public function testExtract()
20+
{
21+
$collection = $this->getSourceLocations(new TranslateAnnotationVisitor(),
22+
TestTranslateAnnotationFile::class);
23+
24+
$this->assertCount(4, $collection);
25+
26+
$this->assertEquals('const_for_translation', $collection->get(0)->getMessage());
27+
$this->assertEquals(['domain' => 'messages'], $collection->get(0)->getContext());
28+
29+
$this->assertEquals('x_to_messages_implicit', $collection->get(1)->getMessage());
30+
$this->assertEquals(['domain' => 'messages'], $collection->get(1)->getContext());
31+
32+
$this->assertEquals('y_to_messages_explicit', $collection->get(2)->getMessage());
33+
$this->assertEquals(['domain' => 'messages'], $collection->get(2)->getContext());
34+
35+
$this->assertEquals('z_to_validators_explicit', $collection->get(3)->getMessage());
36+
$this->assertEquals(['domain' => 'validators'], $collection->get(3)->getContext());
37+
}
38+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
4+
namespace Translation\Extractor\Tests\Resources\Php;
5+
6+
use Translation\Extractor\Annotation\Desc;
7+
8+
class TestTranslateAnnotationFile
9+
{
10+
const SOME_CONST = /** @Translate */'const_for_translation';
11+
12+
protected function test()
13+
{
14+
$a = 'not_commented';
15+
$b = /* some weird comment */'commented';
16+
$c = 'commented_too'; //some other weird comment
17+
$d = /* @Translate */'incorrectly_annotated';
18+
$e = /** @foo */'unknown_annotation';
19+
$f = /** @Desc(text="something) */'desc_annotation';
20+
21+
$x = /** @Translate */'x_to_messages_implicit';
22+
$y = /** @Translate(domain="messages") */'y_to_messages_explicit';
23+
$z = /** @Translate(domain="validators") */'z_to_validators_explicit';
24+
}
25+
}

tests/Smoke/AllExtractorsTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Translation\Extractor\Visitor\Php\Symfony\FormTypeLabelExplicit;
3030
use Translation\Extractor\Visitor\Php\Symfony\FormTypeLabelImplicit;
3131
use Translation\Extractor\Visitor\Php\Symfony\FormTypePlaceholder;
32+
use Translation\Extractor\Visitor\Php\TranslateAnnotationVisitor;
3233
use Translation\Extractor\Visitor\Twig\TwigVisitorFactory;
3334

3435
/**
@@ -153,6 +154,7 @@ private function getPHPFileExtractor()
153154
$file->addVisitor(new FormTypeLabelImplicit());
154155
$file->addVisitor(new FormTypePlaceholder());
155156
$file->addVisitor(new SourceLocationContainerVisitor());
157+
$file->addVisitor(new TranslateAnnotationVisitor());
156158

157159
return $file;
158160
}

0 commit comments

Comments
 (0)