From cc1a1dc49ece8416590f08c3b2bb036c5fb830ed Mon Sep 17 00:00:00 2001 From: Hidehito Nozawa Date: Sun, 17 May 2015 00:24:06 +0900 Subject: [PATCH] Add code. Signed-off-by: Hidehito Nozawa --- .bashrc | 11 +++ .gitignore | 6 ++ Vagrantfile | 25 +++++ composer.json | 26 +++++ phpunit-bootstrap.php | 3 + phpunit.xml.dist | 37 +++++++ src/ShouldBee/Translation/Negotiation.php | 97 +++++++++++++++++++ src/ShouldBee/Translation/Translator.php | 79 +++++++++++++++ .../ShouldBee/Translation/NegotiationTest.php | 30 ++++++ .../ShouldBee/Translation/TranslatorTest.php | 47 +++++++++ .../Translation/catalogue-default.json | 5 + tests/ShouldBee/Translation/catalogue-en.json | 6 ++ tests/ShouldBee/Translation/catalogue-ja.json | 6 ++ 13 files changed, 378 insertions(+) create mode 100644 .bashrc create mode 100644 .gitignore create mode 100644 Vagrantfile create mode 100644 composer.json create mode 100644 phpunit-bootstrap.php create mode 100644 phpunit.xml.dist create mode 100644 src/ShouldBee/Translation/Negotiation.php create mode 100644 src/ShouldBee/Translation/Translator.php create mode 100644 tests/ShouldBee/Translation/NegotiationTest.php create mode 100644 tests/ShouldBee/Translation/TranslatorTest.php create mode 100644 tests/ShouldBee/Translation/catalogue-default.json create mode 100644 tests/ShouldBee/Translation/catalogue-en.json create mode 100644 tests/ShouldBee/Translation/catalogue-ja.json diff --git a/.bashrc b/.bashrc new file mode 100644 index 0000000..882dffb --- /dev/null +++ b/.bashrc @@ -0,0 +1,11 @@ +PROJECT=translation +PS1="\`if [ \$? = 0 ]; then echo \[\e[32m\]${PROJECT}\[\e[0m\]; else echo \[\e[31m\]${PROJECT}\[\e[0m\]; fi\`:\w$ " +cd /vagrant + +function php { + sudo docker run -it --rm --net host -v $(pwd):/wd -w /wd shouldbee/php /sbin/my_init --quiet --skip-startup-files --skip-runit -- php "$@" +} + +function composer { + sudo docker run -it --rm --net host -v $(pwd):/app composer/composer "$@" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ad9b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.phpmake +/vendor +/composer.phar +/composer.lock +/metrics +/.vagrant diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..f5f7314 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,25 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "shouldbee/ubuntu-14.04-with-docker" + config.vm.box_version = "0.5" + + host = RbConfig::CONFIG['host_os'] + + case host + when /darwin/ # mac + cpus = `sysctl -n hw.ncpu`.to_i + when /linux/ + cpus = `nproc`.to_i + else + cpus = 2 + end + + config.vm.provider "vmware_fusion" do |v| + v.vmx["memsize"] = "512" + v.vmx["numvcpus"] = cpus + end +end diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9aee436 --- /dev/null +++ b/composer.json @@ -0,0 +1,26 @@ +{ + "name": "shouldbee/translation", + "description": "Simple translation library", + "keywords": ["translation"], + "homepage": "https://github.com/shouldbee/php-translation", + "license": "MIT", + "authors": [ + { + "name": "Hidehito Nozawa", + "email": "suinyeze@gmail.com", + "homepage": "https://www.facebook.com/suinyeze", + "role": "Developer" + } + ], + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "autoload": { + "psr-0": { + "ShouldBee\\Translation": "src/" + } + } +} diff --git a/phpunit-bootstrap.php b/phpunit-bootstrap.php new file mode 100644 index 0000000..111bde4 --- /dev/null +++ b/phpunit-bootstrap.php @@ -0,0 +1,3 @@ + + + + + tests/*/* + + + + + + + + + + + src + + + + src + tests/*/* + + + + diff --git a/src/ShouldBee/Translation/Negotiation.php b/src/ShouldBee/Translation/Negotiation.php new file mode 100644 index 0000000..fa77d3a --- /dev/null +++ b/src/ShouldBee/Translation/Negotiation.php @@ -0,0 +1,97 @@ +defaultCatalogue = $defaultCatalogue; + } + + /** + * @param string $language + * @param string[] $catalogue + */ + public function setCatalogue($language, array $catalogue) + { + $this->catalogues[$language] = $catalogue; + } + + /** + * @param string $language + */ + public function setLanguage($language) + { + $this->language = $language; + } + + /** + * @param string $key + * @param string ... $value + * @return string + */ + public function translate($key, $value = null) + { + if ( + array_key_exists($this->language, $this->catalogues) + and array_key_exists($key, $this->catalogues[$this->language]) + ) { + $message = $this->catalogues[$this->language][$key]; + } elseif (array_key_exists($key, $this->defaultCatalogue) === true) { + // default fallback + $message = $this->defaultCatalogue[$key]; + } else { + // can't translate + return $key; + } + + if (func_num_args() == 1) { + return $message; + } + + $params = array_slice(func_get_args(), 1); + + foreach ($params as $i => $param) { + $message = str_replace('{' . $i . '}', $param, $message); + } + + return $message; + } +} diff --git a/tests/ShouldBee/Translation/NegotiationTest.php b/tests/ShouldBee/Translation/NegotiationTest.php new file mode 100644 index 0000000..5588f41 --- /dev/null +++ b/tests/ShouldBee/Translation/NegotiationTest.php @@ -0,0 +1,30 @@ +assertSame('en', $language); + + // set Accept-Language. + $_SERVER['HTTP_ACCEPT_LANGUAGE'] = "ja-JP,ja;q=0.8,en;q=0.6"; + $language = Negotiation::negotiate($availableLanguages); + $this->assertSame('ja', $language); + + // set query string. + $_GET['language'] = 'ko'; + $language = Negotiation::negotiate($availableLanguages); + $this->assertSame('ko', $language); + + // set cookie. + $_COOKIE['language'] = 'zh'; + $language = Negotiation::negotiate($availableLanguages); + $this->assertSame('zh', $language); + } +} \ No newline at end of file diff --git a/tests/ShouldBee/Translation/TranslatorTest.php b/tests/ShouldBee/Translation/TranslatorTest.php new file mode 100644 index 0000000..a78efe8 --- /dev/null +++ b/tests/ShouldBee/Translation/TranslatorTest.php @@ -0,0 +1,47 @@ +setCatalogue('ja', $japaneseCatalogue); + $translator->setCatalogue('en', $englishCatalogue); + + // no key to translate + $message = $translator->translate('foo.bar'); + $this->assertSame($message, 'foo.bar'); + + // output default catalogue translation, as no language is specified. + $message = $translator->translate('delete.confirm'); + $this->assertSame($message, 'delete ok?'); + + // set English to current language. + $translator->setLanguage('en'); + $message = $translator->translate('user.name'); + $this->assertSame($message, 'User name'); + + // replace placeholders + $message1 = $translator->translate("hello.user", "alice"); + $message2 = $translator->translate("files.summary", 12114, "Macintosh HD"); + $this->assertSame($message1, 'Hello, alice'); + $this->assertSame($message2, 'The disk Macintosh HD contains 12114 file(s).'); + + // output default catalogue translation, as there is no English translation for the key. + $message = $translator->translate("delete.confirm"); + $this->assertSame($message, 'delete ok?'); + + // set Japanese to current language. + $translator->setLanguage('ja'); + $message1 = $translator->translate("user.name"); + $message2 = $translator->translate("files.summary", 12114, "Macintosh HD"); + $this->assertSame($message1, 'ユーザ名'); + $this->assertSame($message2, 'ディスクMacintosh HDに12114個のファイル'); + } +} \ No newline at end of file diff --git a/tests/ShouldBee/Translation/catalogue-default.json b/tests/ShouldBee/Translation/catalogue-default.json new file mode 100644 index 0000000..44d707e --- /dev/null +++ b/tests/ShouldBee/Translation/catalogue-default.json @@ -0,0 +1,5 @@ +{ + "hello": "Hello", + "user.name": "User name", + "delete.confirm": "delete ok?" +} \ No newline at end of file diff --git a/tests/ShouldBee/Translation/catalogue-en.json b/tests/ShouldBee/Translation/catalogue-en.json new file mode 100644 index 0000000..d3524aa --- /dev/null +++ b/tests/ShouldBee/Translation/catalogue-en.json @@ -0,0 +1,6 @@ +{ + "hello": "Hello", + "user.name": "User name", + "hello.user": "Hello, {0}", + "files.summary": "The disk {1} contains {0} file(s)." +} \ No newline at end of file diff --git a/tests/ShouldBee/Translation/catalogue-ja.json b/tests/ShouldBee/Translation/catalogue-ja.json new file mode 100644 index 0000000..7863902 --- /dev/null +++ b/tests/ShouldBee/Translation/catalogue-ja.json @@ -0,0 +1,6 @@ +{ + "hello": "こんにちは", + "user.name": "ユーザ名", + "hello.user": "こんにちは, {0}さん", + "files.summary": "ディスク{1}に{0}個のファイル" +} \ No newline at end of file