Skip to content

Commit

Permalink
#97 Working generate pot command
Browse files Browse the repository at this point in the history
  • Loading branch information
amostajo committed Feb 5, 2023
1 parent 5f17e74 commit 1b7ab48
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 138 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"require": {
"php": ">=5.4.0",
"10quality/ayuco": "^1.0",
"nikic/php-parser": "^4.2"
"nikic/php-parser": "^4.2",
"10quality/gettext-wp-scanner": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "9.*"
Expand Down
44 changes: 44 additions & 0 deletions src/Base/BaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,48 @@ public function getMainClassPath()
{
return $this->rootPath.'/app/Main.php';
}
/**
* Returns the value of an argument (by index).
* @since 1.1.17
*
* @param array $args
* @param int $index
* @param mixed $default
*/
protected function getArgsValue($args, $index, $default = null)
{
return !isset($args[$index]) || empty($args[$index]) ? $default : $args[$index];
}
/**
* Returns path to /app folder.
* @since 1.1.17
*
* @return string
*/
public function getAppPath()
{
return $this->rootPath.'/app/';
}
/**
* Returns path to /app folder.
* @since 1.1.17
*
* @return string
*/
public function getViewsPath()
{
return str_replace('app\Config/../../', '',
str_replace('app/Config/../../', '', $this->config['paths']['views'])
);
}
/**
* Returns path to /app folder.
* @since 1.1.17
*
* @return string
*/
public function getAssetsPath()
{
return $this->rootPath.'/assets/';
}
}
12 changes: 4 additions & 8 deletions src/GenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @copyright 10Quality <http://www.10quality.com>
* @license MIT
* @package WPMVC\Commands
* @version 1.1.2
* @version 1.1.17
*/
class GenerateCommand extends Command
{
Expand All @@ -32,7 +32,7 @@ class GenerateCommand extends Command
* @since 1.0.0
* @var string
*/
protected $description = 'Generates files, like the language Pot file [in-progress, has bugs].';
protected $description = 'Generates POT, PO and MO files.';

/**
* Calls to command action.
Expand All @@ -43,15 +43,11 @@ class GenerateCommand extends Command
public function call($args = [])
{
if (count($args) == 0 || empty($args[2]))
throw new NoticeException('Command "'.$this->key.'": Expecting a file to generate (pot).');

throw new NoticeException('Command "'.$this->key.'": Expecting something to generate (pot).');
$object = explode(':', $args[2]);

switch ($object[0]) {
case 'pot':
$textdomain = !isset($args[3]) || empty($args[3]) ? null : $args[3];
$lang = !isset($args[4]) || empty($args[4]) ? 'en' : $args[4];
$this->generatePot($textdomain, $lang);
$this->generatePot($this->getArgsValue($args, 3, 'en'));
break;
}
}
Expand Down
167 changes: 53 additions & 114 deletions src/Traits/GeneratePotTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
namespace WPMVC\Commands\Traits;

use Exception;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Ayuco\Exceptions\NoticeException;
use Gettext\Translations;
use Gettext\Generator\PoGenerator;
use TenQuality\Gettext\Scanner\WPJsScanner;
use TenQuality\Gettext\Scanner\WPPhpScanner;

/**
* Generates POT file.
Expand All @@ -14,59 +16,69 @@
* @copyright 10Quality <http://www.10quality.com>
* @license MIT
* @package WPMVC\Commands
* @version 1.1.8
* @version 1.1.17
*/
trait GeneratePotTrait
{
/**
* Generate pot file.
* @since 1.1.0
*
* @param string $textdomain Domain name.
* @param string $lang Pot default language.
* @param string $lang Pot default language.
*/
protected function generatePot($textdomain = null, $lang = 'en')
protected function generatePot($lang = 'en')
{
try {
// Search project
if (empty($textdomain))
$textdomain = $this->config['localize']['textdomain'];
$pot = $this->getPotHeader($lang, $textdomain);
$lang_regex = '/_[_enx]\([|\s][\\\'\"][\s\S]+?(?=[\\\'|\"]'.$textdomain.'[\\\'|\"])/';
$string_regex = '/[\\\'|\"]([^\\\'|\"]+)[\\\'|\"]/';
// App folder
$dir = new RecursiveDirectoryIterator($this->config['paths']['base'], RecursiveDirectoryIterator::SKIP_DOTS);
foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST) as $filename => $item) {
if($item->isDir())
continue;
$content = file_get_contents($filename);
preg_match_all($lang_regex, $content, $matches );
if (empty($matches))
continue;
foreach ($matches[0] as $match) {
$this->evalPotMatch($pot, $match, $string_regex);
}
$domain = $this->config['localize']['textdomain'];
$translations = Translations::create($domain, $lang);
// Prepare headers
$translations->getHeaders()->set('Project-Id-Version', $this->config['namespace']);
$translations->getHeaders()->set('POT-Creation-Date', date('Y-m-d H:i:s'));
$translations->getHeaders()->set('MIME-Version', $this->config['version']);
$translations->getHeaders()->set('Content-Type', 'text/plain; charset=UTF-8');
$translations->getHeaders()->set('Last-Translator', $this->config['author']);
$translations->getHeaders()->set('X-Generator', 'WordPress MVC Commands 1.1');
// Php files
$scanner = new WPPhpScanner(
Translations::create($domain)
);
foreach (glob($this->rootPath.'*.php') as $file) {
$scanner->scanFile($file);
}
// Views folder
$dir = new RecursiveDirectoryIterator($this->config['paths']['views'], RecursiveDirectoryIterator::SKIP_DOTS);
foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST) as $filename => $item) {
if($item->isDir())
continue;
$content = file_get_contents($filename);
preg_match_all($lang_regex, $content, $matches );
if (empty($matches))
continue;
foreach ($matches[0] as $match) {
$this->evalPotMatch($pot, $match, $string_regex);
}
foreach (glob($this->getAppPath().'*.php') as $file) {
$scanner->scanFile($file);
}
// Write pot file
$filename = $this->config['localize']['path'].$textdomain.'.pot';
foreach (glob($this->getAppPath().'**/*.php') as $file) {
$scanner->scanFile($file);
}
foreach (glob($this->getViewsPath().'*.php') as $file) {
$scanner->scanFile($file);
}
foreach (glob($this->getViewsPath().'**/*.php') as $file) {
$scanner->scanFile($file);
}
$scannedTranslations = $scanner->getTranslations();
if (array_key_exists($domain, $scannedTranslations))
$translations = $translations->mergeWith($scannedTranslations[$domain]);
// Js files
$scanner = new WPJsScanner(
Translations::create($domain)
);
foreach (glob($this->getAssetsPath().'js/*.js') as $file) {
$scanner->scanFile($file);
}
foreach (glob($this->getAssetsPath().'js/**/*.js') as $file) {
$scanner->scanFile($file);
}
$scannedTranslations = $scanner->getTranslations();
if (array_key_exists($domain, $scannedTranslations))
$translations = $translations->mergeWith($scannedTranslations[$domain]);
// Prepare
if (!is_dir($this->config['localize']['path']))
mkdir($this->config['localize']['path'], 0777, true);
if (file_exists($filename))
unlink($filename);
file_put_contents($filename,implode("\n", $pot));
// Write pot file
$generator = new PoGenerator();
$generator->generateFile($translations, $this->config['localize']['path'].$domain.'.pot');
// Print end
$this->_print('POT file generated!');
$this->_lineBreak();
Expand All @@ -75,77 +87,4 @@ protected function generatePot($textdomain = null, $lang = 'en')
throw new NoticeException('Command "'.$this->key.'": Fatal error ocurred.');
}
}
/**
* Returns POT basic header.
* @since 1.1.0
*
* @param string $lang Pot default language.
* @param string $textdomain
*
* @return array
*/
private function getPotHeader($lang, $textdomain)
{
return [
'# Copyright (C) '.date('Y').' 10 Quality <info@10quality.com>',
'msgid ""',
'msgstr ""',
'"Project-Id-Version: '.$textdomain.'\n"',
'"POT-Creation-Date: '.date('Y-m-d H:i:s').'\n"',
'"PO-Creation-Date: '.date('Y-m-d H:i:s').'\n"',
'"MIME-Version: 1.0\n"',
'"Content-Type: text/plain; charset=UTF-8\n"',
'"Content-Transfer-Encoding: 8bit\n"',
'"X-Generator: WordPress MVC Commands 1.1.0\n"',
'"Language: '.$lang.'\n"',
];
}
/**
* Appends a new text translation line to a po file.
* @since 1.1.0
*
* @param array &$po Po or Pot file.
* @param string $text Text to append.
* @param string $translation Text translation append.
*/
private function appendPotText(&$po, $text, $translation = '')
{
if (!in_array($text, $po)) {
$po[] = '';
$po[] = 'msgid "'.$text.'"';
$po[] = 'msgstr "'.$translation.'"';
}
}
/**
* Evaluates match and appends string to Po/Pot file.
* @since 1.1.0
*
* @param array &$po Po or Pot file.
* @param string $match String match.
* @param string $string_regex String regex rule.
*/
private function evalPotMatch(&$po, &$match, &$string_regex)
{
if (strpos($match, '_n') !== false) {
preg_match_all($string_regex, $match, $strings );
for ($i = 0; $i < count($strings[1]); $i++) {
$this->appendPotText($po, $this->parsePotString($strings[1][$i]));
}
} else {
preg_match($string_regex, $match, $strings );
$this->appendPotText($po, $this->parsePotString($strings[1]));
}
}
/**
* Returns parsed pot string.
* @since 1.1.0
*
* @param string $string
*
* @return string
*/
private function parsePotString($string)
{
return str_replace('"', '\"', $string);
}
}
16 changes: 1 addition & 15 deletions tests/cases/GeneratePotTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function setUp(): void
* Test resulting message.
* @group pot
*/
public function testResultMessage()
public function testGeneration()
{
// Prepare
$filename = FRAMEWORK_PATH.'/environment/assets/lang/my-app.pot';
Expand All @@ -52,18 +52,4 @@ public function testResultMessage()
$this->assertEquals('POT file generated!', $execution);
$this->assertFileExists($filename);
}
/**
* Test resulting message.
* @group pot
*/
public function testMultidomainGeneration()
{
// Prepare
$filename = FRAMEWORK_PATH.'/environment/assets/lang/other-domain.pot';
// Execure
$execution = exec('php '.WPMVC_AYUCO.' generate pot other-domain');
// Assert
$this->assertEquals('POT file generated!', $execution);
$this->assertFileExists($filename);
}
}

0 comments on commit 1b7ab48

Please sign in to comment.