diff --git a/thirdparty/zend_translate_railsyaml/.piston.yml b/thirdparty/zend_translate_railsyaml/.piston.yml new file mode 100644 index 000000000..572cc4ba4 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/.piston.yml @@ -0,0 +1,8 @@ +--- +format: 1 +handler: + commit: 2d5f2164b200309f6643f8f8486e0cdbbcae348d + branch: master +lock: false +repository_class: Piston::Git::Repository +repository_url: git://github.com/chillu/zend_translate_railsyaml.git diff --git a/thirdparty/zend_translate_railsyaml/LICENSE b/thirdparty/zend_translate_railsyaml/LICENSE new file mode 100644 index 000000000..8fc42c252 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/LICENSE @@ -0,0 +1,24 @@ +* Copyright (c) 2011, Ingo Schommer +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY Ingo Schommer. ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL Silverstripe Ltd. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/thirdparty/zend_translate_railsyaml/README.md b/thirdparty/zend_translate_railsyaml/README.md new file mode 100644 index 000000000..e1889e816 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/README.md @@ -0,0 +1,61 @@ +# Zend_Translate Adapter for Rails-style YAML files # + +## Overview ## + +Adds support for translations in YAML to [Zend_Translate](http://framework.zend.com/manual/en/zend.translate.html). +As Yaml is a very flexible format, the translation files need some conventions. +These conventions are adopted from Ruby on Rails (see [Rails' i18n docs](http://guides.rubyonrails.org/i18n.html)). +Note: You don't need Ruby or Rails to run this code, its just PHP with the same YAML conventions. + +## Requirements ## + + * Zend Framework (tested with 1.11.6) + * PHP 5.2 + +## Installation and Usage ## + +Assumes a working `include_path` setup for Zend (see [tutorial](http://framework.zend.com/manual/en/learning.quickstart.create-project.html)). + +Copy the files into your Zend directory (replace `` below): + + cp -r library/Translate/Adapter/* /Zend/Translate/Adapter + cp -r tests/Translate/Adapter/* /Zend/tests/Translate/Adapter + +Usage: + + require_once 'Zend/Translate/Adapater/RailsYaml.php'; + $adapter = new Zend_Translate_Adapter_RailsYaml('en.yml', 'en'); + $adapter->addTranslation('de.yml', 'de'); + +Does not support namespace "fallbacks", as `Zend_Translate` +doesn't have built-in support for them - it just flattens nested keys. +Does not support multiple locales per translation file. + +## Sample translation files + +en.yml + + en: + Message1: Message 1 (en) + Message2: Message 2 (en) + Namespace1: + Message1: Namespace 1 Message 2 (en) + Namespace1Message1: Namespace 1 Message 2 (en) + +de.yml + + de: + Message1: Message 1 (de) + Namespace1: + Message1: Namespace 1 Message 2 (de) + Namespace1Message1: Namespace 1 Message 2 (de) + +## Running the unit tests ## + +The tests assume the Zend Framework in a very specific location. See `tests/TestHelper.php` for details. +Its recommended that you copy the relevant files directly into the Zend directory structure. + +## Links ## + + * [`Zend_Translate_Yaml` Proposal on zend.com](http://framework.zend.com/wiki/display/ZFPROP/Zend_Translate_Yaml+-+Thomas+Weidner) - not actively pursued any longer + * [`Zend_Translate_Yaml` sample code](http://framework.zend.com/issues/browse/ZF-2152) \ No newline at end of file diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/RailsYAML.php b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/RailsYAML.php new file mode 100644 index 000000000..3441d8e2a --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/RailsYAML.php @@ -0,0 +1,104 @@ +_options['keyDelimiter'] = "."; + + parent::__construct($options); + } + + /** + * Load translation data + * + * @param string|array $data Filename and full path to the translation source + * @param string $locale Locale/Language to add data for, identical with locale identifier, + * see Zend_Locale for more information + * @param array $option OPTIONAL Options to use + */ + protected function _loadTranslationData($data, $locale, array $options = array()) + { + $options = array_merge($this->_options, $options); + + if ($options['clear'] || !isset($this->_translate[$locale])) { + $this->_translate[$locale] = array(); + } + + if(is_array($data)) return array($locale => $data); + + $this->_filename = $data; + if (!is_readable($this->_filename)) { + require_once 'Zend/Translate/Exception.php'; + throw new Zend_Translate_Exception('Error opening translation file \'' . $this->_filename . '\'.'); + } + + $content = sfYaml::load(file_get_contents($this->_filename)); + if($locale != 'auto' && !array_key_exists($locale, $content)) { + require_once 'Zend/Translate/Exception.php'; + throw new Zend_Translate_Exception(sprintf('Locale "%s" not found in file %s', $locale, $this->_filename)); + } + + // Rails YML files supported arbitrarily nested keys, Zend_Translate doesn't - so we flatten them. + // See http://stackoverflow.com/questions/7011451/transaprently-flatten-an-array/7011675 + $flattened = array(); + if($content[$locale]) { + $iterator = new Translate_Adapter_RailsYaml_Iterator(new RecursiveArrayIterator($content[$locale])); + foreach($iterator as $k => $v) { + $flattened[implode($options['keyDelimiter'], $iterator->getKeyStack())] = $v; + } + } + + return array($locale => $flattened); + } + + /** + * returns the adapters name + * + * @return string + */ + public function toString() + { + return "RailsYaml"; + } + +} + +class Translate_Adapter_RailsYaml_Iterator extends RecursiveIteratorIterator +{ + protected $keyStack = array(); + + public function callGetChildren() + { + $this->keyStack[] = parent::key(); + return parent::callGetChildren(); + } + + public function endChildren() + { + array_pop($this->keyStack); + parent::endChildren(); + } + + public function key() + { + return json_encode($this->getKeyStack()); + } + + public function getKeyStack() + { + return array_merge($this->keyStack, array(parent::key())); + } +} \ No newline at end of file diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/LICENSE b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/LICENSE new file mode 100644 index 000000000..3cef85317 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2008-2009 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/README.markdown b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/README.markdown new file mode 100644 index 000000000..e4f80cfba --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/README.markdown @@ -0,0 +1,15 @@ +Symfony YAML: A PHP library that speaks YAML +============================================ + +Symfony YAML is a PHP library that parses YAML strings and converts them to +PHP arrays. It can also converts PHP arrays to YAML strings. Its official +website is at http://components.symfony-project.org/yaml/. + +The documentation is to be found in the `doc/` directory. + +Symfony YAML is licensed under the MIT license (see LICENSE file). + +The Symfony YAML library is developed and maintained by the +[symfony](http://www.symfony-project.org/) project team. It has been extracted +from symfony to be used as a standalone library. Symfony YAML is part of the +[symfony components project](http://components.symfony-project.org/). diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYaml.php b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYaml.php new file mode 100644 index 000000000..1d89ccc97 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYaml.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * sfYaml offers convenience methods to load and dump YAML. + * + * @package symfony + * @subpackage yaml + * @author Fabien Potencier + * @version SVN: $Id: sfYaml.class.php 8988 2008-05-15 20:24:26Z fabien $ + */ +class sfYaml +{ + static protected + $spec = '1.2'; + + /** + * Sets the YAML specification version to use. + * + * @param string $version The YAML specification version + */ + static public function setSpecVersion($version) + { + if (!in_array($version, array('1.1', '1.2'))) + { + throw new InvalidArgumentException(sprintf('Version %s of the YAML specifications is not supported', $version)); + } + + self::$spec = $version; + } + + /** + * Gets the YAML specification version to use. + * + * @return string The YAML specification version + */ + static public function getSpecVersion() + { + return self::$spec; + } + + /** + * Loads YAML into a PHP array. + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. + * + * Usage: + * + * $array = sfYaml::load('config.yml'); + * print_r($array); + * + * + * @param string $input Path of YAML file or string containing YAML + * + * @return array The YAML converted to a PHP array + * + * @throws InvalidArgumentException If the YAML is not valid + */ + public static function load($input) + { + $file = ''; + + // if input is a file, process it + if (strpos($input, "\n") === false && is_file($input)) + { + $file = $input; + + ob_start(); + $retval = include($input); + $content = ob_get_clean(); + + // if an array is returned by the config file assume it's in plain php form else in YAML + $input = is_array($retval) ? $retval : $content; + } + + // if an array is returned by the config file assume it's in plain php form else in YAML + if (is_array($input)) + { + return $input; + } + + require_once dirname(__FILE__).'/sfYamlParser.php'; + + $yaml = new sfYamlParser(); + + try + { + $ret = $yaml->parse($input); + } + catch (Exception $e) + { + throw new InvalidArgumentException(sprintf('Unable to parse %s: %s', $file ? sprintf('file "%s"', $file) : 'string', $e->getMessage())); + } + + return $ret; + } + + /** + * Dumps a PHP array to a YAML string. + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. + * + * @param array $array PHP array + * @param integer $inline The level where you switch to inline YAML + * + * @return string A YAML string representing the original PHP array + */ + public static function dump($array, $inline = 2) + { + require_once dirname(__FILE__).'/sfYamlDumper.php'; + + $yaml = new sfYamlDumper(); + + return $yaml->dump($array, $inline); + } +} + +/** + * Wraps echo to automatically provide a newline. + * + * @param string $string The string to echo with new line + */ +function echoln($string) +{ + echo $string."\n"; +} diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlDumper.php b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlDumper.php new file mode 100644 index 000000000..0ada2b37d --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlDumper.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require_once(dirname(__FILE__).'/sfYamlInline.php'); + +/** + * sfYamlDumper dumps PHP variables to YAML strings. + * + * @package symfony + * @subpackage yaml + * @author Fabien Potencier + * @version SVN: $Id: sfYamlDumper.class.php 10575 2008-08-01 13:08:42Z nicolas $ + */ +class sfYamlDumper +{ + /** + * Dumps a PHP value to YAML. + * + * @param mixed $input The PHP value + * @param integer $inline The level where you switch to inline YAML + * @param integer $indent The level o indentation indentation (used internally) + * + * @return string The YAML representation of the PHP value + */ + public function dump($input, $inline = 0, $indent = 0) + { + $output = ''; + $prefix = $indent ? str_repeat(' ', $indent) : ''; + + if ($inline <= 0 || !is_array($input) || empty($input)) + { + $output .= $prefix.sfYamlInline::dump($input); + } + else + { + $isAHash = array_keys($input) !== range(0, count($input) - 1); + + foreach ($input as $key => $value) + { + $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value); + + $output .= sprintf('%s%s%s%s', + $prefix, + $isAHash ? sfYamlInline::dump($key).':' : '-', + $willBeInlined ? ' ' : "\n", + $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + 2) + ).($willBeInlined ? "\n" : ''); + } + } + + return $output; + } +} diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlInline.php b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlInline.php new file mode 100644 index 000000000..a88cbb3d9 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlInline.php @@ -0,0 +1,442 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require_once dirname(__FILE__).'/sfYaml.php'; + +/** + * sfYamlInline implements a YAML parser/dumper for the YAML inline syntax. + * + * @package symfony + * @subpackage yaml + * @author Fabien Potencier + * @version SVN: $Id: sfYamlInline.class.php 16177 2009-03-11 08:32:48Z fabien $ + */ +class sfYamlInline +{ + const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; + + /** + * Convert a YAML string to a PHP array. + * + * @param string $value A YAML string + * + * @return array A PHP array representing the YAML string + */ + static public function load($value) + { + $value = trim($value); + + if (0 == strlen($value)) + { + return ''; + } + + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) + { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('ASCII'); + } + + switch ($value[0]) + { + case '[': + $result = self::parseSequence($value); + break; + case '{': + $result = self::parseMapping($value); + break; + default: + $result = self::parseScalar($value); + } + + if (isset($mbEncoding)) + { + mb_internal_encoding($mbEncoding); + } + + return $result; + } + + /** + * Dumps a given PHP variable to a YAML string. + * + * @param mixed $value The PHP variable to convert + * + * @return string The YAML string representing the PHP array + */ + static public function dump($value) + { + if ('1.1' === sfYaml::getSpecVersion()) + { + $trueValues = array('true', 'on', '+', 'yes', 'y'); + $falseValues = array('false', 'off', '-', 'no', 'n'); + } + else + { + $trueValues = array('true'); + $falseValues = array('false'); + } + + switch (true) + { + case is_resource($value): + throw new InvalidArgumentException('Unable to dump PHP resources in a YAML file.'); + case is_object($value): + return '!!php/object:'.serialize($value); + case is_array($value): + return self::dumpArray($value); + case null === $value: + return 'null'; + case true === $value: + return 'true'; + case false === $value: + return 'false'; + case ctype_digit($value): + return is_string($value) ? "'$value'" : (int) $value; + case is_numeric($value): + return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value); + case false !== strpos($value, "\n") || false !== strpos($value, "\r"): + return sprintf('"%s"', str_replace(array('"', "\n", "\r"), array('\\"', '\n', '\r'), $value)); + case preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value): + return sprintf("'%s'", str_replace('\'', '\'\'', $value)); + case '' == $value: + return "''"; + case preg_match(self::getTimestampRegex(), $value): + return "'$value'"; + case in_array(strtolower($value), $trueValues): + return "'$value'"; + case in_array(strtolower($value), $falseValues): + return "'$value'"; + case in_array(strtolower($value), array('null', '~')): + return "'$value'"; + default: + return $value; + } + } + + /** + * Dumps a PHP array to a YAML string. + * + * @param array $value The PHP array to dump + * + * @return string The YAML string representing the PHP array + */ + static protected function dumpArray($value) + { + // array + $keys = array_keys($value); + if ( + (1 == count($keys) && '0' == $keys[0]) + || + (count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2)) + { + $output = array(); + foreach ($value as $val) + { + $output[] = self::dump($val); + } + + return sprintf('[%s]', implode(', ', $output)); + } + + // mapping + $output = array(); + foreach ($value as $key => $val) + { + $output[] = sprintf('%s: %s', self::dump($key), self::dump($val)); + } + + return sprintf('{ %s }', implode(', ', $output)); + } + + /** + * Parses a scalar to a YAML string. + * + * @param scalar $scalar + * @param string $delimiters + * @param array $stringDelimiter + * @param integer $i + * @param boolean $evaluate + * + * @return string A YAML string + */ + static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true) + { + if (in_array($scalar[$i], $stringDelimiters)) + { + // quoted scalar + $output = self::parseQuotedScalar($scalar, $i); + } + else + { + // "normal" string + if (!$delimiters) + { + $output = substr($scalar, $i); + $i += strlen($output); + + // remove comments + if (false !== $strpos = strpos($output, ' #')) + { + $output = rtrim(substr($output, 0, $strpos)); + } + } + else if (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) + { + $output = $match[1]; + $i += strlen($output); + } + else + { + throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', $scalar)); + } + + $output = $evaluate ? self::evaluateScalar($output) : $output; + } + + return $output; + } + + /** + * Parses a quoted scalar to YAML. + * + * @param string $scalar + * @param integer $i + * + * @return string A YAML string + */ + static protected function parseQuotedScalar($scalar, &$i) + { + if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) + { + throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i))); + } + + $output = substr($match[0], 1, strlen($match[0]) - 2); + + if ('"' == $scalar[$i]) + { + // evaluate the string + $output = str_replace(array('\\"', '\\n', '\\r'), array('"', "\n", "\r"), $output); + } + else + { + // unescape ' + $output = str_replace('\'\'', '\'', $output); + } + + $i += strlen($match[0]); + + return $output; + } + + /** + * Parses a sequence to a YAML string. + * + * @param string $sequence + * @param integer $i + * + * @return string A YAML string + */ + static protected function parseSequence($sequence, &$i = 0) + { + $output = array(); + $len = strlen($sequence); + $i += 1; + + // [foo, bar, ...] + while ($i < $len) + { + switch ($sequence[$i]) + { + case '[': + // nested sequence + $output[] = self::parseSequence($sequence, $i); + break; + case '{': + // nested mapping + $output[] = self::parseMapping($sequence, $i); + break; + case ']': + return $output; + case ',': + case ' ': + break; + default: + $isQuoted = in_array($sequence[$i], array('"', "'")); + $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i); + + if (!$isQuoted && false !== strpos($value, ': ')) + { + // embedded mapping? + try + { + $value = self::parseMapping('{'.$value.'}'); + } + catch (InvalidArgumentException $e) + { + // no, it's not + } + } + + $output[] = $value; + + --$i; + } + + ++$i; + } + + throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $sequence)); + } + + /** + * Parses a mapping to a YAML string. + * + * @param string $mapping + * @param integer $i + * + * @return string A YAML string + */ + static protected function parseMapping($mapping, &$i = 0) + { + $output = array(); + $len = strlen($mapping); + $i += 1; + + // {foo: bar, bar:foo, ...} + while ($i < $len) + { + switch ($mapping[$i]) + { + case ' ': + case ',': + ++$i; + continue 2; + case '}': + return $output; + } + + // key + $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false); + + // value + $done = false; + while ($i < $len) + { + switch ($mapping[$i]) + { + case '[': + // nested sequence + $output[$key] = self::parseSequence($mapping, $i); + $done = true; + break; + case '{': + // nested mapping + $output[$key] = self::parseMapping($mapping, $i); + $done = true; + break; + case ':': + case ' ': + break; + default: + $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i); + $done = true; + --$i; + } + + ++$i; + + if ($done) + { + continue 2; + } + } + } + + throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $mapping)); + } + + /** + * Evaluates scalars and replaces magic values. + * + * @param string $scalar + * + * @return string A YAML string + */ + static protected function evaluateScalar($scalar) + { + $scalar = trim($scalar); + + if ('1.1' === sfYaml::getSpecVersion()) + { + $trueValues = array('true', 'on', '+', 'yes', 'y'); + $falseValues = array('false', 'off', '-', 'no', 'n'); + } + else + { + $trueValues = array('true'); + $falseValues = array('false'); + } + + switch (true) + { + case 'null' == strtolower($scalar): + case '' == $scalar: + case '~' == $scalar: + return null; + case 0 === strpos($scalar, '!str'): + return (string) substr($scalar, 5); + case 0 === strpos($scalar, '! '): + return intval(self::parseScalar(substr($scalar, 2))); + case 0 === strpos($scalar, '!!php/object:'): + return unserialize(substr($scalar, 13)); + case ctype_digit($scalar): + $raw = $scalar; + $cast = intval($scalar); + return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); + case in_array(strtolower($scalar), $trueValues): + return true; + case in_array(strtolower($scalar), $falseValues): + return false; + case is_numeric($scalar): + return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar); + case 0 == strcasecmp($scalar, '.inf'): + case 0 == strcasecmp($scalar, '.NaN'): + return -log(0); + case 0 == strcasecmp($scalar, '-.inf'): + return log(0); + case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): + return floatval(str_replace(',', '', $scalar)); + case preg_match(self::getTimestampRegex(), $scalar): + return strtotime($scalar); + default: + return (string) $scalar; + } + } + + static protected function getTimestampRegex() + { + return <<[0-9][0-9][0-9][0-9]) + -(?P[0-9][0-9]?) + -(?P[0-9][0-9]?) + (?:(?:[Tt]|[ \t]+) + (?P[0-9][0-9]?) + :(?P[0-9][0-9]) + :(?P[0-9][0-9]) + (?:\.(?P[0-9]*))? + (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) + (?::(?P[0-9][0-9]))?))?)? + $~x +EOF; + } +} diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlParser.php b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlParser.php new file mode 100644 index 000000000..cc6ba609e --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlParser.php @@ -0,0 +1,622 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require_once(dirname(__FILE__).'/sfYamlInline.php'); + +if (!defined('PREG_BAD_UTF8_OFFSET_ERROR')) +{ + define('PREG_BAD_UTF8_OFFSET_ERROR', 5); +} + +/** + * sfYamlParser parses YAML strings to convert them to PHP arrays. + * + * @package symfony + * @subpackage yaml + * @author Fabien Potencier + * @version SVN: $Id: sfYamlParser.class.php 10832 2008-08-13 07:46:08Z fabien $ + */ +class sfYamlParser +{ + protected + $offset = 0, + $lines = array(), + $currentLineNb = -1, + $currentLine = '', + $refs = array(); + + /** + * Constructor + * + * @param integer $offset The offset of YAML document (used for line numbers in error messages) + */ + public function __construct($offset = 0) + { + $this->offset = $offset; + } + + /** + * Parses a YAML string to a PHP value. + * + * @param string $value A YAML string + * + * @return mixed A PHP value + * + * @throws InvalidArgumentException If the YAML is not valid + */ + public function parse($value) + { + $this->currentLineNb = -1; + $this->currentLine = ''; + $this->lines = explode("\n", $this->cleanup($value)); + + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) + { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('UTF-8'); + } + + $data = array(); + while ($this->moveToNextLine()) + { + if ($this->isCurrentLineEmpty()) + { + continue; + } + + // tab? + if (preg_match('#^\t+#', $this->currentLine)) + { + throw new InvalidArgumentException(sprintf('A YAML file cannot contain tabs as indentation at line %d (%s).', $this->getRealCurrentLineNb() + 1, $this->currentLine)); + } + + $isRef = $isInPlace = $isProcessed = false; + if (preg_match('#^\-((?P\s+)(?P.+?))?\s*$#u', $this->currentLine, $values)) + { + if (isset($values['value']) && preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) + { + $isRef = $matches['ref']; + $values['value'] = $matches['value']; + } + + // array + if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) + { + $c = $this->getRealCurrentLineNb() + 1; + $parser = new sfYamlParser($c); + $parser->refs =& $this->refs; + $data[] = $parser->parse($this->getNextEmbedBlock()); + } + else + { + if (isset($values['leadspaces']) + && ' ' == $values['leadspaces'] + && preg_match('#^(?P'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"\{].*?) *\:(\s+(?P.+?))?\s*$#u', $values['value'], $matches)) + { + // this is a compact notation element, add to next block and parse + $c = $this->getRealCurrentLineNb(); + $parser = new sfYamlParser($c); + $parser->refs =& $this->refs; + + $block = $values['value']; + if (!$this->isNextLineIndented()) + { + $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2); + } + + $data[] = $parser->parse($block); + } + else + { + $data[] = $this->parseValue($values['value']); + } + } + } + else if (preg_match('#^(?P'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"].*?) *\:(\s+(?P.+?))?\s*$#u', $this->currentLine, $values)) + { + $key = sfYamlInline::parseScalar($values['key']); + + if ('<<' === $key) + { + if (isset($values['value']) && '*' === substr($values['value'], 0, 1)) + { + $isInPlace = substr($values['value'], 1); + if (!array_key_exists($isInPlace, $this->refs)) + { + throw new InvalidArgumentException(sprintf('Reference "%s" does not exist at line %s (%s).', $isInPlace, $this->getRealCurrentLineNb() + 1, $this->currentLine)); + } + } + else + { + if (isset($values['value']) && $values['value'] !== '') + { + $value = $values['value']; + } + else + { + $value = $this->getNextEmbedBlock(); + } + $c = $this->getRealCurrentLineNb() + 1; + $parser = new sfYamlParser($c); + $parser->refs =& $this->refs; + $parsed = $parser->parse($value); + + $merged = array(); + if (!is_array($parsed)) + { + throw new InvalidArgumentException(sprintf("YAML merge keys used with a scalar value instead of an array at line %s (%s)", $this->getRealCurrentLineNb() + 1, $this->currentLine)); + } + else if (isset($parsed[0])) + { + // Numeric array, merge individual elements + foreach (array_reverse($parsed) as $parsedItem) + { + if (!is_array($parsedItem)) + { + throw new InvalidArgumentException(sprintf("Merge items must be arrays at line %s (%s).", $this->getRealCurrentLineNb() + 1, $parsedItem)); + } + $merged = array_merge($parsedItem, $merged); + } + } + else + { + // Associative array, merge + $merged = array_merge($merged, $parsed); + } + + $isProcessed = $merged; + } + } + else if (isset($values['value']) && preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) + { + $isRef = $matches['ref']; + $values['value'] = $matches['value']; + } + + if ($isProcessed) + { + // Merge keys + $data = $isProcessed; + } + // hash + else if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) + { + // if next line is less indented or equal, then it means that the current value is null + if ($this->isNextLineIndented()) + { + $data[$key] = null; + } + else + { + $c = $this->getRealCurrentLineNb() + 1; + $parser = new sfYamlParser($c); + $parser->refs =& $this->refs; + $data[$key] = $parser->parse($this->getNextEmbedBlock()); + } + } + else + { + if ($isInPlace) + { + $data = $this->refs[$isInPlace]; + } + else + { + $data[$key] = $this->parseValue($values['value']); + } + } + } + else + { + // 1-liner followed by newline + if (2 == count($this->lines) && empty($this->lines[1])) + { + $value = sfYamlInline::load($this->lines[0]); + if (is_array($value)) + { + $first = reset($value); + if ('*' === substr($first, 0, 1)) + { + $data = array(); + foreach ($value as $alias) + { + $data[] = $this->refs[substr($alias, 1)]; + } + $value = $data; + } + } + + if (isset($mbEncoding)) + { + mb_internal_encoding($mbEncoding); + } + + return $value; + } + + switch (preg_last_error()) + { + case PREG_INTERNAL_ERROR: + $error = 'Internal PCRE error on line'; + break; + case PREG_BACKTRACK_LIMIT_ERROR: + $error = 'pcre.backtrack_limit reached on line'; + break; + case PREG_RECURSION_LIMIT_ERROR: + $error = 'pcre.recursion_limit reached on line'; + break; + case PREG_BAD_UTF8_ERROR: + $error = 'Malformed UTF-8 data on line'; + break; + case PREG_BAD_UTF8_OFFSET_ERROR: + $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point on line'; + break; + default: + $error = 'Unable to parse line'; + } + + throw new InvalidArgumentException(sprintf('%s %d (%s).', $error, $this->getRealCurrentLineNb() + 1, $this->currentLine)); + } + + if ($isRef) + { + $this->refs[$isRef] = end($data); + } + } + + if (isset($mbEncoding)) + { + mb_internal_encoding($mbEncoding); + } + + return empty($data) ? null : $data; + } + + /** + * Returns the current line number (takes the offset into account). + * + * @return integer The current line number + */ + protected function getRealCurrentLineNb() + { + return $this->currentLineNb + $this->offset; + } + + /** + * Returns the current line indentation. + * + * @return integer The current line indentation + */ + protected function getCurrentLineIndentation() + { + return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' ')); + } + + /** + * Returns the next embed block of YAML. + * + * @param integer $indentation The indent level at which the block is to be read, or null for default + * + * @return string A YAML string + */ + protected function getNextEmbedBlock($indentation = null) + { + $this->moveToNextLine(); + + if (null === $indentation) + { + $newIndent = $this->getCurrentLineIndentation(); + + if (!$this->isCurrentLineEmpty() && 0 == $newIndent) + { + throw new InvalidArgumentException(sprintf('Indentation problem at line %d (%s)', $this->getRealCurrentLineNb() + 1, $this->currentLine)); + } + } + else + { + $newIndent = $indentation; + } + + $data = array(substr($this->currentLine, $newIndent)); + + while ($this->moveToNextLine()) + { + if ($this->isCurrentLineEmpty()) + { + if ($this->isCurrentLineBlank()) + { + $data[] = substr($this->currentLine, $newIndent); + } + + continue; + } + + $indent = $this->getCurrentLineIndentation(); + + if (preg_match('#^(?P *)$#', $this->currentLine, $match)) + { + // empty line + $data[] = $match['text']; + } + else if ($indent >= $newIndent) + { + $data[] = substr($this->currentLine, $newIndent); + } + else if (0 == $indent) + { + $this->moveToPreviousLine(); + + break; + } + else + { + throw new InvalidArgumentException(sprintf('Indentation problem at line %d (%s)', $this->getRealCurrentLineNb() + 1, $this->currentLine)); + } + } + + return implode("\n", $data); + } + + /** + * Moves the parser to the next line. + */ + protected function moveToNextLine() + { + if ($this->currentLineNb >= count($this->lines) - 1) + { + return false; + } + + $this->currentLine = $this->lines[++$this->currentLineNb]; + + return true; + } + + /** + * Moves the parser to the previous line. + */ + protected function moveToPreviousLine() + { + $this->currentLine = $this->lines[--$this->currentLineNb]; + } + + /** + * Parses a YAML value. + * + * @param string $value A YAML value + * + * @return mixed A PHP value + */ + protected function parseValue($value) + { + if ('*' === substr($value, 0, 1)) + { + if (false !== $pos = strpos($value, '#')) + { + $value = substr($value, 1, $pos - 2); + } + else + { + $value = substr($value, 1); + } + + if (!array_key_exists($value, $this->refs)) + { + throw new InvalidArgumentException(sprintf('Reference "%s" does not exist (%s).', $value, $this->currentLine)); + } + return $this->refs[$value]; + } + + if (preg_match('/^(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?$/', $value, $matches)) + { + $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; + + return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers))); + } + else + { + return sfYamlInline::load($value); + } + } + + /** + * Parses a folded scalar. + * + * @param string $separator The separator that was used to begin this folded scalar (| or >) + * @param string $indicator The indicator that was used to begin this folded scalar (+ or -) + * @param integer $indentation The indentation that was used to begin this folded scalar + * + * @return string The text value + */ + protected function parseFoldedScalar($separator, $indicator = '', $indentation = 0) + { + $separator = '|' == $separator ? "\n" : ' '; + $text = ''; + + $notEOF = $this->moveToNextLine(); + + while ($notEOF && $this->isCurrentLineBlank()) + { + $text .= "\n"; + + $notEOF = $this->moveToNextLine(); + } + + if (!$notEOF) + { + return ''; + } + + if (!preg_match('#^(?P'.($indentation ? str_repeat(' ', $indentation) : ' +').')(?P.*)$#u', $this->currentLine, $matches)) + { + $this->moveToPreviousLine(); + + return ''; + } + + $textIndent = $matches['indent']; + $previousIndent = 0; + + $text .= $matches['text'].$separator; + while ($this->currentLineNb + 1 < count($this->lines)) + { + $this->moveToNextLine(); + + if (preg_match('#^(?P {'.strlen($textIndent).',})(?P.+)$#u', $this->currentLine, $matches)) + { + if (' ' == $separator && $previousIndent != $matches['indent']) + { + $text = substr($text, 0, -1)."\n"; + } + $previousIndent = $matches['indent']; + + $text .= str_repeat(' ', $diff = strlen($matches['indent']) - strlen($textIndent)).$matches['text'].($diff ? "\n" : $separator); + } + else if (preg_match('#^(?P *)$#', $this->currentLine, $matches)) + { + $text .= preg_replace('#^ {1,'.strlen($textIndent).'}#', '', $matches['text'])."\n"; + } + else + { + $this->moveToPreviousLine(); + + break; + } + } + + if (' ' == $separator) + { + // replace last separator by a newline + $text = preg_replace('/ (\n*)$/', "\n$1", $text); + } + + switch ($indicator) + { + case '': + $text = preg_replace('#\n+$#s', "\n", $text); + break; + case '+': + break; + case '-': + $text = preg_replace('#\n+$#s', '', $text); + break; + } + + return $text; + } + + /** + * Returns true if the next line is indented. + * + * @return Boolean Returns true if the next line is indented, false otherwise + */ + protected function isNextLineIndented() + { + $currentIndentation = $this->getCurrentLineIndentation(); + $notEOF = $this->moveToNextLine(); + + while ($notEOF && $this->isCurrentLineEmpty()) + { + $notEOF = $this->moveToNextLine(); + } + + if (false === $notEOF) + { + return false; + } + + $ret = false; + if ($this->getCurrentLineIndentation() <= $currentIndentation) + { + $ret = true; + } + + $this->moveToPreviousLine(); + + return $ret; + } + + /** + * Returns true if the current line is blank or if it is a comment line. + * + * @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise + */ + protected function isCurrentLineEmpty() + { + return $this->isCurrentLineBlank() || $this->isCurrentLineComment(); + } + + /** + * Returns true if the current line is blank. + * + * @return Boolean Returns true if the current line is blank, false otherwise + */ + protected function isCurrentLineBlank() + { + return '' == trim($this->currentLine, ' '); + } + + /** + * Returns true if the current line is a comment line. + * + * @return Boolean Returns true if the current line is a comment line, false otherwise + */ + protected function isCurrentLineComment() + { + //checking explicitly the first char of the trim is faster than loops or strpos + $ltrimmedLine = ltrim($this->currentLine, ' '); + return $ltrimmedLine[0] === '#'; + } + + /** + * Cleanups a YAML string to be parsed. + * + * @param string $value The input YAML string + * + * @return string A cleaned up YAML string + */ + protected function cleanup($value) + { + $value = str_replace(array("\r\n", "\r"), "\n", $value); + + if (!preg_match("#\n$#", $value)) + { + $value .= "\n"; + } + + // strip YAML header + $count = 0; + $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#su', '', $value, -1, $count); + $this->offset += $count; + + // remove leading comments + $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count); + if ($count == 1) + { + // items have been removed, update the offset + $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); + $value = $trimmedValue; + } + + // remove start of the document marker (---) + $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count); + if ($count == 1) + { + // items have been removed, update the offset + $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); + $value = $trimmedValue; + + // remove end of the document marker (...) + $value = preg_replace('#\.\.\.\s*$#s', '', $value); + } + + return $value; + } +} diff --git a/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/package.xml b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/package.xml new file mode 100644 index 000000000..e07ea3f8b --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/package.xml @@ -0,0 +1,172 @@ + + + YAML + pear.symfony-project.com + The Symfony YAML Component. + The Symfony YAML Component. + + Fabien Potencier + fabpot + fabien.potencier@symfony-project.org + yes + + 2011-02-22 + + 1.0.6 + 1.0.0 + + + stable + stable + + MIT license + - + + + + + + + + + + + + + + + + + + 5.2.4 + + + 1.4.1 + + + + + + + + + + + + + + + + + 1.0.6 + 1.0.0 + + + stable + stable + + 2010-02-22 + MIT + + * fabien: renamed doc files to avoid collision with pecl/yaml + + + + + 1.0.5 + 1.0.0 + + + stable + stable + + 2010-02-22 + MIT + + * indiyets: fixed package.xml + + + + + 1.0.4 + 1.0.0 + + + stable + stable + + 2010-11-29 + MIT + + * fabien: fixed parsing of simple inline documents + + + + + 1.0.3 + 1.0.0 + + + stable + stable + + 2010-04-06 + MIT + + * fabien: fixed YAML parser when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII + * fabien: fixed offset when the document use --- or the %YAML element + * fabien: added ? in the list of characters that trigger quoting (for compatibility with libyaml) + * fabien: added backtick to the list of characters that trigger quotes as it is reserved for future use + * FabianLange: fixed missing newline in sfYamlParser when parsing certain symfony core files + * FabianLange: removed the unused value property from Parser + * fabien: changed Exception to InvalidArgumentException + * fabien: fixed YAML dump when a string contains a \r without a \n + + + + + 1.0.2 + 1.0.0 + + + stable + stable + + 2009-12-01 + MIT + + * fabien: fixed \ usage in quoted string + + + + + 1.0.1 + 1.0.0 + + + stable + stable + + 2009-12-01 + MIT + + * fabien: fixed a possible loop in parsing a non-valid quoted string + + + + + 1.0.0 + 1.0.0 + + + stable + stable + + 2009-11-30 + MIT + + * fabien: first stable release as a Symfony Component + + + + diff --git a/thirdparty/zend_translate_railsyaml/tests/TestHelper.php b/thirdparty/zend_translate_railsyaml/tests/TestHelper.php new file mode 100644 index 000000000..ec5e3f966 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/tests/TestHelper.php @@ -0,0 +1,88 @@ +=')) { + if (version_compare($phpunitVersion, '3.6.0', '>=')) { + echo 'This verison of PHPUnit is not supported in Zend Framework 1.x unit tests.'; + exit(1); + } + require_once 'PHPUnit/Autoload.php'; // >= PHPUnit 3.5.5 +} else { + require_once 'PHPUnit/Framework.php'; // < PHPUnit 3.5.5 +} + +/* + * Set error reporting to the level to which Zend Framework code must comply. + */ +error_reporting(E_ALL | E_STRICT); + +/* + * Determine the root, library, and tests directories of the framework + * distribution. + */ +$ds = DIRECTORY_SEPARATOR; +$zfRoot = realpath(dirname(dirname(dirname(__FILE__)))) . $ds . 'sapphire' . $ds . 'thirdparty'; +$zfCoreLibrary = "$zfRoot"; +$zfCoreTests = "$zfRoot/tests"; +$zfCustomLibrary = realpath(dirname(dirname(__FILE__))) . $ds . 'library'; + +/* + * Prepend the Zend Framework library/ and tests/ directories to the + * include_path. This allows the tests to run out of the box and helps prevent + * loading other copies of the framework code and tests that would supersede + * this copy. + */ +$path = array( + $zfCoreLibrary, + $zfCustomLibrary, + $zfCoreTests, + get_include_path() + ); +set_include_path(implode(PATH_SEPARATOR, $path)); + +// /* +// * Load the user-defined test configuration file, if it exists; otherwise, load +// * the default configuration. +// */ +// if (is_readable($zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php')) { +// require_once $zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php'; +// } else { +// require_once $zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php.dist'; +// } + +/** + * Start output buffering, if enabled + */ +if (defined('TESTS_ZEND_OB_ENABLED') && constant('TESTS_ZEND_OB_ENABLED')) { + ob_start(); +} + +/* + * Unset global variables that are no longer needed. + */ +unset($zfRoot, $zfCoreLibrary, $zfCoreTests, $path); diff --git a/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/RailsYAMLTest.php b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/RailsYAMLTest.php new file mode 100644 index 000000000..52d0bddd5 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/RailsYAMLTest.php @@ -0,0 +1,239 @@ +fail('Exception expected'); + } catch (Zend_Translate_Exception $e) { + $this->assertContains('Error opening translation file', $e->getMessage()); + } + + } + + public function testToString() + { + $adapter = $this->getDefaultAdapter(); + $this->assertEquals('RailsYaml', $adapter->toString()); + } + + public function testTranslate() + { + $adapter = $this->getDefaultAdapter(); + $this->assertEquals('Message1 (en)', $adapter->translate('Message1'), + 'Message without namespace through translate()' + ); + $this->assertEquals('Message1 (en)', $adapter->_('Message1'), + 'Message without namespace through _()' + ); + $this->assertEquals('Namespace1 Message1 (en)', $adapter->translate('Namespace1.Message1'), + 'Message with namespace' + ); + } + + public function testIsTranslated() + { + $adapter = $this->getDefaultAdapter(); + $this->assertTrue($adapter->isTranslated('Message1')); + $this->assertFalse($adapter->isTranslated('NonExistent')); + $this->assertTrue($adapter->isTranslated('Message1', true)); + $this->assertFalse($adapter->isTranslated('Message1', true, 'en_US')); + $this->assertTrue($adapter->isTranslated('Message1', false, 'en_US')); + $this->assertFalse($adapter->isTranslated('Message1', false, 'es')); + $this->assertFalse($adapter->isTranslated('Message1', 'es')); + $this->assertFalse($adapter->isTranslated('Message1', 'xx_XX')); + $this->assertTrue($adapter->isTranslated('Message1', 'en_XX')); + } + + public function testLoadTranslationData() + { + $adapter = $this->getDefaultAdapter(); + $this->assertEquals('Message1 (en)', $adapter->translate('Message1')); + $this->assertEquals('Message2', $adapter->translate('Message2', 'ru')); + $this->assertEquals('Message1', $adapter->translate('Message1', 'xx')); + $this->assertEquals('Message1 (en)', $adapter->translate('Message1', 'en_US')); + + try { + $adapter->addTranslation(dirname(__FILE__) . '/_files/translation_en.yml', 'xx'); + $this->fail("exception expected"); + } catch (Zend_Translate_Exception $e) { + $this->assertContains('does not exist', $e->getMessage()); + } + + $adapter->addTranslation(dirname(__FILE__) . '/_files/translation_de.yml', 'de', array('clear' => true)); + $this->assertEquals('Message1 (de)', $adapter->translate('Message1')); + } + + public function testOptions() + { + $adapter = $this->getDefaultAdapter(); + $adapter->setOptions(array('testoption' => 'testkey')); + $expected = array( + 'testoption' => 'testkey', + 'clear' => false, + 'content' => dirname(__FILE__) . '/_files/translation_en.yml', + 'scan' => null, + 'locale' => 'en', + 'ignore' => '.', + // 'disableNotices' => false, + 'log' => false, + 'logMessage' => 'Untranslated message within \'%locale%\': %message%', + 'logUntranslated' => false, + 'reload' => false, + ); + + $options = $adapter->getOptions(); + + foreach ($expected as $key => $value) { + $this->assertArrayHasKey($key, $options); + $this->assertEquals($value, $options[$key], $key); + } + + $this->assertEquals('testkey', $adapter->getOptions('testoption')); + $this->assertTrue(is_null($adapter->getOptions('nooption'))); + } + + public function testClearing() + { + $adapter = $this->getDefaultAdapter(); + $this->assertEquals('Message1 (en)', $adapter->translate('Message1')); + $adapter->addTranslation(dirname(__FILE__) . '/_files/translation_de.yml', 'de', array('clear' => true)); + $this->assertEquals('Message1 (de)', $adapter->translate('Message1')); + $this->assertEquals('Message4', $adapter->translate('Message4')); + } + + public function testCaching() + { + require_once 'Zend/Cache.php'; + $cache = Zend_Cache::factory('Core', 'File', + array('lifetime' => 120, 'automatic_serialization' => true), + array('cache_dir' => dirname(__FILE__) . '/_files/')); + + $this->assertFalse(Translate_Adapter_RailsYAML::hasCache()); + Translate_Adapter_RailsYAML::setCache($cache); + $this->assertTrue(Translate_Adapter_RailsYAML::hasCache()); + + $adapter = $this->getDefaultAdapter(); + $cache = Translate_Adapter_RailsYAML::getCache(); + $this->assertTrue($cache instanceof Zend_Cache_Core); + unset ($adapter); + + $adapter = $this->getDefaultAdapter(); + $cache = Translate_Adapter_RailsYAML::getCache(); + $this->assertTrue($cache instanceof Zend_Cache_Core); + + Translate_Adapter_RailsYAML::removeCache(); + $this->assertFalse(Translate_Adapter_RailsYAML::hasCache()); + + $cache->save('testdata', 'testid'); + Translate_Adapter_RailsYAML::setCache($cache); + $adapter = $this->getDefaultAdapter(); + Translate_Adapter_RailsYAML::removeCache(); + $temp = $cache->load('testid'); + $this->assertEquals('testdata', $temp); + } + + public function testLoadingFilesIntoCacheAfterwards() + { + require_once 'Zend/Cache.php'; + $cache = Zend_Cache::factory('Core', 'File', + array('lifetime' => 120, 'automatic_serialization' => true), + array('cache_dir' => dirname(__FILE__) . '/_files/')); + + $this->assertFalse(Translate_Adapter_RailsYAML::hasCache()); + Translate_Adapter_RailsYAML::setCache($cache); + $this->assertTrue(Translate_Adapter_RailsYAML::hasCache()); + + $adapter = $this->getDefaultAdapter(); + $cache = Translate_Adapter_RailsYAML::getCache(); + $this->assertTrue($cache instanceof Zend_Cache_Core); + + $adapter->addTranslation(dirname(__FILE__) . '/_files/translation_de.yml', 'de', array('reload' => true)); + $test = $adapter->getMessages('all'); + $this->assertEquals(4, count($test['de'])); + } + + /** + * Ignores a raised PHP error when in effect, but throws a flag to indicate an error occurred + * + * @param integer $errno + * @param string $errstr + * @param string $errfile + * @param integer $errline + * @param array $errcontext + * @return void + */ + public function errorHandlerIgnore($errno, $errstr, $errfile, $errline, array $errcontext) + { + $this->_errorOccurred = true; + } + + /** + * @return Translate_Adapter_RailsYAML + */ + protected function getDefaultAdapter() + { + return new Translate_Adapter_RailsYAML( + dirname(__FILE__) . '/_files/translation_en.yml', + 'en', + array('disableNotices' => true) + ); + } +} + +// Call Translate_Adapter_RailsYAMLTest::main() if this source file is executed directly. +if (PHPUnit_MAIN_METHOD == "Translate_Adapter_RailsYAMLTest::main") { + Translate_Adapter_RailsYAMLTest::main(); +} diff --git a/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/_files/translation_de.yml b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/_files/translation_de.yml new file mode 100644 index 000000000..612608567 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/_files/translation_de.yml @@ -0,0 +1,6 @@ +de: + Message1: Message1 (de) + Message2: Message2 (de) + Namespace1: + Message1: Namespace1 Message2 (de) + Namespace1Message1: Namespace1 Message2 (de) \ No newline at end of file diff --git a/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/_files/translation_en.yml b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/_files/translation_en.yml new file mode 100644 index 000000000..f36c1ef88 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/_files/translation_en.yml @@ -0,0 +1,9 @@ +en: + Message1: Message1 (en) + Message2: Message2 (en) + Namespace1: + Message1: Namespace1 Message1 (en) + Namespace1Message1: Namespace1 Message2 (en) + Namespace2: + Message1: Namespace2 Message1 (en) + Namespace2Message2: Namespace2 Message2 (en) \ No newline at end of file diff --git a/thirdparty/zend_translate_railsyaml/tests/phpunit.xml b/thirdparty/zend_translate_railsyaml/tests/phpunit.xml new file mode 100644 index 000000000..10aad0b99 --- /dev/null +++ b/thirdparty/zend_translate_railsyaml/tests/phpunit.xml @@ -0,0 +1,5 @@ + + + ./ + +