diff --git a/LiveTranslator/Storage/NetteDatabase.php b/LiveTranslator/Storage/NetteDatabase.php index 021c8f2..f6525ff 100644 --- a/LiveTranslator/Storage/NetteDatabase.php +++ b/LiveTranslator/Storage/NetteDatabase.php @@ -15,6 +15,8 @@ class NetteDatabase implements \LiveTranslator\ITranslatorStorage /** @var string */ private $translationTable; + /** @var \Nette\Caching\Cache */ + private $cache; /** @@ -22,8 +24,9 @@ class NetteDatabase implements \LiveTranslator\ITranslatorStorage * @param string $translationTableName name of table with translated texts * @param \Nette\Database\Connection $db * @param \Nette\Database\Context|NULL $context + * @param \Nette\Caching\IStorage $cacheStorage */ - public function __construct($defaultTableName, $translationTableName, \Nette\Database\Connection $db, \Nette\Database\Context $context = NULL) + public function __construct($defaultTableName, $translationTableName, \Nette\Database\Connection $db, \Nette\Database\Context $context = NULL, \Nette\Caching\IStorage $cacheStorage) { $this->db = $context ?: $db; // Context is part of newer Nette version if ($defaultTableName[0] !== '`') { @@ -34,29 +37,50 @@ public function __construct($defaultTableName, $translationTableName, \Nette\Dat } $this->defaultTable = $defaultTableName; $this->translationTable = $translationTableName; + + $this->cache = new \Nette\Caching\Cache($cacheStorage, 'VladaHejda.LiveTranslator'); + } + + + + public function cacheDisable($disable = TRUE) + { + if ($disable) { + $this->cache = NULL; + } } public function getTranslation($original, $lang, $variant = 0, $namespace = NULL) { - $arg = array(); + $translation = isset($this->cache) ? $this->cache->load($original.$lang.$variant.$namespace) : NULL; - $arg[0] = "SELECT t.`translation` FROM {$this->defaultTable} d - JOIN {$this->translationTable} t ON d.`id` = t.`text_id` - WHERE "; + if ($translation === NULL) { + $arg = array(); - if ($namespace){ - $arg[0] .= 'd.`ns` = ? AND '; - $arg[] = $namespace; - } + $arg[0] = "SELECT t.`translation` FROM {$this->defaultTable} d + JOIN {$this->translationTable} t ON d.`id` = t.`text_id` + WHERE "; - $arg[0] .= 'd.`text` = ? AND t.`lang` = ? AND t.`variant` <= ? ORDER BY t.`variant` DESC'; - $arg[] = $original; - $arg[] = $lang; - $arg[] = $variant; + if ($namespace){ + $arg[0] .= 'd.`ns` = ? AND '; + $arg[] = $namespace; + } + + $arg[0] .= 'BINARY d.`text` = ? AND t.`lang` = ? AND t.`variant` <= ? ORDER BY t.`variant` DESC'; + $arg[] = $original; + $arg[] = $lang; + $arg[] = $variant; - $translation = $this->fetchField($arg); + $translation = $this->fetchField($arg); + + if (isset($this->cache)) { + $this->cache->save($original.$lang.$variant.$namespace, $translation, array( + \Nette\Caching\Cache::TAGS => array($original.$lang.$namespace) + )); + } + } return $translation ?: NULL; } @@ -95,6 +119,10 @@ public function getAllTranslations($lang, $namespace = NULL) public function setTranslation($original, $translated, $lang, $variant = 0, $namespace = NULL) { + if (isset($this->cache)) { + $this->cache->remove($original.$lang.$variant.$namespace); + } + $arg = array(); $arg[0] = "SELECT `id` FROM {$this->defaultTable} WHERE "; @@ -104,7 +132,7 @@ public function setTranslation($original, $translated, $lang, $variant = 0, $nam $arg[] = $namespace; } - $arg[0] .= "`text` = ?"; + $arg[0] .= "BINARY `text` = ?"; $arg[] = $original; $textId = $this->fetchField($arg); @@ -140,6 +168,10 @@ public function setTranslation($original, $translated, $lang, $variant = 0, $nam public function removeTranslation($original, $lang, $namespace = NULL) { + if (isset($this->cache)) { + $this->cache->clean(array(\Nette\Caching\Cache::TAGS => $original.$lang.$namespace)); + } + $arg = array(); $arg[0] = "SELECT d.`id` FROM {$this->defaultTable} d diff --git a/LiveTranslator/Translator.php b/LiveTranslator/Translator.php index 9033d88..806a8a7 100644 --- a/LiveTranslator/Translator.php +++ b/LiveTranslator/Translator.php @@ -46,20 +46,34 @@ class Translator extends Nette\Object implements Nette\Localization\ITranslator /** @var Nette\Application\Application */ private $application; + /** @var \Nette\Caching\Cache */ + private $cache; + /** * @param string $defaultLang * @param ITranslatorStorage $translatorStorage * @param Nette\Http\Session $session * @param Nette\Application\Application $application + * @param \Nette\Caching\IStorage $cacheStorage */ - public function __construct($defaultLang, ITranslatorStorage $translatorStorage, Nette\Http\Session $session, Nette\Application\Application $application) + public function __construct($defaultLang, ITranslatorStorage $translatorStorage, Nette\Http\Session $session, Nette\Application\Application $application, Nette\Caching\IStorage $cacheStorage) { $this->setDefaultLang($defaultLang); $this->translatorStorage = $translatorStorage; $session->start(); $this->session = $session; $this->application = $application; + + $this->cache = new Nette\Caching\Cache($cacheStorage, 'VladaHejda.LiveTranslator'); + } + + + public function cacheDisable($disable = TRUE) + { + if ($disable) { + $this->cache = NULL; + } } @@ -279,7 +293,7 @@ public function setPresenterLanguageParam($paramName) * @return string * @throws TranslatorException */ - public function translate($string, $count = 1) + public function translate($string, $count = NULL) { $hasVariants = FALSE; if (is_array($string)) { @@ -297,6 +311,9 @@ public function translate($string, $count = 1) unset($args[0]); $args = array_values($args); + } elseif ($count === NULL) { + $args = NULL; + } else { $args = array($count); } @@ -355,8 +372,7 @@ public function translate($string, $count = 1) } if (!$translated) { - $newStrings = &$this->getNewStrings(); - $newStrings[$string] = FALSE; + $this->setNewStringUntranslated($string); if ($hasVariants) { if (isset($stringVariants[$plural])) { @@ -370,7 +386,7 @@ public function translate($string, $count = 1) } } - if (FALSE !== strpos($translated, '%')) { + if ($args !== NULL AND FALSE !== strpos($translated, '%')) { $tmp = str_replace(array('%label', '%name', '%value'), array('#label', '#name', '#value'), $translated); if (FALSE !== strpos($tmp, '%')) { $translated = vsprintf($tmp, $args); @@ -413,9 +429,8 @@ public function setTranslation($original, $translated) } $original = trim($original); if ($translated === FALSE) { - $newStrings = &$this->getNewStrings(); $this->translatorStorage->removeTranslation($original, $lang, $this->namespace); - $newStrings[$original] = FALSE; + $this->setNewStringUntranslated($original); return; } @@ -426,8 +441,7 @@ public function setTranslation($original, $translated) foreach ($translated as $variant => $string) { $this->translatorStorage->setTranslation($original, $string, $lang, $variant, $this->namespace); } - $newStrings = &$this->getNewStrings(); - unset($newStrings[$original]); + $this->setNewStringTranslated($original); } @@ -440,14 +454,53 @@ protected function getSessionSection() - protected function &getNewStrings() + protected function saveNewStrings(array $newStrings) + { + if (isset($this->cache)) { + $ns = $this->namespace ?: 'default'; + $this->cache->save("newStrings-$ns", $newStrings); + + } else { + $section = $this->getSessionSection(); + $section->strings = $newStrings; + } + } + + + + protected function setNewStringTranslated($original) { - // todo mohlo by to mít jednu section a ns by byly jednotlivý property zde - $section = $this->getSessionSection(); - if (!isset($section->strings)) { - $section->strings = array(); + $newStrings = $this->getNewStrings(); + unset($newStrings[$original]); + $this->saveNewStrings($newStrings); + } + + + + protected function setNewStringUntranslated($original) + { + $newStrings = $this->getNewStrings(); + $newStrings[$original] = FALSE; + $this->saveNewStrings($newStrings); + } + + + + protected function getNewStrings() + { + if (isset($this->cache)) { + $ns = $this->namespace ?: 'default'; + $strings = (array) $this->cache->load("newStrings-$ns"); + + } else { + // todo mohlo by to mít jednu section a ns by byly jednotlivý property zde + $section = $this->getSessionSection(); + if (!isset($section->strings)) { + $section->strings = array(); + } + $strings = $section->strings; } - $strings = &$section->strings; + return $strings; } diff --git a/README.md b/README.md index be89a85..d31c408 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,15 @@ services: translatorStorage: LiveTranslator\Storage\NetteDatabase(localization_text, localization) ``` -*You can rename tables in SQL script (use the same names in config file).* +*You can rename tables in SQL script (use the same names in config file).* +In default `LiveTranslator\Storage\NetteDatabase` uses `Nette\Caching`. For disabling this function use `cacheDisable()` method: +``` +services: + translatorStorage: + class: LiveTranslator\Storage\NetteDatabase(localization_text, localization) + setup: + - cacheDisable() +``` - **I am using [Dibi](http://dibiphp.com/)** @@ -95,6 +103,16 @@ services: translatorPanel: LiveTranslator\Panel ``` +In default `LiveTranslator\Translator` uses `Nette\Caching` for storage untranslated strings. For disabling caching use `cacheDisable()` method. Then will be use SEESIONS: +``` +services: + translator: + class: LiveTranslator\Translator(en) + setup: + - cacheDisable() + ... +``` + ### 3. set up your BasePresenter diff --git a/tests/Panel.phpt b/tests/Panel.phpt index ede8571..386514e 100644 --- a/tests/Panel.phpt +++ b/tests/Panel.phpt @@ -5,7 +5,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/simple.php'; -$trans = new \LiveTranslator\Translator('en', new SimpleStorage, $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('en', new SimpleStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $panel = new \LiveTranslator\Panel($trans, $container->getService('httpRequest')); Assert::type('LiveTranslator\Translator', $panel->getTranslator()); diff --git a/tests/Translator.exceptions.phpt b/tests/Translator.exceptions.phpt index cf5de55..bb35a01 100644 --- a/tests/Translator.exceptions.phpt +++ b/tests/Translator.exceptions.phpt @@ -6,10 +6,10 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/dummy.php'; Assert::exception(function() use($container){ - new \LiveTranslator\Translator('', new DummyStorage, $container->getService('session'), $container->getService('application')); + new \LiveTranslator\Translator('', new DummyStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); }, 'LiveTranslator\TranslatorException'); -$trans = new \LiveTranslator\Translator('en', new DummyStorage, $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('en', new DummyStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setAvailableLanguages(array( 'en', 'cz' @@ -23,7 +23,7 @@ Assert::exception(function() use($trans){ $trans->setDefaultLang('de'); }, 'LiveTranslator\TranslatorException'); -$trans = new \LiveTranslator\Translator('de', new DummyStorage(), $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('de', new DummyStorage(), $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); Assert::exception(function() use($trans){ $trans->setAvailableLanguages(array( @@ -31,7 +31,7 @@ Assert::exception(function() use($trans){ )); }, 'LiveTranslator\TranslatorException'); -$trans = new \LiveTranslator\Translator('en', new DummyStorage(), $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('en', new DummyStorage(), $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setCurrentLang('de'); diff --git a/tests/Translator.getAll.phpt b/tests/Translator.getAll.phpt index f35fbeb..3ca66be 100644 --- a/tests/Translator.getAll.phpt +++ b/tests/Translator.getAll.phpt @@ -6,7 +6,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/simple.php'; use \LiveTranslator\Translator as Tr; -$trans = new Tr('en', new SimpleStorage, $container->getService('session'), $container->getService('application')); +$trans = new Tr('en', new SimpleStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setCurrentLang('cz'); diff --git a/tests/Translator.langSwitch.phpt b/tests/Translator.langSwitch.phpt index 5d0864c..1f53673 100644 --- a/tests/Translator.langSwitch.phpt +++ b/tests/Translator.langSwitch.phpt @@ -6,7 +6,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/language.php'; use \LiveTranslator\Translator as Tr; -$trans = new Tr('en', new LanguageStorage, $container->getService('session'), $container->getService('application')); +$trans = new Tr('en', new LanguageStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setCurrentLang('cz'); diff --git a/tests/Translator.minimum.phpt b/tests/Translator.minimum.phpt index 30c58c8..bf3b67a 100644 --- a/tests/Translator.minimum.phpt +++ b/tests/Translator.minimum.phpt @@ -5,6 +5,6 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/dummy.php'; -$trans = new \LiveTranslator\Translator('en', new DummyStorage, $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('en', new DummyStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); Assert::equal('hello', $trans->translate('hello')); diff --git a/tests/Translator.namespaces.phpt b/tests/Translator.namespaces.phpt index 1015685..024d7c8 100644 --- a/tests/Translator.namespaces.phpt +++ b/tests/Translator.namespaces.phpt @@ -6,7 +6,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/namespace.php'; use \LiveTranslator\Translator as Tr; -$trans = new Tr('en', new NamespaceStorage, $container->getService('session'), $container->getService('application')); +$trans = new Tr('en', new NamespaceStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setCurrentLang('cz') ->setNamespace('first'); diff --git a/tests/Translator.phpt b/tests/Translator.phpt index d781c14..cb07052 100644 --- a/tests/Translator.phpt +++ b/tests/Translator.phpt @@ -5,7 +5,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/simple.php'; -$trans = new \LiveTranslator\Translator('en', new SimpleStorage, $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('en', new SimpleStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setCurrentLang('cz') ->setAvailableLanguages(array( @@ -31,6 +31,9 @@ Assert::equal('jména Johnny, George', $trans->translate(array('name %s'), 'Joh Assert::equal('Woohoo křičí 1 muž.', $trans->translate(array('%2$d man screams %1$s.'), 'Woohoo', 1)); Assert::equal('2 muži křičí "Woohoo!".', $trans->translate(array('%2$d man screams %1$s.'), 'Woohoo', 2)); Assert::equal('Woohoo křičí 5 mužů.', $trans->translate(array('%2$d man screams %1$s.'), 'Woohoo', 5)); +Assert::equal('Tax is 21%', $trans->translate('Tax is 21%')); +Assert::equal('Tax is 21% or 15%', $trans->translate('Tax is 21% or 15%')); +Assert::equal('50%done', $trans->translate('50%done')); $trans->setCurrentLang('en'); diff --git a/tests/Translator.remove.phpt b/tests/Translator.remove.phpt index b43040f..37657a7 100644 --- a/tests/Translator.remove.phpt +++ b/tests/Translator.remove.phpt @@ -6,7 +6,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/simple.php'; use \LiveTranslator\Translator as Tr; -$trans = new Tr('en', new SimpleStorage, $container->getService('session'), $container->getService('application')); +$trans = new Tr('en', new SimpleStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setCurrentLang('cz'); diff --git a/tests/Translator.set.phpt b/tests/Translator.set.phpt index 03e825d..20046e5 100644 --- a/tests/Translator.set.phpt +++ b/tests/Translator.set.phpt @@ -5,7 +5,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/simple.php'; -$trans = new \LiveTranslator\Translator('en', new SimpleStorage, $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('en', new SimpleStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans->setCurrentLang('cz') ->setAvailableLanguages(array( diff --git a/tests/Translator.variants.phpt b/tests/Translator.variants.phpt index 827ef6e..ce8acb7 100644 --- a/tests/Translator.variants.phpt +++ b/tests/Translator.variants.phpt @@ -5,7 +5,7 @@ $container = require __DIR__ . '/bootstrap.application.php'; require __DIR__.'/storage/dummy.php'; -$trans = new \LiveTranslator\Translator('cz', new DummyStorage, $container->getService('session'), $container->getService('application')); +$trans = new \LiveTranslator\Translator('cz', new DummyStorage, $container->getService('session'), $container->getService('application'), $container->getService('cache.storage')); $trans::$defaultPluralForms = 'nplurals=2; plural=(n==1) ? 0 : 1;'; Assert::equal(2, $trans->getVariantsCount()); diff --git a/tests/bootstrap.application.php b/tests/bootstrap.application.php index 1efae73..e807c0a 100644 --- a/tests/bootstrap.application.php +++ b/tests/bootstrap.application.php @@ -11,6 +11,21 @@ Tester\Environment::setup(); +// For caching lock tests and clean up cache dir +@mkdir($dir = __DIR__ . '/temp/lock'); +Tester\Environment::lock('cache', $dir); + +if (is_dir($dir = __DIR__ . '/temp/cache/_VladaHejda.LiveTranslator')) { + $h = opendir($dir); + while ($file = readdir($h)) { + if (is_dir($file)) { + continue; + } + unlink("$dir/$file"); + } +} + + $configurator = new Nette\Configurator; $configurator->setTempDirectory(__DIR__ . '/temp'); return $configurator->createContainer();