Skip to content

Commit 82dbc63

Browse files
committed
first commit
0 parents  commit 82dbc63

14 files changed

+525
-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/

.php_cs.dist

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
return My\PhpCsFixerConfig::create()
4+
->setFinder(
5+
PhpCsFixer\Finder::create()
6+
->files()
7+
->name('*.php')
8+
->in(__DIR__.'/src')
9+
->in(__DIR__.'/tests')
10+
->exclude('assets')
11+
);

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: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# JS Scanner
2+
3+
Created by Oscar Otero <http://oscarotero.com> <[email protected]> (MIT License)
4+
5+
Javascript code scanner to use with [gettext/gettext](https://github.com/php-gettext/Gettext)
6+
7+
## Installation
8+
9+
```
10+
composer require gettext/js-scanner
11+
```
12+
13+
## Usage example
14+
15+
```php
16+
use Gettext\Scanner\JsScanner;
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+
$jsScanner = new JsScanner(
22+
Translations::create('domain1'),
23+
Translations::create('domain2'),
24+
Translations::create('domain3')
25+
);
26+
27+
//Scan files
28+
foreach (glob('*.js') as $file) {
29+
$jsScanner->scanFile($file);
30+
}
31+
32+
//Save the translations in .po files
33+
$generator = new PoGenerator();
34+
35+
foreach ($jsScanner->getTranslations() as $translations) {
36+
$domain = $translations->getDomain();
37+
$generator->generateFile($translations, "locales/{$domain}.po");
38+
}
39+
```

composer.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "gettext/js-scanner",
3+
"type": "library",
4+
"description": "Javascript scanner for gettext",
5+
"keywords": ["javascript", "gettext", "i18n", "translation", "scanner"],
6+
"homepage": "https://github.com/php-gettext/JS-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/JS-Scanner/issues"
19+
},
20+
"require": {
21+
"php": "^7.2",
22+
"gettext/gettext": "dev-v5-dev",
23+
"nikic/php-parser": "^4.2",
24+
"mck89/peast": "^1.9"
25+
},
26+
"require-dev": {
27+
"phpunit/phpunit": "^8.0",
28+
"squizlabs/php_codesniffer": "^3.0",
29+
"oscarotero/php-cs-fixer-config": "^1.0",
30+
"friendsofphp/php-cs-fixer": "^2.15"
31+
},
32+
"autoload": {
33+
"psr-4": {
34+
"Gettext\\Scanner\\": "src"
35+
}
36+
},
37+
"autoload-dev": {
38+
"psr-4": {
39+
"Gettext\\Tests\\": "tests"
40+
}
41+
},
42+
"scripts": {
43+
"test": [
44+
"phpunit",
45+
"phpcs"
46+
],
47+
"cs-fix": "php-cs-fixer fix"
48+
}
49+
}

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/JsFunctionsScanner.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Gettext\Scanner;
5+
6+
use Peast\Peast;
7+
use Peast\Traverser;
8+
9+
class JsFunctionsScanner implements FunctionsScannerInterface
10+
{
11+
protected $validFunctions;
12+
protected $parser = ['latest', []];
13+
14+
public function __construct(array $validFunctions = null)
15+
{
16+
$this->validFunctions = $validFunctions;
17+
}
18+
19+
public function parser(string $version, array $options): self
20+
{
21+
$this->parser = [$version, $options];
22+
23+
return $this;
24+
}
25+
26+
public function scan(string $code, string $filename = null): array
27+
{
28+
list($version, $options) = $this->parser;
29+
30+
$ast = Peast::$version($code, $options)->parse();
31+
32+
$traverser = new Traverser();
33+
$visitor = new JsNodeVisitor($filename, $this->validFunctions);
34+
$traverser->addFunction($visitor);
35+
$traverser->traverse($ast);
36+
37+
return $visitor->getFunctions();
38+
}
39+
}

src/JsNodeVisitor.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Gettext\Scanner;
5+
6+
use Peast\Syntax\Node\CallExpression;
7+
use Peast\Syntax\Node\Node;
8+
9+
class JsNodeVisitor
10+
{
11+
protected $validFunctions;
12+
protected $filename;
13+
protected $functions = [];
14+
15+
public function __construct(string $filename = null, array $validFunctions = null)
16+
{
17+
$this->filename = $filename;
18+
$this->validFunctions = $validFunctions;
19+
}
20+
21+
public function __invoke(Node $node)
22+
{
23+
if ($node->getType() === 'CallExpression') {
24+
$function = $this->createFunction($node);
25+
26+
if ($function) {
27+
$this->functions[] = $function;
28+
}
29+
}
30+
}
31+
32+
public function getFunctions(): array
33+
{
34+
return $this->functions;
35+
}
36+
37+
protected function createFunction(CallExpression $node): ?ParsedFunction
38+
{
39+
$name = static::getFunctionName($node);
40+
41+
if (empty($name) || ($this->validFunctions !== null && !in_array($name, $this->validFunctions))) {
42+
return null;
43+
}
44+
45+
$position = $node->getLocation();
46+
47+
$function = new ParsedFunction(
48+
$name,
49+
$this->filename,
50+
$position->getStart()->getLine(),
51+
$position->getEnd()->getLine()
52+
);
53+
54+
foreach ($node->getArguments() as $argument) {
55+
switch ($argument->getType()) {
56+
case 'Literal':
57+
$function->addArgument($argument->getValue());
58+
break;
59+
default:
60+
$function->addArgument();
61+
}
62+
}
63+
64+
foreach ($node->getLeadingComments() as $comment) {
65+
$function->addComment($comment->getText());
66+
}
67+
68+
return $function;
69+
}
70+
71+
protected static function getFunctionName(CallExpression $node): ?string
72+
{
73+
$callee = $node->getCallee();
74+
75+
switch ($callee->getType()) {
76+
case 'Identifier':
77+
return $callee->getName();
78+
case 'MemberExpression':
79+
return $callee->getProperty()->getName();
80+
default:
81+
return null;
82+
}
83+
}
84+
}

src/JsScanner.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Gettext\Scanner;
5+
6+
use Gettext\Translations;
7+
8+
/**
9+
* Class to scan PHP files and get gettext translations
10+
*/
11+
class JsScanner extends CodeScanner
12+
{
13+
public function getFunctionsScanner(): FunctionsScannerInterface
14+
{
15+
return new JsFunctionsScanner(array_keys($this->functions));
16+
}
17+
}

0 commit comments

Comments
 (0)