Browse Source

Merge pull request #6882 from cakephp/master-i18n

Provide initialize command to create PO from POT.
Mark Story 10 years ago
parent
commit
256b0ccd96
2 changed files with 165 additions and 1 deletions
  1. 72 1
      src/Shell/I18nShell.php
  2. 93 0
      tests/TestCase/Shell/I18nShellTest.php

+ 72 - 1
src/Shell/I18nShell.php

@@ -42,14 +42,18 @@ class I18nShell extends Shell
         $this->out('<info>I18n Shell</info>');
         $this->hr();
         $this->out('[E]xtract POT file from sources');
+        $this->out('[I]inialize a language from POT file');
         $this->out('[H]elp');
         $this->out('[Q]uit');
 
-        $choice = strtolower($this->in('What would you like to do?', ['E', 'H', 'Q']));
+        $choice = strtolower($this->in('What would you like to do?', ['E', 'I', 'H', 'Q']));
         switch ($choice) {
             case 'e':
                 $this->Extract->main();
                 break;
+            case 'i':
+                $this->init();
+                break;
             case 'h':
                 $this->out($this->OptionParser->help());
                 break;
@@ -64,6 +68,51 @@ class I18nShell extends Shell
     }
 
     /**
+     * Inits PO file from POT file.
+     *
+     * @param string|null $language Language code to use.
+     * @return void|int
+     */
+    public function init($language = null)
+    {
+        if (!$language) {
+            $language = strtolower($this->in('Please specify language code, e.g. `en`, `eng`, `en_US` etc.'));
+        }
+        if (strlen($language) < 2) {
+            return $this->error('Invalid language code. Valid is `en`, `eng`, `en_US` etc.');
+        }
+
+        $this->_paths = [APP];
+        if ($this->param('plugin')) {
+            $plugin = Inflector::camelize($this->param('plugin'));
+            $this->_paths = [Plugin::classPath($plugin)];
+        }
+
+        $response = $this->in('What folder?', null, rtrim($this->_paths[0], DS) . DS . 'Locale');
+        $sourceFolder = rtrim($response, DS) . DS;
+        $targetFolder = $sourceFolder . $language . DS;
+        if (!is_dir($targetFolder)) {
+            mkdir($targetFolder, 0770, true);
+        }
+
+        $count = 0;
+        $iterator = new \DirectoryIterator($sourceFolder);
+        foreach ($iterator as $fileinfo) {
+            if (!$fileinfo->isFile()) {
+                continue;
+            }
+            $filename = $fileinfo->getFilename();
+            $newFilename = $fileinfo->getBasename('.pot');
+            $newFilename = $newFilename . '.po';
+
+            $this->createFile($targetFolder . $newFilename, file_get_contents($sourceFolder . $filename));
+            $count++;
+        }
+
+        $this->out('Generated ' . $count . ' PO files in ' . $targetFolder);
+    }
+
+    /**
      * Gets the option parser instance and configures it.
      *
      * @return \Cake\Console\ConsoleOptionParser
@@ -71,12 +120,34 @@ class I18nShell extends Shell
     public function getOptionParser()
     {
         $parser = parent::getOptionParser();
+        $initParser = [
+            'options' => [
+                'plugin' => [
+                    'help' => 'Plugin name.',
+                    'short' => 'p'
+                ],
+                'force' => [
+                    'help' => 'Force overwriting.',
+                    'short' => 'f',
+                    'boolean' => true
+                ]
+            ],
+            'arguments' => [
+                'language' => [
+                    'help' => 'Two-letter language code.'
+                ]
+            ]
+        ];
 
         $parser->description(
             'I18n Shell generates .pot files(s) with translations.'
         )->addSubcommand('extract', [
             'help' => 'Extract the po translations from your application',
             'parser' => $this->Extract->getOptionParser()
+        ])
+        ->addSubcommand('init', [
+            'help' => 'Init PO language file from POT file',
+            'parser' => $initParser
         ]);
 
         return $parser;

+ 93 - 0
tests/TestCase/Shell/I18nShellTest.php

@@ -0,0 +1,93 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.8
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\TestCase\Shell;
+
+use Cake\Cache\Cache;
+use Cake\Datasource\ConnectionManager;
+use Cake\Shell\I18nShell;
+use Cake\TestSuite\TestCase;
+
+/**
+ * I18nShell test.
+ */
+class I18nShellTest extends TestCase
+{
+
+    /**
+     * setup method
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        parent::setUp();
+        $this->io = $this->getMock('Cake\Console\ConsoleIo');
+        $this->shell = new I18nShell($this->io);
+
+        $this->localeDir = TMP . 'Locale' . DS;
+    }
+
+    /**
+     * Teardown
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        parent::tearDown();
+
+        $deDir = $this->localeDir . 'de' . DS;
+
+        unlink($this->localeDir . 'default.pot');
+        unlink($this->localeDir . 'cake.pot');
+
+        unlink($deDir . 'default.po');
+        unlink($deDir . 'cake.po');
+    }
+
+    /**
+     * Tests that init() creates the PO files from POT files.
+     *
+     * @return void
+     */
+    public function testInit()
+    {
+        $deDir = $this->localeDir . 'de' . DS;
+        if (!is_dir($deDir)) {
+            mkdir($deDir, 0770, true);
+        }
+        file_put_contents($this->localeDir . 'default.pot', 'Testing POT file.');
+        file_put_contents($this->localeDir . 'cake.pot', 'Testing POT file.');
+        if (file_exists($deDir . 'default.po')) {
+            unlink($deDir . 'default.po');
+        }
+        if (file_exists($deDir . 'default.po')) {
+            unlink($deDir . 'cake.po');
+        }
+
+        $this->shell->io()->expects($this->at(0))
+            ->method('ask')
+            ->will($this->returnValue('de'));
+        $this->shell->io()->expects($this->at(1))
+            ->method('ask')
+            ->will($this->returnValue($this->localeDir));
+
+        $this->shell->params['verbose'] = true;
+        $this->shell->init();
+
+        $this->assertFileExists($deDir . 'default.po');
+        $this->assertFileExists($deDir . 'cake.po');
+    }
+}