Skip to content

Commit 5a69701

Browse files
committed
first commit
0 parents  commit 5a69701

15 files changed

+729
-0
lines changed

.gitattributes

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/tests/ export-ignore
2+
/phpunit.xml export-ignore
3+
.* export-ignore
4+
phpcs.xml export-ignore
5+
6+
# Set the line ending configuration
7+
* text=lf

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
vendor
2+
composer.lock
3+
*.cache
4+
5+
# Eclipse-specific files
6+
/.settings/
7+
/.buildpath
8+
/.project
9+
10+
# PhpStorm-specific files
11+
/.idea/

CONTRIBUTING.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Contributing to Gettext
2+
=======================
3+
4+
Looking to contribute something to this library? Here's how you can help.
5+
6+
## Bugs
7+
8+
A bug is a demonstrable problem that is caused by the code in the repository. Good bug reports are extremely helpful – thank you!
9+
10+
Please try to be as detailed as possible in your report. Include specific information about the environment – version of PHP, version of gettext, etc, and steps required to reproduce the issue.
11+
12+
## Pull Requests
13+
14+
Good pull requests – patches, improvements, new features – are a fantastic help. New extractors or generator are welcome. Before create a pull request, please follow these instructions:
15+
16+
* The code must be PSR-2 compliant
17+
* Write some tests

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2019 Oscar Otero Marzoa
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# PHP Scanner
2+
3+
Created by Oscar Otero <http://oscarotero.com> <[email protected]> (MIT License)
4+
5+
PHP code scanner to use with [gettext/gettext](https://github.com/php-gettext/Gettext)
6+
7+
## Installation
8+
9+
```
10+
composer require gettext/php-scanner
11+
```
12+
13+
## Usage example
14+
15+
```php
16+
use Gettext\Scanner\PhpScanner;
17+
use Gettext\Generator\PoGenerator;
18+
use Gettext\Translations;
19+
20+
//Create a new scanner, adding a translation for each domain we want to get:
21+
$phpScanner = new PhpScanner(
22+
Translations::create('domain1'),
23+
Translations::create('domain2'),
24+
Translations::create('domain3')
25+
);
26+
27+
//Scan files
28+
foreach (glob('*.php') as $file) {
29+
$phpScanner->scanFile($file);
30+
}
31+
32+
//Save the translations in .po files
33+
$generator = new PoGenerator();
34+
35+
foreach ($phpScanner->getTranslations() as $translations) {
36+
$domain = $translations->getDomain();
37+
$generator->generateFile($translations, "locales/{$domain}.po");
38+
}
39+
```
40+
41+
## Contributors
42+
43+
Thanks to all [contributors](https://github.com/oscarotero/Gettext/graphs/contributors) specially to [@mlocati](https://github.com/mlocati).

composer.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"name": "gettext/php-scanner",
3+
"type": "library",
4+
"description": "PHP scanner for gettext",
5+
"keywords": ["php", "gettext", "i18n", "translation", "scanner"],
6+
"homepage": "https://github.com/php-gettext/PHP-Scanner",
7+
"license": "MIT",
8+
"authors": [
9+
{
10+
"name": "Oscar Otero",
11+
"email": "[email protected]",
12+
"homepage": "http://oscarotero.com",
13+
"role": "Developer"
14+
}
15+
],
16+
"support": {
17+
"email": "[email protected]",
18+
"issues": "https://github.com/php-gettext/PHP-Scanner/issues"
19+
},
20+
"require": {
21+
"php": "^7.2",
22+
"gettext/gettext": "dev-v5-dev",
23+
"nikic/php-parser": "^4.2"
24+
},
25+
"require-dev": {
26+
"phpunit/phpunit": "^8.0",
27+
"squizlabs/php_codesniffer": "^3.0"
28+
},
29+
"autoload": {
30+
"psr-4": {
31+
"Gettext\\Scanner\\": "src"
32+
}
33+
},
34+
"autoload-dev": {
35+
"psr-4": {
36+
"Gettext\\Tests\\": "tests"
37+
}
38+
},
39+
"scripts": {
40+
"test": [
41+
"phpunit",
42+
"phpcs"
43+
],
44+
"codefix": "phpcbf"
45+
}
46+
}

phpcs.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0"?>
2+
<ruleset name="Gettext coding standard">
3+
<description>Gettext coding standard</description>
4+
5+
<!-- display progress -->
6+
<arg value="p"/>
7+
<arg name="colors"/>
8+
9+
<!-- coding standard -->
10+
<rule ref="PSR2"/>
11+
12+
<!-- Paths to check -->
13+
<file>src</file>
14+
</ruleset>

phpunit.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<phpunit bootstrap="./vendor/autoload.php">
2+
<testsuites>
3+
<testsuite name="All tests">
4+
<directory>./tests/</directory>
5+
</testsuite>
6+
</testsuites>
7+
<filter>
8+
<whitelist processUncoveredFilesFromWhitelist="true">
9+
<directory suffix=".php">src</directory>
10+
</whitelist>
11+
</filter>
12+
</phpunit>

src/PhpFunctionsScanner.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Gettext\Scanner;
5+
6+
use PhpParser\Parser;
7+
use PhpParser\ParserFactory;
8+
use PhpParser\NodeTraverser;
9+
use PhpParser\NodeDumper;
10+
11+
class PhpFunctionsScanner implements FunctionsScannerInterface
12+
{
13+
protected $parser;
14+
protected $validFunctions;
15+
16+
public function __construct(array $validFunctions = null, Parser $parser = null)
17+
{
18+
$this->validFunctions = $validFunctions;
19+
$this->parser = $parser ?: (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
20+
}
21+
22+
public function scan(string $code, string $filename = null): array
23+
{
24+
$ast = $this->parser->parse($code);
25+
26+
$traverser = new NodeTraverser();
27+
$visitor = new PhpNodeVisitor($filename, $this->validFunctions);
28+
$traverser->addVisitor($visitor);
29+
$traverser->traverse($ast);
30+
31+
return $visitor->getFunctions();
32+
}
33+
}

src/PhpNodeVisitor.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Gettext\Scanner;
5+
6+
use PhpParser\NodeVisitor;
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\FuncCall;
9+
use PhpParser\Node\Stmt\Nop;
10+
use PhpParser\Comment;
11+
12+
class PhpNodeVisitor implements NodeVisitor
13+
{
14+
protected $validFunctions;
15+
protected $filename;
16+
protected $functions = [];
17+
18+
public function __construct(string $filename = null, array $validFunctions = null)
19+
{
20+
$this->filename = $filename;
21+
$this->validFunctions = $validFunctions;
22+
}
23+
24+
public function beforeTraverse(array $nodes)
25+
{
26+
return null;
27+
}
28+
29+
public function enterNode(Node $node)
30+
{
31+
if ($node instanceof FuncCall) {
32+
$name = $node->name->getLast();
33+
34+
if ($this->validFunctions === null || in_array($name, $this->validFunctions)) {
35+
$this->functions[] = $this->createFunction($node);
36+
}
37+
38+
return null;
39+
}
40+
41+
return null;
42+
}
43+
44+
public function leaveNode(Node $node)
45+
{
46+
return null;
47+
}
48+
49+
public function afterTraverse(array $nodes)
50+
{
51+
return null;
52+
}
53+
54+
public function getFunctions(): array
55+
{
56+
return $this->functions;
57+
}
58+
59+
protected function createFunction(FuncCall $node): ParsedFunction
60+
{
61+
$arguments = [];
62+
$function = new ParsedFunction(
63+
$node->name->getLast(),
64+
$this->filename,
65+
$node->getStartLine(),
66+
$node->getEndLine()
67+
);
68+
69+
foreach($node->getComments() as $comment) {
70+
$function->addComment(static::getComment($comment));
71+
}
72+
73+
foreach ($node->args as $argument) {
74+
$value = $argument->value;
75+
76+
foreach ($argument->getComments() as $comment) {
77+
$function->addComment(static::getComment($comment));
78+
}
79+
80+
switch ($value->getType()) {
81+
case 'Scalar_String':
82+
case 'Scalar_LNumber':
83+
case 'Scalar_DNumber':
84+
$function->addArgument($value->value);
85+
break;
86+
87+
default:
88+
$function->addArgument();
89+
}
90+
}
91+
92+
return $function;
93+
}
94+
95+
protected static function getComment(Comment $comment): string
96+
{
97+
$text = $comment->getReformattedText();
98+
99+
$lines = array_map(function ($line) {
100+
$line = ltrim($line, "#*/ \t");
101+
$line = rtrim($line, "#*/ \t");
102+
return trim($line);
103+
}, explode("\n", $text));
104+
105+
return trim(implode("\n", $lines));
106+
}
107+
}

0 commit comments

Comments
 (0)