diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index f182d06c9c9044554026e56e7843521b2a9214ce..9eba1f4267a3a685d730ad059e44f61fa39654d0 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -289,8 +289,13 @@ $config = array( $translator = $factory->createService($sm); // Set up the ExtendedIni plugin: + $pathStack = array( + APPLICATION_PATH . '/languages', + LOCAL_OVERRIDE_DIR . '/languages' + ); $translator->getPluginManager()->setService( - 'extendedini', new \VuFind\I18n\Translator\Loader\ExtendedIni() + 'extendedini', + new \VuFind\I18n\Translator\Loader\ExtendedIni($pathStack) ); // Set up language caching for better performance: diff --git a/module/VuFind/src/VuFind/Bootstrapper.php b/module/VuFind/src/VuFind/Bootstrapper.php index 56ad367b2291626c967d160a33be953a6abd5918..0ba80bf116708099ba7a4299c179bf19d34097f0 100644 --- a/module/VuFind/src/VuFind/Bootstrapper.php +++ b/module/VuFind/src/VuFind/Bootstrapper.php @@ -363,9 +363,8 @@ class Bootstrapper } $sm = $event->getApplication()->getServiceManager(); - $langFile = APPLICATION_PATH . '/languages/' . $language . '.ini'; $sm->get('VuFind\Translator') - ->addTranslationFile('ExtendedIni', $langFile, 'default', $language) + ->addTranslationFile('ExtendedIni', null, 'default', $language) ->setLocale($language); // Send key values to view: diff --git a/module/VuFind/src/VuFind/I18n/Translator/Loader/ExtendedIni.php b/module/VuFind/src/VuFind/I18n/Translator/Loader/ExtendedIni.php index b7bf10d214efd1234dc3fc270fde5522517fe1de..0df3043ec616884c89e8d1156af34bb6218dcbb4 100644 --- a/module/VuFind/src/VuFind/I18n/Translator/Loader/ExtendedIni.php +++ b/module/VuFind/src/VuFind/I18n/Translator/Loader/ExtendedIni.php @@ -42,17 +42,27 @@ use Zend\I18n\Exception\InvalidArgumentException, class ExtendedIni implements FileLoaderInterface { /** - * Parsed translation data + * List of directories to search for language files. * - * @var TextDomain + * @var array */ - protected $data; + protected $pathStack; + + /** + * Constructor + * + * @param array $pathStack List of directories to search for language files. + */ + public function __construct($pathStack = array()) + { + $this->pathStack = $pathStack; + } /** * load(): defined by LoaderInterface. * * @param string $locale Locale to read from language file - * @param string $filename Language file to read + * @param string $filename Language file to read (not used) * * @return TextDomain * @throws InvalidArgumentException @@ -60,21 +70,34 @@ class ExtendedIni implements FileLoaderInterface */ public function load($locale, $filename) { - $this->data = new TextDomain(); - if (!file_exists($filename)) { - throw new InvalidArgumentException("Ini file '".$filename."' not found"); - } - // Load base data: - $this->loadLanguageFile($filename); + return $this->loadLanguageFile($locale . '.ini'); + } - // Load local overrides, if available: - $localFile = LOCAL_OVERRIDE_DIR . '/languages/' . basename($filename); - if (file_exists($localFile)) { - $this->loadLanguageFile($localFile); + /** + * Search the path stack for language files and merge them together. + * + * @param string $filename Name of file to search path stack for. + * + * @return TextDomain + */ + protected function loadLanguageFile($filename) + { + $data = false; + foreach ($this->pathStack as $path) { + if (file_exists($path . '/' . $filename)) { + $current = $this->languageFileToTextDomain($path . '/' . $filename); + if ($data === false) { + $data = $current; + } else { + $data->merge($current); + } + } } - - return $this->data; + if ($data === false) { + throw new InvalidArgumentException("Ini file '{$filename}' not found"); + } + return $data; } /** @@ -82,10 +105,12 @@ class ExtendedIni implements FileLoaderInterface * * @param string $file Filename to load * - * @return void + * @return TextDomain */ - protected function loadLanguageFile($file) + protected function languageFileToTextDomain($file) { + $data = new TextDomain(); + // Manually parse the language file: $contents = file($file); if (is_array($contents)) { @@ -109,10 +134,12 @@ class ExtendedIni implements FileLoaderInterface '‌', ENT_NOQUOTES, 'UTF-8' ); } - $this->data[$key] = $value; + $data[$key] = $value; } } } } + + return $data; } } diff --git a/module/VuFind/tests/fixtures/language/base/en.ini b/module/VuFind/tests/fixtures/language/base/en.ini new file mode 100644 index 0000000000000000000000000000000000000000..89dba8cacc252ede704b374305855d1a8700b9f2 --- /dev/null +++ b/module/VuFind/tests/fixtures/language/base/en.ini @@ -0,0 +1,4 @@ +; This comment should be ignored +blank_line = "" +test1 = "test one" +test2 = "test two" \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/language/overrides/en.ini b/module/VuFind/tests/fixtures/language/overrides/en.ini new file mode 100644 index 0000000000000000000000000000000000000000..fc58817be4656ba75423221055785440dcf3c738 --- /dev/null +++ b/module/VuFind/tests/fixtures/language/overrides/en.ini @@ -0,0 +1 @@ +test2 = "test two - override" \ No newline at end of file diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/I18n/Translator/Loader/ExtendedIniTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/I18n/Translator/Loader/ExtendedIniTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ffb22687e9d7aa1fcecbea68da8691face427007 --- /dev/null +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/I18n/Translator/Loader/ExtendedIniTest.php @@ -0,0 +1,79 @@ +<?php +/** + * ExtendedIni translation loader Test Class + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package Tests + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:unit_tests Wiki + */ +namespace VuFindTest\I18n\Translator\Loader; +use VuFind\I18n\Translator\Loader\ExtendedIni; + +/** + * ExtendedIni translation loader Test Class + * + * @category VuFind2 + * @package Tests + * @author Demian Katz <demian.katz@villanova.edu> + * @author Chris Hallberg <challber@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:unit_tests Wiki + */ +class ExtendedIniTest extends \VuFindTest\Unit\TestCase +{ + /** + * Test translations. + * + * @return void + */ + public function testTranslations() + { + $pathStack = array( + realpath(__DIR__ . '/../../../../../../fixtures/language/base'), + realpath(__DIR__ . '/../../../../../../fixtures/language/overrides') + ); + $loader = new ExtendedIni($pathStack); + $result = $loader->load('en', null); + $this->assertEquals( + array( + 'blank_line' => + html_entity_decode('‌', ENT_NOQUOTES, 'UTF-8'), + 'test1' => 'test one', + 'test2' => 'test two - override', + ), + (array)$result + ); + } + + /** + * Test missing path stack. + * + * @return void + * @expectedException Zend\I18n\Exception\InvalidArgumentException + * @expectedExceptionMessage Ini file 'en.ini' not found + */ + public function testMissingPathStack() + { + $loader = new ExtendedIni(); + $loader->load('en', null); + } +} \ No newline at end of file