From 0d03380e3bada92dc971a4d46c64d2cbae636f95 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 8 Jul 2012 18:05:32 +0200 Subject: [PATCH 001/127] Native string adapter don't need ext/mbstring --- src/StringAdapter/Iconv.php | 5 +++++ src/StringAdapter/MbString.php | 5 +++++ src/StringAdapter/Native.php | 9 --------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/StringAdapter/Iconv.php b/src/StringAdapter/Iconv.php index 896bd210a..314e67115 100644 --- a/src/StringAdapter/Iconv.php +++ b/src/StringAdapter/Iconv.php @@ -15,6 +15,11 @@ class Iconv extends AbstractStringAdapter 'UTF-8', // TODO ); + /** + * Constructor + * + * @throws Exception\ExtensionNotLoadedException + */ public function __construct() { if (!extension_loaded('iconv')) { diff --git a/src/StringAdapter/MbString.php b/src/StringAdapter/MbString.php index e3432530f..2e1566801 100644 --- a/src/StringAdapter/MbString.php +++ b/src/StringAdapter/MbString.php @@ -17,6 +17,11 @@ class MbString extends AbstractStringAdapter 'UTF-8', // TODO ); + /** + * Constructor + * + * @throws Exception\ExtensionNotLoadedException + */ public function __construct() { if (!extension_loaded('mbstring')) { diff --git a/src/StringAdapter/Native.php b/src/StringAdapter/Native.php index fa5f940db..32707abe3 100644 --- a/src/StringAdapter/Native.php +++ b/src/StringAdapter/Native.php @@ -20,15 +20,6 @@ class Native extends AbstractStringAdapter 'UCS-4', 'UCS-4BE', 'UCS-4LE', ); - public function __construct() - { - if (!extension_loaded('mbstring')) { - throw new Exception\ExtensionNotLoadedException( - 'PHP extension "mbstring" is required for this adapter' - ); - } - } - public function isCharsetSupported($charset) { $charset = strtoupper($charset); From 9bce95a459b0b5c58c7ad9bef53662cc9f83c9ba Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 8 Jul 2012 22:09:09 +0200 Subject: [PATCH 002/127] StringUtils: tests, no component deps --- src/StringAdapter/AbstractStringAdapter.php | 18 ++++ src/StringAdapter/Iconv.php | 6 -- src/StringAdapter/MbString.php | 6 -- src/StringAdapter/Native.php | 6 -- src/StringAdapter/StringAdapterInterface.php | 2 + src/StringUtils.php | 40 ++++---- test/StringUtilsTest.php | 96 ++++++++++++++++++++ 7 files changed, 138 insertions(+), 36 deletions(-) create mode 100644 test/StringUtilsTest.php diff --git a/src/StringAdapter/AbstractStringAdapter.php b/src/StringAdapter/AbstractStringAdapter.php index a0a01a935..01987b0f4 100644 --- a/src/StringAdapter/AbstractStringAdapter.php +++ b/src/StringAdapter/AbstractStringAdapter.php @@ -5,6 +5,24 @@ abstract class AbstractStringAdapter implements StringAdapterInterface { + /** + * List of supported character sets (upper case) + * + * @var string[] + */ + protected static $charsets = array(); + + public function isCharsetSupported($charset) + { + $charset = strtoupper($charset); + return in_array($charset, static::$charsets); + } + + public function getSupportedCharsets() + { + return static::$charsets; + } + /** * Word wrap * diff --git a/src/StringAdapter/Iconv.php b/src/StringAdapter/Iconv.php index 314e67115..3baf002c0 100644 --- a/src/StringAdapter/Iconv.php +++ b/src/StringAdapter/Iconv.php @@ -29,12 +29,6 @@ public function __construct() } } - public function isCharsetSupported($charset) - { - $charset = strtoupper($charset); - return in_array($charset, static::$charsets); - } - public function strlen($str, $charset = 'UTF-8') { return iconv_strlen($str, $charset); diff --git a/src/StringAdapter/MbString.php b/src/StringAdapter/MbString.php index 2e1566801..54036733b 100644 --- a/src/StringAdapter/MbString.php +++ b/src/StringAdapter/MbString.php @@ -31,12 +31,6 @@ public function __construct() } } - public function isCharsetSupported($charset) - { - $charset = strtoupper($charset); - return in_array($charset, static::$charsets); - } - public function strlen($str, $charset = 'UTF-8') { return mb_strlen($str, $charset); diff --git a/src/StringAdapter/Native.php b/src/StringAdapter/Native.php index 32707abe3..d4efbe1f3 100644 --- a/src/StringAdapter/Native.php +++ b/src/StringAdapter/Native.php @@ -20,12 +20,6 @@ class Native extends AbstractStringAdapter 'UCS-4', 'UCS-4BE', 'UCS-4LE', ); - public function isCharsetSupported($charset) - { - $charset = strtoupper($charset); - return in_array($charset, static::$charsets); - } - public function strlen($str, $charset = 'UTF-8') { if (StringUtils::isSingleByteCharset($charset)) { diff --git a/src/StringAdapter/StringAdapterInterface.php b/src/StringAdapter/StringAdapterInterface.php index 4b15ef5df..7b8c30efc 100644 --- a/src/StringAdapter/StringAdapterInterface.php +++ b/src/StringAdapter/StringAdapterInterface.php @@ -7,6 +7,8 @@ interface StringAdapterInterface public function isCharsetSupported($charset); + public function getSupportedCharsets(); + public function strlen($str, $charset = 'UTF-8'); public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8'); diff --git a/src/StringUtils.php b/src/StringUtils.php index a10f0ef9d..10d71a49b 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -4,6 +4,7 @@ use Zend\Loader\Broker, Zend\Loader\PluginBroker, + Zend\Stdlib\StringAdapter\StringAdapterInterface, Zend\Stdlib\StringAdapter\MbString as MbStringAdapter, Zend\Stdlib\StringAdapter\Iconv as IconvAdapter, Zend\Stdlib\StringAdapter\Native as NativeAdapter; @@ -11,7 +12,7 @@ class StringUtils { - protected static $broker; + protected static $adapterRegistry; protected static $singleByteCharsets = array( 'ASCII', '7BIT', '8BIT', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', @@ -23,44 +24,47 @@ class StringUtils ); /** - * Get broker + * Get registered string adapters * - * @return Zend\Loader\Broker + * @return Zend\Stdlib\StringAdapter\StringAdapterInterface[] */ - public static function getBroker() + public static function getRegisteredAdapters() { - if (static::$broker === null) { - $broker = new PluginBroker(); + if (static::$adapterRegistry === null) { + static::$adapterRegistry = array(); if (extension_loaded('mbstring')) { - $broker->register('mbstring', new MbStringAdapter()); + static::$adapterRegistry[] = new MbStringAdapter(); } if (extension_loaded('iconv')) { - $broker->register('iconv', new IconvAdapter()); + static::$adapterRegistry[] = new IconvAdapter(); } - $broker->register('native', new NativeAdapter()); - - static::setBroker($broker); + static::$adapterRegistry[] = new NativeAdapter(); } - return static::$broker; + + return static::$adapterRegistry; } - public static function setBroker(Broker $broker) + public static function registerAdapter(StringAdapterInterface $adapter) { - static::$broker = $broker; + if (!in_array($adapter, static::$adapterRegistry, true)) { + static::$adapterRegistry[] = $adapter; + } } - public static function resetBroker() + public static function unregisterAdapter(StringAdapterInterface $adapter) { - static::$broker = null; + $index = array_search($adapter, static::$adapterRegistry, true); + if ($index !== false) { + unset(static::$adapterRegistry[$index]); + } } public static function getAdapterByCharset($charset = 'UTF-8') { - $broker = static::getBroker(); - foreach ($broker->getPlugins() as $adapter) { + foreach (static::getRegisteredAdapters() as $adapter) { if ($adapter->isCharsetSupported($charset)) { return $adapter; } diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php new file mode 100644 index 000000000..63c84d2f0 --- /dev/null +++ b/test/StringUtilsTest.php @@ -0,0 +1,96 @@ +bufferedAdapters = StringUtils::getRegisteredAdapters(); + } + + public function tearDown() + { + // reset registered adapters + foreach (StringUtils::getRegisteredAdapters() as $adapter) { + StringUtils::unregisterAdapter($adapter); + } + foreach ($this->bufferedAdapters as $adapter) { + StringUtils::registerAdapter($adapter); + } + + } + + public function singleByCharsets() + { + return array( + array('AscII'), + array('ISo-8859-1'), + ); + } + + public function nonSingleByteCharsets() + { + return array( + array('UTf-8'), + array('usC-2') + ); + } + + /** + * @dataProvider singleByCharsets + * @param string $charset + */ + public function testIsSingleByteCharsetReturnsTrue($charset) + { + $this->assertTrue(StringUtils::isSingleByteCharset($charset)); + } + + /** + * @dataProvider nonSingleByteCharsets + * @param string $charset + */ + public function testIsSingleByteCharsetReturnsFalse($charset) + { + $this->assertFalse(StringUtils::isSingleByteCharset($charset)); + } + + public function testGetAdapterByCharset() + { + $adapter = StringUtils::getAdapterByCharset('UTF-8'); + + if (extension_loaded('mbstring')) { + $this->assertInstanceOf('Zend\Stdlib\StringAdapter\MbString', $adapter); + } elseif (extension_loaded('iconv')) { + $this->assertInstanceOf('Zend\Stdlib\StringAdapter\Iconv', $adapter); + } else { + $this->assertInstanceOf('Zend\Stdlib\StringAdapter\Native', $adapter); + } + } +} From d66f8a899196dc82577bdd0bfcaddfd57cfe6b19 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Fri, 13 Jul 2012 08:39:35 +0200 Subject: [PATCH 003/127] intl string wrapper and some small other changes --- src/Exception/ExtensionNotLoadedException.php | 7 + src/Exception/RuntimeException.php | 7 + src/StringUtils.php | 27 +++- src/StringWrapper/AbstractStringWrapper.php | 6 +- src/StringWrapper/Iconv.php | 8 +- src/StringWrapper/Intl.php | 68 +++++++++ src/StringWrapper/MbString.php | 8 +- src/StringWrapper/Native.php | 141 +----------------- test/StringUtilsTest.php | 35 ++++- 9 files changed, 161 insertions(+), 146 deletions(-) create mode 100644 src/Exception/ExtensionNotLoadedException.php create mode 100644 src/Exception/RuntimeException.php create mode 100644 src/StringWrapper/Intl.php diff --git a/src/Exception/ExtensionNotLoadedException.php b/src/Exception/ExtensionNotLoadedException.php new file mode 100644 index 000000000..40ceaf4ee --- /dev/null +++ b/src/Exception/ExtensionNotLoadedException.php @@ -0,0 +1,7 @@ +isCharsetSupported($charset)) { - return $wrapper; + foreach ($charsets as $charset) { + if (!$wrapper->isCharsetSupported($charset)) { + continue 2; + } } + + return $wrapper; } - throw new Exception\RuntimeException("No wrapper found for charset '{$charset}'"); + throw new Exception\RuntimeException('No wrapper found supporting charset(s) ' . implode(', ', $charsets)); + } + + public static function getSingleByteCharsets() + { + return static::$singleByteCharsets; } public static function isSingleByteCharset($charset) { return in_array(strtoupper($charset), static::$singleByteCharsets); } + + public static function isValidUtf8($string) + { + return ($string === '' || preg_match('/^./su', $string) == 1); + } } diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index d3dda48a3..8394385a3 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -10,17 +10,17 @@ abstract class AbstractStringWrapper implements StringWrapperInterface * * @var string[] */ - protected static $charsets = array(); + protected $charsets = array(); public function isCharsetSupported($charset) { $charset = strtoupper($charset); - return in_array($charset, static::$charsets); + return in_array($charset, $this->charsets); } public function getSupportedCharsets() { - return static::$charsets; + return $this->$charsets; } /** diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 625285c18..4c99be628 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -11,7 +11,11 @@ class Iconv extends AbstractStringWrapper * @var string[] * @link http://php.net/manual/mbstring.supported-encodings.php */ - protected static $charsets = array( + protected $charsets = array( + 'ASCII', '7BIT', '8BIT', + 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', + 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', + 'ISO-8859-11', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', 'UTF-8', // TODO ); @@ -24,7 +28,7 @@ public function __construct() { if (!extension_loaded('iconv')) { throw new Exception\ExtensionNotLoadedException( - 'PHP extension "iconv" is required for this adapter' + 'PHP extension "iconv" is required for this wrapper' ); } } diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php new file mode 100644 index 000000000..4a631f0b8 --- /dev/null +++ b/src/StringWrapper/Intl.php @@ -0,0 +1,68 @@ +charsets = StringUtils::getSingleByteCharsets(); + } public function strlen($str, $charset = 'UTF-8') { - if (StringUtils::isSingleByteCharset($charset)) { - return strlen($str); - } - - $charset = strtoupper($charset); - if ($charset == 'UTF-8') { - // replace multibyte characters with 1 byte and count bytes - return strlen(preg_replace('/(' - . '[\xc0-\xdf][\x80-\xbf]' // 2 bytes (110xxxxx 10xxxxxx) - . '|[\xe0-\xef][\x80-\xbf]{2}' // 3 bytes (1110xxxx [10xxxxxx, ...]) - . '|[\xf0-\xf7][\x80-\xbf]{3}' // 4 bytes (11110xxx [10xxxxxx, ...]) - . '|[\xf8-\xfb][\x80-\xbf]{4}' // 5 bytes (111110xx [10xxxxxx, ...]) - . '|[\xfd-\xfe][\x80-\xbf]{5}' // 6 bytes (1111110x [10xxxxxx, ...]) - . '|\xfe[\x80-\xbf]{6}' // 7 bytes (11111110 [10xxxxxx, ...]) - . ')/s', ' ', $str)); - } elseif ($charset == 'UTF-7') { - // TODO - } elseif ($charset == 'UTF-16' || $charset == 'UCS-2' || $charset == 'UCS-2BE' || $charset == 'UCS-2LE') { - return ceil(strlen($str) / 2); - } elseif ($charset == 'UTF-32' || $charset == 'UCS-4' || $charset == 'UCS-4BE' || $charset == 'UCS-4LE') { - return ceil(strlen($str) / 4); - } - - return false; + return strlen($str); } public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') { - if (StringUtils::isSingleByteCharset($charset)) { - return substr($str, $offset, $length); - } - - $charset = strtoupper($charset); - if ($charset == 'UTF-8') { - // TODO - } elseif ($charset == 'UTF-7') { - // TODO - } elseif ($charset == 'UTF-16' || $charset == 'UCS-2') { - return substr($str, $offset * 2, $length * 2); - } elseif ($charset == 'UTF-32' || $charset == 'UCS-4') { - return substr($str, $offset * 4, $length * 4); - } - - return false; + return substr($str, $offset, $length); } public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') { - if (StringUtils::isSingleByteCharset($charset)) { - return strpos($haystack, $needle, $offset); - } - - $charset = strtoupper($charset); - if ($charset == 'UTF-8') { - // TODO - } elseif ($charset == 'UTF-7') { - // TODO - } elseif ($charset == 'UTF-16' || $charset == 'UCS-2') { - // TODO - } elseif ($charset == 'UTF-32' || $charset == 'UCS-4') { - // TODO - } - - return false; + return strpos($haystack, $needle, $offset); } public function convert($str, $toCharset, $fromCharset = 'UTF-8') { - $fromName = str_replace('-', '', strtolower($fromCharset)); - $toName = str_replace('-', '', strtolower($toCharset)); - $method = 'convert' . $fromName . 'To' . $toName; - - if (method_exists($this, $method)) { - return $this->$method($str); - } - return false; } - - public function convertAsciiToUtf8($str) - { - return $str; - } - - public function convertAsciiToUtf16($str) - { - return preg_replace_callback("/./", function ($char) { - return "\0" . $char; - }, $str); - } - - public function convertAsciiToUcs2($str) - { - return $this->convertAsciiToUtf16($str); - } - - public function convertAsciiToUtf32($str) - { - return preg_replace_callback("/./", function ($char) { - return "\0\0\0" . $char; - }, $str); - } - - public function convertAsciiToUcs4($str) - { - return $this->convertAsciiToUtf32($str); - } - - public function convertUtf8ToAscii($str) - { - // TODO - return $str; - } - - public function convertUtf8ToUtf16($str) - { - // TODO - return $str; - } - - public function convertUtf8ToUcs2($str) - { - return $this->convertUtf8ToUtf16($str); - } - - public function convertUtf8ToUtf32($str) - { - // TODO - return $str; - } - - public function convertUtf8ToUcs4($str) - { - return $this->convertUtf8ToUtf32($str); - } } diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php index b351aec9a..c38e6f221 100644 --- a/test/StringUtilsTest.php +++ b/test/StringUtilsTest.php @@ -83,8 +83,7 @@ public function testIsSingleByteCharsetReturnsFalse($charset) public function testGetWrapper() { - $wrapper = StringUtils::getWrapper('UTF-8'); - + $wrapper = StringUtils::getWrapper('ISO-8859-1'); if (extension_loaded('mbstring')) { $this->assertInstanceOf('Zend\Stdlib\StringWrapper\MbString', $wrapper); } elseif (extension_loaded('iconv')) { @@ -92,5 +91,37 @@ public function testGetWrapper() } else { $this->assertInstanceOf('Zend\Stdlib\StringWrapper\Native', $wrapper); } + + try { + $wrapper = StringUtils::getWrapper('UTF-8'); + if (extension_loaded('intl')) { + $this->assertInstanceOf('Zend\Stdlib\StringWrapper\Intl', $wrapper); + } elseif (extension_loaded('mbstring')) { + $this->assertInstanceOf('Zend\Stdlib\StringWrapper\MbString', $wrapper); + } elseif (extension_loaded('iconv')) { + $this->assertInstanceOf('Zend\Stdlib\StringWrapper\Iconv', $wrapper); + } + } catch (Exception $e) { + if (extension_loaded('intl') + || extension_loaded('mbstring') + || extension_loaded('iconv') + ) { + $this->fail("Failed to get intl, mbstring or iconv wrapper for UTF-8"); + } + } + + try { + $wrapper = StringUtils::getWrapper('UTF-8', 'ISO-8859-1'); + if (extension_loaded('mbstring')) { + $this->assertInstanceOf('Zend\Stdlib\StringWrapper\MbString', $wrapper); + } elseif (extension_loaded('iconv')) { + $this->assertInstanceOf('Zend\Stdlib\StringWrapper\Iconv', $wrapper); + } + } catch (Exception $e) { + if (extension_loaded('mbstring') || extension_loaded('iconv') + ) { + $this->fail("Failed to get mbstring or iconv wrapper for UTF-8 and ISO-8859-1"); + } + } } } From daddc6aa5488cacf072aa03fcb3dd8e53be2460e Mon Sep 17 00:00:00 2001 From: blanchonvincent Date: Tue, 7 Aug 2012 20:31:54 +0200 Subject: [PATCH 004/127] Add hydrator strategy Add hydrator strategy with serializer --- .../Strategy/SerializableStrategy.php | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/Hydrator/Strategy/SerializableStrategy.php diff --git a/src/Hydrator/Strategy/SerializableStrategy.php b/src/Hydrator/Strategy/SerializableStrategy.php new file mode 100644 index 000000000..31804fb03 --- /dev/null +++ b/src/Hydrator/Strategy/SerializableStrategy.php @@ -0,0 +1,128 @@ +setSerializer($serializer); + if($serializerOptions) { + $this->setSerializerOptions($serializerOptions); + } + } + + /** + * Serialize the given value so that it can be extracted by the hydrator. + * + * @param mixed $value The original value. + * @return mixed Returns the value that should be extracted. + */ + public function extract($value) + { + $serializer = $this->getSerializer(); + return $serializer->serialize($value); + } + + /** + * Unserialize the given value so that it can be hydrated by the hydrator. + * + * @param mixed $value The original value. + * @return mixed Returns the value that should be hydrated. + */ + public function hydrate($value) + { + $serializer = $this->getSerializer(); + return $serializer->unserialize($value); + } + + /** + * Set serializer + * + * @param string|SerializerAdapter $serializer + * @return Serializer + */ + public function setSerializer($serializer) + { + if (!is_string($serializer) && !$serializer instanceof SerializerAdapter) { + throw new InvalidArgumentException(sprintf( + '%s expects either a string serializer name or Zend\Serializer\Adapter\AdapterInterface instance; ' + . 'received "%s"', + __METHOD__, + (is_object($serializer) ? get_class($serializer) : gettype($serializer)) + )); + } + $this->serializer = $serializer; + return $this; + } + + /** + * Get serializer + * + * @return SerializerAdapter + */ + public function getSerializer() + { + if (is_string($this->serializer)) { + $options = $this->getSerializerOptions(); + $this->setSerializer(SerializerFactory::factory($this->serializer, $options)); + } elseif (null === $this->serializer) { + $this->setSerializer(SerializerFactory::getDefaultAdapter()); + } + + return $this->serializer; + } + + /** + * Set configuration options for instantiating a serializer adapter + * + * @param mixed $serializerOptions + * @return SerializableStrategy + */ + public function setSerializerOptions($serializerOptions) + { + $this->serializerOptions = $serializerOptions; + return $this; + } + + /** + * Get configuration options for instantiating a serializer adapter + * + * @return mixed + */ + public function getSerializerOptions() + { + return $this->serializerOptions; + } +} From f43755f1a44ccbe4f9105ac3f2a1cfe1e392c655 Mon Sep 17 00:00:00 2001 From: blanchonvincent Date: Tue, 7 Aug 2012 20:32:51 +0200 Subject: [PATCH 005/127] Add unit tests for wildcard Add unit tests for wirldcard --- test/HydratorTest.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 10fae389e..34365083a 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -16,6 +16,8 @@ use ZendTest\Stdlib\TestAsset\ClassMethodsUnderscore; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCaseMissing; use ZendTest\Stdlib\TestAsset\Reflection as ReflectionAsset; +use Zend\Stdlib\Hydrator\Strategy\DefaultStrategy; +use Zend\Stdlib\Hydrator\Strategy\SerializableStrategy; /** * @category Zend @@ -146,4 +148,37 @@ public function testHydratorClassMethodsDefaultBehaviorIsConvertUnderscoreToCame $this->assertEquals($test->getFooBar(), 'foo'); $this->assertEquals($test->getFooBarBaz(), 'bar'); } + + public function testRetrieveWildStrategyAndOther() + { + $hydrator = new ClassMethods(); + $hydrator->addStrategy('default', new DefaultStrategy()); + $hydrator->addStrategy('*', new SerializableStrategy('phpserialize')); + $default = $hydrator->getStrategy('default'); + $this->assertEquals(get_class($default), 'Zend\Stdlib\Hydrator\Strategy\DefaultStrategy'); + $serializable = $hydrator->getStrategy('*'); + $this->assertEquals(get_class($serializable), 'Zend\Stdlib\Hydrator\Strategy\SerializableStrategy'); + } + + public function testUseWildStrategyByDefault() + { + $hydrator = new ClassMethods(); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], '1'); + $hydrator->addStrategy('*', new SerializableStrategy('phpserialize')); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], 's:1:"1";'); + } + + public function testUseWildStrategyAndOther() + { + $hydrator = new ClassMethods(); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], '1'); + $hydrator->addStrategy('foo_bar', new DefaultStrategy()); + $hydrator->addStrategy('*', new SerializableStrategy('phpserialize')); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], '1'); + $this->assertEquals($datas['foo_bar_baz'], 's:1:"2";'); + } } From 143f41a49099f28d167bc121a9b097aac3e8be4a Mon Sep 17 00:00:00 2001 From: blanchonvincent Date: Tue, 7 Aug 2012 20:33:58 +0200 Subject: [PATCH 006/127] Add unit tests for serializable strategy Add unit tests for serializable strategy --- test/Strategy/SerializableStrategyTest.php | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/Strategy/SerializableStrategyTest.php diff --git a/test/Strategy/SerializableStrategyTest.php b/test/Strategy/SerializableStrategyTest.php new file mode 100644 index 000000000..1bd88c774 --- /dev/null +++ b/test/Strategy/SerializableStrategyTest.php @@ -0,0 +1,53 @@ +setExpectedException('Zend\Stdlib\Exception\InvalidArgumentException'); + $serializerStrategy = new SerializableStrategy(false); + } + + public function testUseBadSerilizerObject() + { + $serializer = Serializer::factory('phpserialize'); + $serializerStrategy = new SerializableStrategy($serializer); + $this->assertEquals($serializer, $serializerStrategy->getSerializer()); + } + + public function testUseBadSerilizerString() + { + $serializerStrategy = new SerializableStrategy('phpserialize'); + $this->assertEquals('Zend\Serializer\Adapter\PhpSerialize', get_class($serializerStrategy->getSerializer())); + } + + public function testCanSerialize() + { + $serializer = Serializer::factory('phpserialize'); + $serializerStrategy = new SerializableStrategy($serializer); + $serialized = $serializerStrategy->extract('foo'); + $this->assertEquals($serialized, 's:3:"foo";'); + } + + public function testCanUnserialize() + { + $serializer = Serializer::factory('phpserialize'); + $serializerStrategy = new SerializableStrategy($serializer); + $serialized = $serializerStrategy->hydrate('s:3:"foo";'); + $this->assertEquals($serialized, 'foo'); + } +} \ No newline at end of file From d5aec0df01200df2dad6c6cb9a9c506519eba9ee Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 14 Sep 2012 16:26:34 -0500 Subject: [PATCH 007/127] [zendframework/zf2#2125] CS fixes - Trailing whitespace --- src/Hydrator/AbstractHydrator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hydrator/AbstractHydrator.php b/src/Hydrator/AbstractHydrator.php index 44e77ba0d..8c8e94a9a 100644 --- a/src/Hydrator/AbstractHydrator.php +++ b/src/Hydrator/AbstractHydrator.php @@ -58,7 +58,7 @@ public function getStrategy($name) */ public function hasStrategy($name) { - return array_key_exists($name, $this->strategies) + return array_key_exists($name, $this->strategies) || array_key_exists('*', $this->strategies); } From 23e59eeb73569a2b20fa933f1bdd393793dc195c Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 14 Sep 2012 16:29:40 -0500 Subject: [PATCH 008/127] [zendframework/zf2#2125] Ensure we have a wildcard strategy before attempting to return it --- src/Hydrator/AbstractHydrator.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Hydrator/AbstractHydrator.php b/src/Hydrator/AbstractHydrator.php index 8c8e94a9a..35e811713 100644 --- a/src/Hydrator/AbstractHydrator.php +++ b/src/Hydrator/AbstractHydrator.php @@ -11,6 +11,7 @@ namespace Zend\Stdlib\Hydrator; use ArrayObject; +use Zend\Stdlib\Exception; use Zend\Stdlib\Hydrator\StrategyEnabledInterface; use Zend\Stdlib\Hydrator\Strategy\StrategyInterface; @@ -44,9 +45,18 @@ public function __construct() */ public function getStrategy($name) { - if(isset($this->strategies[$name])) { + if (isset($this->strategies[$name])) { return $this->strategies[$name]; } + + if (!isset($this->strategies['*'])) { + throw new Exception\InvalidArgumentException(sprintf( + '%s: no strategy by name of "%s", and no wildcard strategy present', + __METHOD__, + $name + )); + } + return $this->strategies['*']; } @@ -59,7 +69,7 @@ public function getStrategy($name) public function hasStrategy($name) { return array_key_exists($name, $this->strategies) - || array_key_exists('*', $this->strategies); + || array_key_exists('*', $this->strategies); } /** From 86deb2f3d1f1c68ad064bbe80904c58738bff67c Mon Sep 17 00:00:00 2001 From: bullfrogblues Date: Sat, 29 Sep 2012 22:00:26 +0100 Subject: [PATCH 009/127] Refactor; short-circuit if array given, no need to check if traversable too --- src/AbstractOptions.php | 17 ++++++++--------- test/OptionsTest.php | 9 +++++++-- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/AbstractOptions.php b/src/AbstractOptions.php index b5d7be77f..628570a59 100644 --- a/src/AbstractOptions.php +++ b/src/AbstractOptions.php @@ -28,8 +28,6 @@ abstract class AbstractOptions implements ParameterObjectInterface /** * @param array|Traversable|null $options - * @return AbstractOptions - * @throws Exception\InvalidArgumentException */ public function __construct($options = null) { @@ -108,14 +106,15 @@ public function __set($key, $value) public function __get($key) { $getter = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); - if (!method_exists($this, $getter)) { - throw new Exception\BadMethodCallException( - 'The option "' . $key . '" does not ' - . 'have a matching ' . $getter . ' getter method ' - . 'which must be defined' - ); + if (method_exists($this, $getter)) { + return $this->{$getter}(); } - return $this->{$getter}(); + + throw new Exception\BadMethodCallException( + 'The option "' . $key . '" does not ' + . 'have a matching ' . $getter . ' getter method ' + . 'which must be defined' + ); } /** diff --git a/test/OptionsTest.php b/test/OptionsTest.php index b41bf86bb..8b64e7715 100644 --- a/test/OptionsTest.php +++ b/test/OptionsTest.php @@ -13,7 +13,6 @@ use ArrayObject; use ZendTest\Stdlib\TestAsset\TestOptions; use ZendTest\Stdlib\TestAsset\TestOptionsNoStrict; -use ZendTest\Stdlib\TestAsset\TestTraversable; use Zend\Stdlib\Exception\InvalidArgumentException; class OptionsTest extends \PHPUnit_Framework_TestCase @@ -48,7 +47,6 @@ public function testNonStrictOptionsDoesNotThrowException() } } - public function testConstructionWithNull() { try { @@ -73,4 +71,11 @@ public function testUnsetThrowsInvalidArgumentException() $options = new TestOptions; unset($options->foobarField); } + + public function testGetThrowsBadMethodCallException() + { + $this->setExpectedException('BadMethodCallException'); + $options = new TestOptions(); + $options->fieldFoobar; + } } From 533337b7622a04b06c73041af6bfb89fa89f896b Mon Sep 17 00:00:00 2001 From: bullfrogblues Date: Sat, 29 Sep 2012 22:11:21 +0100 Subject: [PATCH 010/127] Make setFromArray() a fluent interface & refactor: short-circuit if array --- src/AbstractOptions.php | 19 ++++++++++--------- test/OptionsTest.php | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/AbstractOptions.php b/src/AbstractOptions.php index 628570a59..8dadafa52 100644 --- a/src/AbstractOptions.php +++ b/src/AbstractOptions.php @@ -39,20 +39,21 @@ public function __construct($options = null) /** * @param array|Traversable $options * @throws Exception\InvalidArgumentException - * @return void + * @return AbstractOptions Provides fluent interface */ public function setFromArray($options) { - if (!is_array($options) && !$options instanceof Traversable) { - throw new Exception\InvalidArgumentException(sprintf( - 'Parameter provided to %s must be an array or Traversable', - __METHOD__ - )); + if (is_array($options) || $options instanceof Traversable) { + foreach ($options as $key => $value) { + $this->__set($key, $value); + } + return $this; } - foreach ($options as $key => $value) { - $this->__set($key, $value); - } + throw new Exception\InvalidArgumentException(sprintf( + 'Parameter provided to %s must be an array or Traversable', + __METHOD__ + )); } /** diff --git a/test/OptionsTest.php b/test/OptionsTest.php index 8b64e7715..93f5b7658 100644 --- a/test/OptionsTest.php +++ b/test/OptionsTest.php @@ -78,4 +78,20 @@ public function testGetThrowsBadMethodCallException() $options = new TestOptions(); $options->fieldFoobar; } + + public function testSetFromArrayAcceptsArray() + { + $array = array('test_field' => 3); + $options = new TestOptions(); + + $this->assertSame($options, $options->setFromArray($array)); + $this->assertEquals(3, $options->test_field); + } + + public function testSetFromArrayThrowsInvalidArgumentException() + { + $this->setExpectedException('InvalidArgumentException'); + $options = new TestOptions; + $options->setFromArray('asd'); + } } From a2e1fbc8cf445abf2352c96e1ce58f2f1a4c6484 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 3 Oct 2012 10:47:41 -0500 Subject: [PATCH 011/127] [zendframework/zf2#2621] revert changes to conditional flow - Reverts changes to conditional flows. Original code was more semantically correct, as it was validating arguments immediately, and then doing the work of the method in the method body, not in the conditional body. --- src/AbstractOptions.php | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/AbstractOptions.php b/src/AbstractOptions.php index 8dadafa52..f9365e811 100644 --- a/src/AbstractOptions.php +++ b/src/AbstractOptions.php @@ -43,17 +43,17 @@ public function __construct($options = null) */ public function setFromArray($options) { - if (is_array($options) || $options instanceof Traversable) { - foreach ($options as $key => $value) { - $this->__set($key, $value); - } - return $this; + if (!is_array($options) && !$options instanceof Traversable) { + throw new Exception\InvalidArgumentException(sprintf( + 'Parameter provided to %s must be an array or Traversable', + __METHOD__ + )); } - throw new Exception\InvalidArgumentException(sprintf( - 'Parameter provided to %s must be an array or Traversable', - __METHOD__ - )); + foreach ($options as $key => $value) { + $this->__set($key, $value); + } + return $this; } /** @@ -107,15 +107,15 @@ public function __set($key, $value) public function __get($key) { $getter = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); - if (method_exists($this, $getter)) { - return $this->{$getter}(); + if (!method_exists($this, $getter)) { + throw new Exception\BadMethodCallException( + 'The option "' . $key . '" does not ' + . 'have a matching ' . $getter . ' getter method ' + . 'which must be defined' + ); } - throw new Exception\BadMethodCallException( - 'The option "' . $key . '" does not ' - . 'have a matching ' . $getter . ' getter method ' - . 'which must be defined' - ); + return $this->{$getter}(); } /** From 214fff241865dc1672949a539fc1ce964c90aa56 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Mon, 26 Nov 2012 16:45:36 +0100 Subject: [PATCH 012/127] ZendTest namespace --- test/ArrayUtilsTest.php | 366 ++++++++++++++++++ test/CallbackHandlerTest.php | 175 +++++++++ test/ErrorHandlerTest.php | 90 +++++ test/GlobTest.php | 35 ++ test/HydratorStrategyTest.php | 147 +++++++ test/HydratorTest.php | 251 ++++++++++++ test/MessageTest.php | 72 ++++ test/OptionsTest.php | 97 +++++ test/ParametersTest.php | 66 ++++ test/PriorityQueueTest.php | 154 ++++++++ test/SignalHandlers/InstanceMethod.php | 24 ++ test/SignalHandlers/Invokable.php | 19 + test/SignalHandlers/ObjectCallback.php | 19 + test/SignalHandlers/Overloadable.php | 19 + test/SplPriorityQueueTest.php | 77 ++++ test/SplQueueTest.php | 54 +++ test/SplStackTest.php | 56 +++ test/Strategy/SerializableStrategyTest.php | 53 +++ test/TestAsset/ClassMethodsCamelCase.php | 92 +++++ .../ClassMethodsCamelCaseMissing.php | 44 +++ test/TestAsset/ClassMethodsUnderscore.php | 92 +++++ test/TestAsset/HydratorStrategy.php | 64 +++ test/TestAsset/HydratorStrategyEntityA.php | 75 ++++ test/TestAsset/HydratorStrategyEntityB.php | 46 +++ test/TestAsset/Reflection.php | 30 ++ test/TestAsset/TestOptions.php | 31 ++ test/TestAsset/TestOptionsNoStrict.php | 33 ++ test/_files/alpha | 0 test/_files/beta | 0 test/_files/delta | 0 test/_files/gamma | 0 31 files changed, 2281 insertions(+) create mode 100644 test/ArrayUtilsTest.php create mode 100644 test/CallbackHandlerTest.php create mode 100644 test/ErrorHandlerTest.php create mode 100644 test/GlobTest.php create mode 100644 test/HydratorStrategyTest.php create mode 100644 test/HydratorTest.php create mode 100644 test/MessageTest.php create mode 100644 test/OptionsTest.php create mode 100644 test/ParametersTest.php create mode 100644 test/PriorityQueueTest.php create mode 100644 test/SignalHandlers/InstanceMethod.php create mode 100644 test/SignalHandlers/Invokable.php create mode 100644 test/SignalHandlers/ObjectCallback.php create mode 100644 test/SignalHandlers/Overloadable.php create mode 100644 test/SplPriorityQueueTest.php create mode 100644 test/SplQueueTest.php create mode 100644 test/SplStackTest.php create mode 100644 test/Strategy/SerializableStrategyTest.php create mode 100644 test/TestAsset/ClassMethodsCamelCase.php create mode 100644 test/TestAsset/ClassMethodsCamelCaseMissing.php create mode 100644 test/TestAsset/ClassMethodsUnderscore.php create mode 100644 test/TestAsset/HydratorStrategy.php create mode 100644 test/TestAsset/HydratorStrategyEntityA.php create mode 100644 test/TestAsset/HydratorStrategyEntityB.php create mode 100644 test/TestAsset/Reflection.php create mode 100644 test/TestAsset/TestOptions.php create mode 100644 test/TestAsset/TestOptionsNoStrict.php create mode 100644 test/_files/alpha create mode 100644 test/_files/beta create mode 100644 test/_files/delta create mode 100644 test/_files/gamma diff --git a/test/ArrayUtilsTest.php b/test/ArrayUtilsTest.php new file mode 100644 index 000000000..15333bb1d --- /dev/null +++ b/test/ArrayUtilsTest.php @@ -0,0 +1,366 @@ + 'bar' + )), + array(array( + '15', + 'foo' => 'bar', + 'baz' => array('baz') + )), + array(array( + 0 => false, + 2 => null + )), + array(array( + -100 => 'foo', + 100 => 'bar' + )), + array(array( + 1 => 0 + )), + ); + } + + public static function validLists() + { + return array( + array(array(null)), + array(array(true)), + array(array(false)), + array(array(0)), + array(array(-0.9999)), + array(array('string')), + array(array(new stdClass)), + array(array( + 0 => 'foo', + 1 => 'bar', + 2 => false, + 3 => null, + 4 => array(), + 5 => new stdClass() + )) + ); + } + + public static function validArraysWithStringKeys() + { + return array( + array(array( + 'foo' => 'bar', + )), + array(array( + 'bar', + 'foo' => 'bar', + 'baz', + )), + ); + } + + public static function validArraysWithNumericKeys() + { + return array( + array(array( + 'foo', + 'bar' + )), + array(array( + '0' => 'foo', + '1' => 'bar', + )), + array(array( + 'bar', + '1' => 'bar', + 3 => 'baz' + )), + array(array( + -10000 => null, + '-10000' => null, + )), + array(array( + '-00000.00009' => 'foo' + )), + array(array( + 1 => 0 + )), + ); + } + + public static function validArraysWithIntegerKeys() + { + return array( + array(array( + 'foo', + 'bar,' + )), + array(array( + 100 => 'foo', + 200 => 'bar' + )), + array(array( + -100 => 'foo', + 0 => 'bar', + 100 => 'baz' + )), + array(array( + 'foo', + 'bar', + 1000 => 'baz' + )), + ); + } + + public static function invalidArrays() + { + return array( + array(new stdClass()), + array(15), + array('foo'), + array(new ArrayObject()), + ); + } + + public static function mergeArrays() + { + return array( + 'merge-integer-and-string keys' => array( + array( + 'foo', + 3 => 'bar', + 'baz' => 'baz' + ), + array( + 'baz', + ), + array( + 0 => 'foo', + 3 => 'bar', + 'baz' => 'baz', + 4 => 'baz' + ) + ), + 'merge-arrays-recursively' => array( + array( + 'foo' => array( + 'baz' + ) + ), + array( + 'foo' => array( + 'baz' + ) + ), + array( + 'foo' => array( + 0 => 'baz', + 1 => 'baz' + ) + ) + ), + 'replace-string-keys' => array( + array( + 'foo' => 'bar', + 'bar' => array() + ), + array( + 'foo' => 'baz', + 'bar' => 'bat' + ), + array( + 'foo' => 'baz', + 'bar' => 'bat' + ) + ), + ); + } + + public static function validIterators() + { + return array( + array(array( + 'foo' => 'bar', + ), array( + 'foo' => 'bar', + )), + array(new Config(array( + 'foo' => array( + 'bar' => array( + 'baz' => array( + 'baz' => 'bat', + ), + ), + ), + )), array( + 'foo' => array( + 'bar' => array( + 'baz' => array( + 'baz' => 'bat', + ), + ), + ), + )), + array(new ArrayObject(array( + 'foo' => array( + 'bar' => array( + 'baz' => array( + 'baz' => 'bat', + ), + ), + ), + )), array( + 'foo' => array( + 'bar' => array( + 'baz' => array( + 'baz' => 'bat', + ), + ), + ), + )), + ); + } + + public static function invalidIterators() + { + return array( + array(null), + array(true), + array(false), + array(0), + array(1), + array(0.0), + array(1.0), + array('string'), + array(new stdClass), + ); + } + + /** + * @dataProvider validArraysWithStringKeys + */ + public function testValidArraysWithStringKeys($test) + { + $this->assertTrue(ArrayUtils::hasStringKeys($test)); + } + + /** + * @dataProvider validArraysWithIntegerKeys + */ + public function testValidArraysWithIntegerKeys($test) + { + $this->assertTrue(ArrayUtils::hasIntegerKeys($test)); + } + + /** + * @dataProvider validArraysWithNumericKeys + */ + public function testValidArraysWithNumericKeys($test) + { + $this->assertTrue(ArrayUtils::hasNumericKeys($test)); + } + + /** + * @dataProvider invalidArrays + */ + public function testInvalidArraysAlwaysReturnFalse($test) + { + $this->assertFalse(ArrayUtils::hasStringKeys($test, False)); + $this->assertFalse(ArrayUtils::hasIntegerKeys($test, False)); + $this->assertFalse(ArrayUtils::hasNumericKeys($test, False)); + $this->assertFalse(ArrayUtils::isList($test, False)); + $this->assertFalse(ArrayUtils::isHashTable($test, False)); + + $this->assertFalse(ArrayUtils::hasStringKeys($test, false)); + $this->assertFalse(ArrayUtils::hasIntegerKeys($test, false)); + $this->assertFalse(ArrayUtils::hasNumericKeys($test, false)); + $this->assertFalse(ArrayUtils::isList($test, false)); + $this->assertFalse(ArrayUtils::isHashTable($test, false)); + } + + /** + * @dataProvider validLists + */ + public function testLists($test) + { + $this->assertTrue(ArrayUtils::isList($test)); + $this->assertTrue(ArrayUtils::hasIntegerKeys($test)); + $this->assertTrue(ArrayUtils::hasNumericKeys($test)); + $this->assertFalse(ArrayUtils::hasStringKeys($test)); + $this->assertFalse(ArrayUtils::isHashTable($test)); + } + + /** + * @dataProvider validHashTables + */ + public function testHashTables($test) + { + $this->assertTrue(ArrayUtils::isHashTable($test)); + $this->assertFalse(ArrayUtils::isList($test)); + } + + public function testEmptyArrayReturnsTrue() + { + $test = array(); + $this->assertTrue(ArrayUtils::hasStringKeys($test, true)); + $this->assertTrue(ArrayUtils::hasIntegerKeys($test, true)); + $this->assertTrue(ArrayUtils::hasNumericKeys($test, true)); + $this->assertTrue(ArrayUtils::isList($test, true)); + $this->assertTrue(ArrayUtils::isHashTable($test, true)); + } + + public function testEmptyArrayReturnsFalse() + { + $test = array(); + $this->assertFalse(ArrayUtils::hasStringKeys($test, false)); + $this->assertFalse(ArrayUtils::hasIntegerKeys($test, false)); + $this->assertFalse(ArrayUtils::hasNumericKeys($test, false)); + $this->assertFalse(ArrayUtils::isList($test, false)); + $this->assertFalse(ArrayUtils::isHashTable($test, false)); + } + + /** + * @dataProvider mergeArrays + */ + public function testMerge($a, $b, $expected) + { + $this->assertEquals($expected, ArrayUtils::merge($a, $b)); + } + + /** + * @dataProvider validIterators + */ + public function testValidIteratorsReturnArrayRepresentation($test, $expected) + { + $result = ArrayUtils::iteratorToArray($test); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider invalidIterators + */ + public function testInvalidIteratorsRaiseInvalidArgumentException($test) + { + $this->setExpectedException('Zend\Stdlib\Exception\InvalidArgumentException'); + $this->assertFalse(ArrayUtils::iteratorToArray($test)); + } +} diff --git a/test/CallbackHandlerTest.php b/test/CallbackHandlerTest.php new file mode 100644 index 000000000..124be3a90 --- /dev/null +++ b/test/CallbackHandlerTest.php @@ -0,0 +1,175 @@ +args)) { + unset($this->args); + } + } + + public function testCallbackShouldStoreMetadata() + { + $handler = new CallbackHandler('rand', array('event' => 'foo')); + $this->assertEquals('foo', $handler->getMetadatum('event')); + $this->assertEquals(array('event' => 'foo'), $handler->getMetadata()); + } + + public function testCallbackShouldBeStringIfNoHandlerPassedToConstructor() + { + $handler = new CallbackHandler('rand'); + $this->assertSame('rand', $handler->getCallback()); + } + + public function testCallbackShouldBeArrayIfHandlerPassedToConstructor() + { + $handler = new CallbackHandler(array('ZendTest\\Stdlib\\SignalHandlers\\ObjectCallback', 'test')); + $this->assertSame(array('ZendTest\\Stdlib\\SignalHandlers\\ObjectCallback', 'test'), $handler->getCallback()); + } + + public function testCallShouldInvokeCallbackWithSuppliedArguments() + { + $handler = new CallbackHandler(array( $this, 'handleCall' )); + $args = array('foo', 'bar', 'baz'); + $handler->call($args); + $this->assertSame($args, $this->args); + } + + public function testPassingInvalidCallbackShouldRaiseInvalidCallbackExceptionDuringInstantiation() + { + $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException'); + $handler = new CallbackHandler('boguscallback'); + } + + public function testCallShouldReturnTheReturnValueOfTheCallback() + { + $handler = new CallbackHandler(array('ZendTest\\Stdlib\\SignalHandlers\\ObjectCallback', 'test')); + if (!is_callable(array('ZendTest\\Stdlib\\SignalHandlers\\ObjectCallback', 'test'))) { + echo "\nClass exists? " . var_export(class_exists('ZendTest\\Stdlib\\SignalHandlers\\ObjectCallback'), 1) . "\n"; + echo "Include path: " . get_include_path() . "\n"; + } + $this->assertEquals('bar', $handler->call(array())); + } + + public function testStringCallbackResolvingToClassDefiningInvokeNameShouldRaiseException() + { + $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException'); + $handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\Invokable'); + } + + public function testStringCallbackReferringToClassWithoutDefinedInvokeShouldRaiseException() + { + $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException'); + $class = new SignalHandlers\InstanceMethod(); + $handler = new CallbackHandler($class); + } + + public function testCallbackConsistingOfStringContextWithNonStaticMethodShouldNotRaiseExceptionButWillRaiseEStrict() + { + $handler = new CallbackHandler(array('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod', 'handler')); + $error = false; + set_error_handler(function ($errno, $errstr) use (&$error) { + $error = true; + }, E_STRICT); + $handler->call(); + restore_error_handler(); + $this->assertTrue($error); + } + + public function testStringCallbackConsistingOfNonStaticMethodShouldRaiseException() + { + $handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::handler'); + + if (version_compare(PHP_VERSION, '5.4.0rc1', '>=')) { + $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException'); + $handler->call(); + } else { + $error = false; + set_error_handler(function ($errno, $errstr) use (&$error) { + $error = true; + }, E_STRICT); + $handler->call(); + restore_error_handler(); + $this->assertTrue($error); + } + } + + public function testStringStaticCallbackForPhp54() + { + if (version_compare(PHP_VERSION, '5.4.0rc1', '<=')) { + $this->markTestSkipped('Requires PHP 5.4'); + } + + $handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::staticHandler'); + $error = false; + set_error_handler(function ($errno, $errstr) use (&$error) { + $error = true; + }, E_STRICT); + $result = $handler->call(); + restore_error_handler(); + $this->assertFalse($error); + $this->assertSame('staticHandler', $result); + } + + public function testStringStaticCallbackForPhp54WithMoreThan3Args() + { + if (version_compare(PHP_VERSION, '5.4.0rc1', '<=')) { + $this->markTestSkipped('Requires PHP 5.4'); + } + + $handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::staticHandler'); + $error = false; + set_error_handler(function ($errno, $errstr) use (&$error) { + $error = true; + }, E_STRICT); + $result = $handler->call(array(1, 2, 3, 4)); + restore_error_handler(); + $this->assertFalse($error); + $this->assertSame('staticHandler', $result); + } + + public function testCallbackToClassImplementingOverloadingButNotInvocableShouldRaiseException() + { + $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException'); + $handler = new CallbackHandler('foo', array( 'ZendTest\\Stdlib\\SignalHandlers\\Overloadable', 'foo' )); + } + + public function testClosureCallbackShouldBeInvokedByCall() + { + $handler = new CallbackHandler(function () { + return 'foo'; + }); + $this->assertEquals('foo', $handler->call()); + } + + public function testHandlerShouldBeInvocable() + { + $handler = new CallbackHandler(array($this, 'handleCall')); + $handler('foo', 'bar'); + $this->assertEquals(array('foo', 'bar'), $this->args); + } + + public function handleCall() + { + $this->args = func_get_args(); + } +} diff --git a/test/ErrorHandlerTest.php b/test/ErrorHandlerTest.php new file mode 100644 index 000000000..f1613d4e1 --- /dev/null +++ b/test/ErrorHandlerTest.php @@ -0,0 +1,90 @@ +assertFalse(ErrorHandler::started()); + + ErrorHandler::start(); + $this->assertTrue(ErrorHandler::started()); + + ErrorHandler::stop(); + $this->assertFalse(ErrorHandler::started()); + } + + public function testStartThrowsLogicException() + { + ErrorHandler::start(); + + $this->setExpectedException('Zend\Stdlib\Exception\LogicException'); + ErrorHandler::start(); + } + + public function testStopThrowsLogicException() + { + $this->setExpectedException('Zend\Stdlib\Exception\LogicException'); + ErrorHandler::stop(); + } + + public function testReturnCatchedError() + { + ErrorHandler::start(); + strpos(); // Invalid argument list + $err = ErrorHandler::stop(); + + $this->assertInstanceOf('ErrorException', $err); + } + + public function testThrowCatchedError() + { + ErrorHandler::start(); + strpos(); // Invalid argument list + + $this->setExpectedException('ErrorException'); + ErrorHandler::stop(true); + } + + public function testAddErrors() + { + ErrorHandler::start(); + ErrorHandler::addError(1, 'test-msg1', 'test-file1', 100); + ErrorHandler::addError(2, 'test-msg2', 'test-file2', 200); + $err = ErrorHandler::stop(); + + $this->assertInstanceOf('ErrorException', $err); + $this->assertEquals('test-file2', $err->getFile()); + $this->assertEquals('test-msg2', $err->getMessage()); + $this->assertEquals(200, $err->getLine()); + $this->assertEquals(0, $err->getCode()); + $this->assertEquals(2, $err->getSeverity()); + + $previous = $err->getPrevious(); + $this->assertInstanceOf('ErrorException', $previous); + $this->assertEquals('test-file1', $previous->getFile()); + $this->assertEquals('test-msg1', $previous->getMessage()); + $this->assertEquals(100, $previous->getLine()); + $this->assertEquals(0, $previous->getCode()); + $this->assertEquals(1, $previous->getSeverity()); + } +} diff --git a/test/GlobTest.php b/test/GlobTest.php new file mode 100644 index 000000000..6eca47add --- /dev/null +++ b/test/GlobTest.php @@ -0,0 +1,35 @@ +markTestSkipped('GLOB_BRACE not available'); + } + + $this->assertEquals( + glob(__DIR__ . '/_files/{alph,bet}a', GLOB_BRACE), + Glob::glob(__DIR__ . '/_files/{alph,bet}a', Glob::GLOB_BRACE, true) + ); + } + + public function testNonMatchingGlobReturnsArray() + { + $result = Glob::glob('/some/path/{,*.}{this,orthis}.php', Glob::GLOB_BRACE); + $this->assertInternalType('array', $result); + } +} diff --git a/test/HydratorStrategyTest.php b/test/HydratorStrategyTest.php new file mode 100644 index 000000000..6f83c2ec2 --- /dev/null +++ b/test/HydratorStrategyTest.php @@ -0,0 +1,147 @@ +hydrator = new ClassMethods(); + } + + public function testAddingStrategy() + { + $this->assertAttributeCount(0, 'strategies', $this->hydrator); + + $this->hydrator->addStrategy('myStrategy', new TestAsset\HydratorStrategy()); + + $this->assertAttributeCount(1, 'strategies', $this->hydrator); + } + + public function testCheckStrategyEmpty() + { + $this->assertFalse($this->hydrator->hasStrategy('myStrategy')); + } + + public function testCheckStrategyNotEmpty() + { + $this->hydrator->addStrategy('myStrategy', new TestAsset\HydratorStrategy()); + + $this->assertTrue($this->hydrator->hasStrategy('myStrategy')); + } + + public function testRemovingStrategy() + { + $this->assertAttributeCount(0, 'strategies', $this->hydrator); + + $this->hydrator->addStrategy('myStrategy', new TestAsset\HydratorStrategy()); + $this->assertAttributeCount(1, 'strategies', $this->hydrator); + + $this->hydrator->removeStrategy('myStrategy'); + $this->assertAttributeCount(0, 'strategies', $this->hydrator); + } + + public function testRetrieveStrategy() + { + $strategy = new TestAsset\HydratorStrategy(); + $this->hydrator->addStrategy('myStrategy', $strategy); + + $this->assertEquals($strategy, $this->hydrator->getStrategy('myStrategy')); + } + + public function testExtractingObjects() + { + $this->hydrator->addStrategy('entities', new TestAsset\HydratorStrategy()); + + $entityA = new TestAsset\HydratorStrategyEntityA(); + $entityA->addEntity(new TestAsset\HydratorStrategyEntityB(111, 'AAA')); + $entityA->addEntity(new TestAsset\HydratorStrategyEntityB(222, 'BBB')); + + $attributes = $this->hydrator->extract($entityA); + + $this->assertContains(111, $attributes['entities']); + $this->assertContains(222, $attributes['entities']); + } + + public function testHydratingObjects() + { + $this->hydrator->addStrategy('entities', new TestAsset\HydratorStrategy()); + + $entityA = new TestAsset\HydratorStrategyEntityA(); + $entityA->addEntity(new TestAsset\HydratorStrategyEntityB(111, 'AAA')); + $entityA->addEntity(new TestAsset\HydratorStrategyEntityB(222, 'BBB')); + + $attributes = $this->hydrator->extract($entityA); + $attributes['entities'][] = 333; + + $this->hydrator->hydrate($attributes, $entityA); + $entities = $entityA->getEntities(); + + $this->assertCount(3, $entities); + } + + /** + * @dataProvider underscoreHandlingDataProvider + */ + public function testWhenUsingUnderscoreSeparatedKeysHydratorStrategyIsAlwaysConsideredUnderscoreSeparatedToo($underscoreSeparatedKeys, $formFieldKey) + { + $hydrator = new ClassMethods($underscoreSeparatedKeys); + + $strategy = $this->getMock('Zend\Stdlib\Hydrator\Strategy\StrategyInterface'); + + $entity = new TestAsset\ClassMethodsUnderscore(); + $value = $entity->getFooBar(); + + $hydrator->addStrategy($formFieldKey, $strategy); + + $strategy + ->expects($this->once()) + ->method('extract') + ->with($this->identicalTo($value)) + ->will($this->returnValue($value)) + ; + + $attributes = $hydrator->extract($entity); + + $strategy + ->expects($this->once()) + ->method('hydrate') + ->with($this->identicalTo($value)) + ->will($this->returnValue($value)) + ; + + $hydrator->hydrate($attributes, $entity); + } + + public function underscoreHandlingDataProvider() + { + return array( + array(true, 'foo_bar'), + array(false, 'fooBar'), + ); + } +} diff --git a/test/HydratorTest.php b/test/HydratorTest.php new file mode 100644 index 000000000..8a30585e3 --- /dev/null +++ b/test/HydratorTest.php @@ -0,0 +1,251 @@ +classMethodsCamelCase = new ClassMethodsCamelCase(); + $this->classMethodsCamelCaseMissing = new ClassMethodsCamelCaseMissing(); + $this->classMethodsUnderscore = new ClassMethodsUnderscore(); + $this->reflection = new ReflectionAsset; + } + + public function testInitiateValues() + { + $this->assertEquals($this->classMethodsCamelCase->getFooBar(), '1'); + $this->assertEquals($this->classMethodsCamelCase->getFooBarBaz(), '2'); + $this->assertEquals($this->classMethodsCamelCase->getIsFoo(), true); + $this->assertEquals($this->classMethodsCamelCase->isBar(), true); + $this->assertEquals($this->classMethodsCamelCase->getHasFoo(), true); + $this->assertEquals($this->classMethodsCamelCase->hasBar(), true); + $this->assertEquals($this->classMethodsUnderscore->getFooBar(), '1'); + $this->assertEquals($this->classMethodsUnderscore->getFooBarBaz(), '2'); + $this->assertEquals($this->classMethodsUnderscore->getIsFoo(), true); + $this->assertEquals($this->classMethodsUnderscore->isBar(), true); + $this->assertEquals($this->classMethodsUnderscore->getHasFoo(), true); + $this->assertEquals($this->classMethodsUnderscore->hasBar(), true); + } + + public function testHydratorReflection() + { + $hydrator = new Reflection; + $datas = $hydrator->extract($this->reflection); + $this->assertTrue(isset($datas['foo'])); + $this->assertEquals($datas['foo'], '1'); + $this->assertTrue(isset($datas['fooBar'])); + $this->assertEquals($datas['fooBar'], '2'); + $this->assertTrue(isset($datas['fooBarBaz'])); + $this->assertEquals($datas['fooBarBaz'], '3'); + + $test = $hydrator->hydrate(array('foo' => 'foo', 'fooBar' => 'bar', 'fooBarBaz' => 'baz'), $this->reflection); + $this->assertEquals($test->foo, 'foo'); + $this->assertEquals($test->getFooBar(), 'bar'); + $this->assertEquals($test->getFooBarBaz(), 'baz'); + } + + public function testHydratorClassMethodsCamelCase() + { + $hydrator = new ClassMethods(false); + $datas = $hydrator->extract($this->classMethodsCamelCase); + $this->assertTrue(isset($datas['fooBar'])); + $this->assertEquals($datas['fooBar'], '1'); + $this->assertTrue(isset($datas['fooBarBaz'])); + $this->assertFalse(isset($datas['foo_bar'])); + $this->assertTrue(isset($datas['isFoo'])); + $this->assertEquals($datas['isFoo'], true); + $this->assertTrue(isset($datas['isBar'])); + $this->assertEquals($datas['isBar'], true); + $this->assertTrue(isset($datas['hasFoo'])); + $this->assertEquals($datas['hasFoo'], true); + $this->assertTrue(isset($datas['hasBar'])); + $this->assertEquals($datas['hasBar'], true); + $test = $hydrator->hydrate( + array( + 'fooBar' => 'foo', + 'fooBarBaz' => 'bar', + 'isFoo' => false, + 'isBar' => false, + 'hasFoo' => false, + 'hasBar' => false, + ), + $this->classMethodsCamelCase + ); + $this->assertSame($this->classMethodsCamelCase, $test); + $this->assertEquals($test->getFooBar(), 'foo'); + $this->assertEquals($test->getFooBarBaz(), 'bar'); + $this->assertEquals($test->getIsFoo(), false); + $this->assertEquals($test->isBar(), false); + $this->assertEquals($test->getHasFoo(), false); + $this->assertEquals($test->hasBar(), false); + } + + public function testHydratorClassMethodsUnderscore() + { + $hydrator = new ClassMethods(true); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertTrue(isset($datas['foo_bar'])); + $this->assertEquals($datas['foo_bar'], '1'); + $this->assertTrue(isset($datas['foo_bar_baz'])); + $this->assertFalse(isset($datas['fooBar'])); + $this->assertTrue(isset($datas['is_foo'])); + $this->assertFalse(isset($datas['isFoo'])); + $this->assertEquals($datas['is_foo'], true); + $this->assertTrue(isset($datas['is_bar'])); + $this->assertFalse(isset($datas['isBar'])); + $this->assertEquals($datas['is_bar'], true); + $this->assertTrue(isset($datas['has_foo'])); + $this->assertFalse(isset($datas['hasFoo'])); + $this->assertEquals($datas['has_foo'], true); + $this->assertTrue(isset($datas['has_bar'])); + $this->assertFalse(isset($datas['hasBar'])); + $this->assertEquals($datas['has_bar'], true); + $test = $hydrator->hydrate( + array( + 'foo_bar' => 'foo', + 'foo_bar_baz' => 'bar', + 'is_foo' => false, + 'is_bar' => false, + 'has_foo' => false, + 'has_bar' => false, + ), + $this->classMethodsUnderscore + ); + $this->assertSame($this->classMethodsUnderscore, $test); + $this->assertEquals($test->getFooBar(), 'foo'); + $this->assertEquals($test->getFooBarBaz(), 'bar'); + $this->assertEquals($test->getIsFoo(), false); + $this->assertEquals($test->isBar(), false); + $this->assertEquals($test->getHasFoo(), false); + $this->assertEquals($test->hasBar(), false); + } + + public function testHydratorClassMethodsOptions() + { + $hydrator = new ClassMethods(); + $this->assertTrue($hydrator->getUnderscoreSeparatedKeys()); + $hydrator->setOptions(array('underscoreSeparatedKeys' => false)); + $this->assertFalse($hydrator->getUnderscoreSeparatedKeys()); + $hydrator->setUnderscoreSeparatedKeys(true); + $this->assertTrue($hydrator->getUnderscoreSeparatedKeys()); + } + + public function testHydratorClassMethodsIgnoresInvalidValues() + { + $hydrator = new ClassMethods(true); + $data = array( + 'foo_bar' => '1', + 'foo_bar_baz' => '2', + 'invalid' => 'value' + ); + $test = $hydrator->hydrate($data, $this->classMethodsUnderscore); + $this->assertSame($this->classMethodsUnderscore, $test); + } + + public function testHydratorClassMethodsDefaultBehaviorIsConvertUnderscoreToCamelCase() + { + $hydrator = new ClassMethods(); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertTrue(isset($datas['foo_bar'])); + $this->assertEquals($datas['foo_bar'], '1'); + $this->assertTrue(isset($datas['foo_bar_baz'])); + $this->assertFalse(isset($datas['fooBar'])); + $test = $hydrator->hydrate(array('foo_bar' => 'foo', 'foo_bar_baz' => 'bar'), $this->classMethodsUnderscore); + $this->assertSame($this->classMethodsUnderscore, $test); + $this->assertEquals($test->getFooBar(), 'foo'); + $this->assertEquals($test->getFooBarBaz(), 'bar'); + } + + public function testRetrieveWildStrategyAndOther() + { + $hydrator = new ClassMethods(); + $hydrator->addStrategy('default', new DefaultStrategy()); + $hydrator->addStrategy('*', new SerializableStrategy('phpserialize')); + $default = $hydrator->getStrategy('default'); + $this->assertEquals(get_class($default), 'Zend\Stdlib\Hydrator\Strategy\DefaultStrategy'); + $serializable = $hydrator->getStrategy('*'); + $this->assertEquals(get_class($serializable), 'Zend\Stdlib\Hydrator\Strategy\SerializableStrategy'); + } + + public function testUseWildStrategyByDefault() + { + $hydrator = new ClassMethods(); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], '1'); + $hydrator->addStrategy('*', new SerializableStrategy('phpserialize')); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], 's:1:"1";'); + } + + public function testUseWildStrategyAndOther() + { + $hydrator = new ClassMethods(); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], '1'); + $hydrator->addStrategy('foo_bar', new DefaultStrategy()); + $hydrator->addStrategy('*', new SerializableStrategy('phpserialize')); + $datas = $hydrator->extract($this->classMethodsUnderscore); + $this->assertEquals($datas['foo_bar'], '1'); + $this->assertEquals($datas['foo_bar_baz'], 's:1:"2";'); + } + + public function testHydratorClassMethodsCamelCaseWithSetterMissing() + { + $hydrator = new ClassMethods(false); + + $datas = $hydrator->extract($this->classMethodsCamelCaseMissing); + $this->assertTrue(isset($datas['fooBar'])); + $this->assertEquals($datas['fooBar'], '1'); + $this->assertTrue(isset($datas['fooBarBaz'])); + $this->assertFalse(isset($datas['foo_bar'])); + $test = $hydrator->hydrate(array('fooBar' => 'foo', 'fooBarBaz' => 1), $this->classMethodsCamelCaseMissing); + $this->assertSame($this->classMethodsCamelCaseMissing, $test); + $this->assertEquals($test->getFooBar(), 'foo'); + $this->assertEquals($test->getFooBarBaz(), '2'); + } +} diff --git a/test/MessageTest.php b/test/MessageTest.php new file mode 100644 index 000000000..9f81add04 --- /dev/null +++ b/test/MessageTest.php @@ -0,0 +1,72 @@ +setContent('I can set content'); + $this->assertInstanceOf('Zend\Stdlib\Message', $ret); + $this->assertEquals('I can set content', $message->getContent()); + } + + public function testMessageCanSetAndGetMetadataKeyAsString() + { + $message = new Message(); + $ret = $message->setMetadata('foo', 'bar'); + $this->assertInstanceOf('Zend\Stdlib\Message', $ret); + $this->assertEquals('bar', $message->getMetadata('foo')); + $this->assertEquals(array('foo' => 'bar'), $message->getMetadata()); + } + + public function testMessageCanSetAndGetMetadataKeyAsArray() + { + $message = new Message(); + $ret = $message->setMetadata(array('foo' => 'bar')); + $this->assertInstanceOf('Zend\Stdlib\Message', $ret); + $this->assertEquals('bar', $message->getMetadata('foo')); + } + + public function testMessageGetMetadataWillUseDefaultValueIfNoneExist() + { + $message = new Message(); + $this->assertEquals('bar', $message->getMetadata('foo', 'bar')); + } + + public function testMessageThrowsExceptionOnInvalidKeyForMetadataSet() + { + $message = new Message(); + + $this->setExpectedException('Zend\Stdlib\Exception\InvalidArgumentException'); + $message->setMetadata(new \stdClass()); + } + + public function testMessageThrowsExceptionOnInvalidKeyForMetadataGet() + { + $message = new Message(); + + $this->setExpectedException('Zend\Stdlib\Exception\InvalidArgumentException'); + $message->getMetadata(new \stdClass()); + } + + public function testMessageToStringWorks() + { + $message = new Message(); + $message->setMetadata(array('Foo' => 'bar', 'One' => 'Two')); + $message->setContent('This is my content'); + $expected = "Foo: bar\r\nOne: Two\r\n\r\nThis is my content"; + $this->assertEquals($expected, $message->toString()); + } +} diff --git a/test/OptionsTest.php b/test/OptionsTest.php new file mode 100644 index 000000000..93f5b7658 --- /dev/null +++ b/test/OptionsTest.php @@ -0,0 +1,97 @@ + 1)); + + $this->assertEquals(1, $options->test_field); + } + + public function testConstructionWithTraversable() + { + $config = new ArrayObject(array('test_field' => 1)); + $options = new TestOptions($config); + + $this->assertEquals(1, $options->test_field); + } + + public function testInvalidFieldThrowsException() + { + $this->setExpectedException('BadMethodCallException'); + $options = new TestOptions(array('foo' => 'bar')); + } + + public function testNonStrictOptionsDoesNotThrowException() + { + try { + $options = new TestOptionsNoStrict(array('foo' => 'bar')); + } catch (\Exception $e) { + $this->fail('Nonstrict options should not throw an exception'); + } + } + + public function testConstructionWithNull() + { + try { + $options = new TestOptions(null); + } catch (InvalidArgumentException $e) { + $this->fail("Unexpected InvalidArgumentException raised"); + } + } + + public function testUnsetting() + { + $options = new TestOptions(array('test_field' => 1)); + + $this->assertEquals(true, isset($options->test_field)); + unset($options->testField); + $this->assertEquals(false, isset($options->test_field)); + } + + public function testUnsetThrowsInvalidArgumentException() + { + $this->setExpectedException('InvalidArgumentException'); + $options = new TestOptions; + unset($options->foobarField); + } + + public function testGetThrowsBadMethodCallException() + { + $this->setExpectedException('BadMethodCallException'); + $options = new TestOptions(); + $options->fieldFoobar; + } + + public function testSetFromArrayAcceptsArray() + { + $array = array('test_field' => 3); + $options = new TestOptions(); + + $this->assertSame($options, $options->setFromArray($array)); + $this->assertEquals(3, $options->test_field); + } + + public function testSetFromArrayThrowsInvalidArgumentException() + { + $this->setExpectedException('InvalidArgumentException'); + $options = new TestOptions; + $options->setFromArray('asd'); + } +} diff --git a/test/ParametersTest.php b/test/ParametersTest.php new file mode 100644 index 000000000..5ebba9b14 --- /dev/null +++ b/test/ParametersTest.php @@ -0,0 +1,66 @@ +assertInstanceOf('Zend\Stdlib\ParametersInterface', $parameters); + $this->assertInstanceOf('ArrayObject', $parameters); + $this->assertInstanceOf('ArrayAccess', $parameters); + $this->assertInstanceOf('Countable', $parameters); + $this->assertInstanceOf('Serializable', $parameters); + $this->assertInstanceOf('Traversable', $parameters); + } + + public function testParametersPersistNameAndValues() + { + $parameters = new Parameters(array('foo' => 'bar')); + $this->assertEquals('bar', $parameters['foo']); + $this->assertEquals('bar', $parameters->foo); + $parameters->offsetSet('baz', 5); + $this->assertEquals(5, $parameters->baz); + + $parameters->fromArray(array('bar' => 'foo')); + $this->assertEquals('foo', $parameters->bar); + + $parameters->fromString('bar=foo&five=5'); + $this->assertEquals('foo', $parameters->bar); + $this->assertEquals('5', $parameters->five); + $this->assertEquals(array('bar' => 'foo', 'five' => '5'), $parameters->toArray()); + $this->assertEquals('bar=foo&five=5', $parameters->toString()); + + $parameters->fromArray(array()); + $parameters->set('foof', 'barf'); + $this->assertEquals('barf', $parameters->get('foof')); + $this->assertEquals('barf', $parameters->foof); + + } + + public function testParametersOffsetgetReturnsNullIfNonexistentKeyIsProvided() + { + $parameters = new Parameters; + $this->assertNull($parameters->foo); + } + + public function testParametersGetReturnsDefaultValueIfNonExistent() + { + $parameters = new Parameters(); + + $this->assertEquals(5, $parameters->get('nonExistentProp', 5)); + } + +} diff --git a/test/PriorityQueueTest.php b/test/PriorityQueueTest.php new file mode 100644 index 000000000..6c5ce77b2 --- /dev/null +++ b/test/PriorityQueueTest.php @@ -0,0 +1,154 @@ +queue = new PriorityQueue(); + $this->queue->insert('foo', 3); + $this->queue->insert('bar', 4); + $this->queue->insert('baz', 2); + $this->queue->insert('bat', 1); + } + + public function testSerializationAndDeserializationShouldMaintainState() + { + $s = serialize($this->queue); + $unserialized = unserialize($s); + $count = count($this->queue); + $this->assertSame($count, count($unserialized), 'Expected count ' . $count . '; received ' . count($unserialized)); + + $expected = array(); + foreach ($this->queue as $item) { + $expected[] = $item; + } + $test = array(); + foreach ($unserialized as $item) { + $test[] = $item; + } + $this->assertSame($expected, $test, 'Expected: ' . var_export($expected, 1) . "\nReceived:" . var_export($test, 1)); + } + + public function testRetrievingQueueAsArrayReturnsDataOnlyByDefault() + { + $expected = array( + 'foo', + 'bar', + 'baz', + 'bat', + ); + $test = $this->queue->toArray(); + $this->assertSame($expected, $test, var_export($test, 1)); + } + + public function testCanCastToArrayOfPrioritiesOnly() + { + $expected = array( + 3, + 4, + 2, + 1, + ); + $test = $this->queue->toArray(PriorityQueue::EXTR_PRIORITY); + $this->assertSame($expected, $test, var_export($test, 1)); + } + + public function testCanCastToArrayOfDataPriorityPairs() + { + $expected = array( + array('data' => 'foo', 'priority' => 3), + array('data' => 'bar', 'priority' => 4), + array('data' => 'baz', 'priority' => 2), + array('data' => 'bat', 'priority' => 1), + ); + $test = $this->queue->toArray(PriorityQueue::EXTR_BOTH); + $this->assertSame($expected, $test, var_export($test, 1)); + } + + public function testCanIterateMultipleTimesAndReceiveSameResults() + { + $expected = array('bar', 'foo', 'baz', 'bat'); + + for ($i = 1; $i < 3; $i++) { + $test = array(); + foreach ($this->queue as $item) { + $test[] = $item; + } + $this->assertEquals($expected, $test, 'Failed at iteration ' . $i); + } + } + + public function testCanRemoveItemFromQueue() + { + $this->queue->remove('baz'); + $expected = array('bar', 'foo', 'bat'); + $test = array(); + foreach ($this->queue as $item) { + $test[] = $item; + } + $this->assertEquals($expected, $test); + } + + public function testCanTestForExistenceOfItemInQueue() + { + $this->assertTrue($this->queue->contains('foo')); + $this->assertFalse($this->queue->contains('foobar')); + } + + public function testCanTestForExistenceOfPriorityInQueue() + { + $this->assertTrue($this->queue->hasPriority(3)); + $this->assertFalse($this->queue->hasPriority(1000)); + } + + public function testCloningAlsoClonesQueue() + { + $foo = new \stdClass(); + $foo->name = 'bar'; + + $queue = new PriorityQueue(); + $queue->insert($foo, 1); + $queue->insert($foo, 2); + + $queueClone = clone $queue; + + while (!$queue->isEmpty()) { + $this->assertSame($foo, $queue->top()); + $queue->remove($queue->top()); + } + + $this->assertTrue($queue->isEmpty()); + $this->assertFalse($queueClone->isEmpty()); + $this->assertEquals(2, $queueClone->count()); + + while (!$queueClone->isEmpty()) { + $this->assertSame($foo, $queueClone->top()); + $queueClone->remove($queueClone->top()); + } + + $this->assertTrue($queueClone->isEmpty()); + } +} diff --git a/test/SignalHandlers/InstanceMethod.php b/test/SignalHandlers/InstanceMethod.php new file mode 100644 index 000000000..af7d905ff --- /dev/null +++ b/test/SignalHandlers/InstanceMethod.php @@ -0,0 +1,24 @@ +queue = new SplPriorityQueue(); + $this->queue->insert('foo', 3); + $this->queue->insert('bar', 4); + $this->queue->insert('baz', 2); + $this->queue->insert('bat', 1); + } + + public function testMaintainsInsertOrderForDataOfEqualPriority() + { + $queue = new SplPriorityQueue(); + $queue->insert('foo', 1000); + $queue->insert('bar', 1000); + $queue->insert('baz', 1000); + $queue->insert('bat', 1000); + + $expected = array('foo', 'bar', 'baz', 'bat'); + $test = array(); + foreach ($queue as $datum) { + $test[] = $datum; + } + $this->assertEquals($expected, $test); + } + + public function testSerializationAndDeserializationShouldMaintainState() + { + $s = serialize($this->queue); + $unserialized = unserialize($s); + $count = count($this->queue); + $this->assertSame($count, count($unserialized), 'Expected count ' . $count . '; received ' . count($unserialized)); + + $expected = array(); + foreach ($this->queue as $item) { + $expected[] = $item; + } + $test = array(); + foreach ($unserialized as $item) { + $test[] = $item; + } + $this->assertSame($expected, $test, 'Expected: ' . var_export($expected, 1) . "\nReceived:" . var_export($test, 1)); + } + + public function testCanRetrieveQueueAsArray() + { + $expected = array( + 'bar', + 'foo', + 'baz', + 'bat', + ); + $test = $this->queue->toArray(); + $this->assertSame($expected, $test, var_export($test, 1)); + } +} diff --git a/test/SplQueueTest.php b/test/SplQueueTest.php new file mode 100644 index 000000000..5eb3af1ac --- /dev/null +++ b/test/SplQueueTest.php @@ -0,0 +1,54 @@ +queue = new SplQueue(); + $this->queue->push('foo'); + $this->queue->push('bar'); + $this->queue->push('baz'); + } + + public function testSerializationAndDeserializationShouldMaintainState() + { + $s = serialize($this->queue); + $unserialized = unserialize($s); + $count = count($this->queue); + $this->assertSame($count, count($unserialized)); + + $expected = array(); + foreach ($this->queue as $item) { + $expected[] = $item; + } + $test = array(); + foreach ($unserialized as $item) { + $test[] = $item; + } + $this->assertSame($expected, $test); + } + + public function testCanRetrieveQueueAsArray() + { + $expected = array('foo', 'bar', 'baz'); + $this->assertSame($expected, $this->queue->toArray()); + } +} diff --git a/test/SplStackTest.php b/test/SplStackTest.php new file mode 100644 index 000000000..18c2ea0db --- /dev/null +++ b/test/SplStackTest.php @@ -0,0 +1,56 @@ +stack = new SplStack(); + $this->stack->push('foo'); + $this->stack->push('bar'); + $this->stack->push('baz'); + $this->stack->push('bat'); + } + + public function testSerializationAndDeserializationShouldMaintainState() + { + $s = serialize($this->stack); + $unserialized = unserialize($s); + $count = count($this->stack); + $this->assertSame($count, count($unserialized)); + + $expected = array(); + foreach ($this->stack as $item) { + $expected[] = $item; + } + $test = array(); + foreach ($unserialized as $item) { + $test[] = $item; + } + $this->assertSame($expected, $test); + } + + public function testCanRetrieveQueueAsArray() + { + $expected = array('bat', 'baz', 'bar', 'foo'); + $test = $this->stack->toArray(); + $this->assertSame($expected, $test, var_export($test, 1)); + } +} diff --git a/test/Strategy/SerializableStrategyTest.php b/test/Strategy/SerializableStrategyTest.php new file mode 100644 index 000000000..f36980de2 --- /dev/null +++ b/test/Strategy/SerializableStrategyTest.php @@ -0,0 +1,53 @@ +setExpectedException('Zend\Stdlib\Exception\InvalidArgumentException'); + $serializerStrategy = new SerializableStrategy(false); + } + + public function testUseBadSerilizerObject() + { + $serializer = Serializer::factory('phpserialize'); + $serializerStrategy = new SerializableStrategy($serializer); + $this->assertEquals($serializer, $serializerStrategy->getSerializer()); + } + + public function testUseBadSerilizerString() + { + $serializerStrategy = new SerializableStrategy('phpserialize'); + $this->assertEquals('Zend\Serializer\Adapter\PhpSerialize', get_class($serializerStrategy->getSerializer())); + } + + public function testCanSerialize() + { + $serializer = Serializer::factory('phpserialize'); + $serializerStrategy = new SerializableStrategy($serializer); + $serialized = $serializerStrategy->extract('foo'); + $this->assertEquals($serialized, 's:3:"foo";'); + } + + public function testCanUnserialize() + { + $serializer = Serializer::factory('phpserialize'); + $serializerStrategy = new SerializableStrategy($serializer); + $serialized = $serializerStrategy->hydrate('s:3:"foo";'); + $this->assertEquals($serialized, 'foo'); + } +} diff --git a/test/TestAsset/ClassMethodsCamelCase.php b/test/TestAsset/ClassMethodsCamelCase.php new file mode 100644 index 000000000..50ccd4ec6 --- /dev/null +++ b/test/TestAsset/ClassMethodsCamelCase.php @@ -0,0 +1,92 @@ +fooBar; + } + + public function setFooBar($value) + { + $this->fooBar = $value; + return $this; + } + + public function getFooBarBaz() + { + return $this->fooBarBaz; + } + + public function setFooBarBaz($value) + { + $this->fooBarBaz = $value; + return $this; + } + + public function getIsFoo() + { + return $this->isFoo; + } + + public function setIsFoo($value) + { + $this->isFoo = $value; + return $this; + } + + public function isBar() + { + return $this->isBar; + } + + public function setIsBar($value) + { + $this->isBar = $value; + return $this; + } + + public function getHasFoo() + { + return $this->hasFoo; + } + + public function setHasFoo($value) + { + $this->hasFoo = $value; + return $this; + } + + public function hasBar() + { + return $this->hasBar; + } + + public function setHasBar($value) + { + $this->hasBar = $value; + return $this; + } +} diff --git a/test/TestAsset/ClassMethodsCamelCaseMissing.php b/test/TestAsset/ClassMethodsCamelCaseMissing.php new file mode 100644 index 000000000..7ad333e26 --- /dev/null +++ b/test/TestAsset/ClassMethodsCamelCaseMissing.php @@ -0,0 +1,44 @@ +fooBar; + } + + public function setFooBar($value) + { + $this->fooBar = $value; + return $this; + } + + public function getFooBarBaz() + { + return $this->fooBarBaz; + } + + /* + * comment to detection verification + * + public function setFooBarBaz($value) + { + $this->fooBarBaz = $value; + return $this; + } + */ +} diff --git a/test/TestAsset/ClassMethodsUnderscore.php b/test/TestAsset/ClassMethodsUnderscore.php new file mode 100644 index 000000000..a51883805 --- /dev/null +++ b/test/TestAsset/ClassMethodsUnderscore.php @@ -0,0 +1,92 @@ +foo_bar; + } + + public function setFooBar($value) + { + $this->foo_bar = $value; + return $this; + } + + public function getFooBarBaz() + { + return $this->foo_bar_baz; + } + + public function setFooBarBaz($value) + { + $this->foo_bar_baz = $value; + return $this; + } + + public function getIsFoo() + { + return $this->is_foo; + } + + public function setIsFoo($value) + { + $this->is_foo = $value; + return $this; + } + + public function isBar() + { + return $this->is_bar; + } + + public function setIsBar($value) + { + $this->is_bar = $value; + return $this; + } + + public function getHasFoo() + { + return $this->has_foo; + } + + public function setHasFoo($value) + { + $this->has_foo = $value; + return $this; + } + + public function hasBar() + { + return $this->has_bar; + } + + public function setHasBar($value) + { + $this->has_bar = $value; + return $this; + } +} diff --git a/test/TestAsset/HydratorStrategy.php b/test/TestAsset/HydratorStrategy.php new file mode 100644 index 000000000..abb7bf47e --- /dev/null +++ b/test/TestAsset/HydratorStrategy.php @@ -0,0 +1,64 @@ +simulatedStorageDevice = array(); + $this->simulatedStorageDevice[] = new HydratorStrategyEntityB(111, 'AAA'); + $this->simulatedStorageDevice[] = new HydratorStrategyEntityB(222, 'BBB'); + $this->simulatedStorageDevice[] = new HydratorStrategyEntityB(333, 'CCC'); + } + + public function extract($value) + { + $result = array(); + foreach ($value as $instance) { + $result[] = $instance->getField1(); + } + return $result; + } + + public function hydrate($value) + { + $result = $value; + if (is_array($value)) { + $result = array(); + foreach ($value as $field1) { + $result[] = $this->findEntity($field1); + } + } + return $result; + } + + private function findEntity($field1) + { + $result = null; + foreach ($this->simulatedStorageDevice as $entity) { + if ($entity->getField1() == $field1) { + $result = $entity; + break; + } + } + return $result; + } +} diff --git a/test/TestAsset/HydratorStrategyEntityA.php b/test/TestAsset/HydratorStrategyEntityA.php new file mode 100644 index 000000000..641d44473 --- /dev/null +++ b/test/TestAsset/HydratorStrategyEntityA.php @@ -0,0 +1,75 @@ +entities = array(); + } + + public function addEntity(HydratorStrategyEntityB $entity) + { + $this->entities[] = $entity; + } + + public function getEntities() + { + return $this->entities; + } + + public function setEntities($entities) + { + $this->entities = $entities; + } + + public function getInputFilter() + { + if (!$this->inputFilter) { + $input = new Input(); + $input->setName('entities'); + $input->setRequired(false); + + $this->inputFilter = new InputFilter(); + $this->inputFilter->add($input); + } + + return $this->inputFilter; + } + + public function setInputFilter(InputFilterInterface $inputFilter) + { + $this->inputFilter = $inputFilter; + } + + // Add the getArrayCopy method so we can test the ArraySerializable hydrator: + public function getArrayCopy() + { + return get_object_vars($this); + } + + // Add the populate method so we can test the ArraySerializable hydrator: + public function populate($data) + { + foreach ($data as $name => $value) { + $this->$name = $value; + } + } +} diff --git a/test/TestAsset/HydratorStrategyEntityB.php b/test/TestAsset/HydratorStrategyEntityB.php new file mode 100644 index 000000000..d31f8c73c --- /dev/null +++ b/test/TestAsset/HydratorStrategyEntityB.php @@ -0,0 +1,46 @@ +field1 = $field1; + $this->field2 = $field2; + } + + public function getField1() + { + return $this->field1; + } + + public function getField2() + { + return $this->field2; + } + + public function setField1($value) + { + $this->field1 = $value; + return $this; + } + + public function setField2($value) + { + $this->field2 = $value; + return $this; + } +} diff --git a/test/TestAsset/Reflection.php b/test/TestAsset/Reflection.php new file mode 100644 index 000000000..97ddc1b12 --- /dev/null +++ b/test/TestAsset/Reflection.php @@ -0,0 +1,30 @@ +fooBar; + } + + public function getFooBarBaz() + { + return $this->fooBarBaz; + } +} diff --git a/test/TestAsset/TestOptions.php b/test/TestAsset/TestOptions.php new file mode 100644 index 000000000..a2fbe9842 --- /dev/null +++ b/test/TestAsset/TestOptions.php @@ -0,0 +1,31 @@ +testField = $value; + } + + public function getTestField() + { + return $this->testField; + } +} diff --git a/test/TestAsset/TestOptionsNoStrict.php b/test/TestAsset/TestOptionsNoStrict.php new file mode 100644 index 000000000..cd1a557ba --- /dev/null +++ b/test/TestAsset/TestOptionsNoStrict.php @@ -0,0 +1,33 @@ +testField = $value; + } + + public function getTestField() + { + return $this->testField; + } +} diff --git a/test/_files/alpha b/test/_files/alpha new file mode 100644 index 000000000..e69de29bb diff --git a/test/_files/beta b/test/_files/beta new file mode 100644 index 000000000..e69de29bb diff --git a/test/_files/delta b/test/_files/delta new file mode 100644 index 000000000..e69de29bb diff --git a/test/_files/gamma b/test/_files/gamma new file mode 100644 index 000000000..e69de29bb From 67985b0537e55af8a13fcda22b792f3b60a4e2c2 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Mon, 26 Nov 2012 22:32:42 +0100 Subject: [PATCH 013/127] StringUtils: phpdoc + cs --- src/StringUtils.php | 92 +++++++++++++++++--- src/StringWrapper/AbstractStringWrapper.php | 13 +++ src/StringWrapper/Iconv.php | 13 +++ src/StringWrapper/Intl.php | 13 +++ src/StringWrapper/MbString.php | 13 +++ src/StringWrapper/Native.php | 13 +++ src/StringWrapper/StringWrapperInterface.php | 61 ++++++++++++- 7 files changed, 203 insertions(+), 15 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 4aa7da8c7..2af69f43e 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -1,19 +1,45 @@ Date: Tue, 27 Nov 2012 11:38:07 +0100 Subject: [PATCH 014/127] StringUtils: phpdoc + cs --- src/StringWrapper/AbstractStringWrapper.php | 18 ++++++++-- src/StringWrapper/Iconv.php | 34 ++++++++++++++++++ src/StringWrapper/Intl.php | 34 ++++++++++++++++++ src/StringWrapper/MbString.php | 34 ++++++++++++++++++ src/StringWrapper/Native.php | 38 ++++++++++++++++++++ src/StringWrapper/StringWrapperInterface.php | 3 +- 6 files changed, 157 insertions(+), 4 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index ae849c8a8..9eb122ea6 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -25,21 +25,32 @@ abstract class AbstractStringWrapper implements StringWrapperInterface */ protected $charsets = array(); + /** + * Check if the given charset is supported + * + * @param string $charset + * @return boolean + */ public function isCharsetSupported($charset) { $charset = strtoupper($charset); return in_array($charset, $this->charsets); } + /** + * Get a list of supported charsets + * + * @return string[] + */ public function getSupportedCharsets() { return $this->$charsets; } /** - * Word wrap + * Wraps a string to a given number of characters * - * @param string $string + * @param string $str * @param integer $width * @param string $break * @param boolean $cut @@ -117,7 +128,7 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $cha } /** - * String padding + * Pad a string to a certain length with another string * * @param string $input * @param integer $padLength @@ -167,3 +178,4 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD return $return; } } + diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 56b1f131b..73ba6dcc3 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -46,23 +46,57 @@ public function __construct() } } + /** + * Returns the length of the given string + * + * @param string $str + * @param string $charset + * @return int|false + */ public function strlen($str, $charset = 'UTF-8') { return iconv_strlen($str, $charset); } + /** + * Returns the portion of string specified by the start and length parameters + * + * @param string $str + * @param int $offset + * @param int|null $length + * @param string $charset + * @return string|false + */ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') { return iconv_substr($str, $offset, $length, $charset); } + /** + * Find the position of the first occurrence of a substring in a string + * + * @param string $haystack + * @param string $needle + * @param int $offset + * @param string $charset + * @return int|false + */ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') { return iconv_strpos($haystack, $needle, $offset, $charset); } + /** + * Convert a string from one character encoding to another + * + * @param string $str + * @param string $toCharset + * @param string $fromCharset + * @return string|false + */ public function convert($str, $toCharset, $fromCharset = 'UTF-8') { return iconv($fromCharset, $toCharset, $str); } } + diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index d0a486b0c..e7e789bc5 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -39,6 +39,13 @@ public function __construct() } } + /** + * Returns the length of the given string + * + * @param string $str + * @param string $charset + * @return int|false + */ public function strlen($str, $charset = 'UTF-8') { if (strcasecmp($charset, 'UTF-8') != 0) { @@ -49,6 +56,15 @@ public function strlen($str, $charset = 'UTF-8') return grapheme_strlen($str); } + /** + * Returns the portion of string specified by the start and length parameters + * + * @param string $str + * @param int $offset + * @param int|null $length + * @param string $charset + * @return string|false + */ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') { if (strcasecmp($charset, 'UTF-8') != 0) { @@ -59,6 +75,15 @@ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') return grapheme_substr($str, $offset, $length); } + /** + * Find the position of the first occurrence of a substring in a string + * + * @param string $haystack + * @param string $needle + * @param int $offset + * @param string $charset + * @return int|false + */ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') { if (strcasecmp($charset, 'UTF-8') != 0) { @@ -69,6 +94,14 @@ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') return grapheme_strpos($haystack, $needle, $offset); } + /** + * Convert a string from one character encoding to another + * + * @param string $str + * @param string $toCharset + * @param string $fromCharset + * @return string|false + */ public function convert($str, $toCharset, $fromCharset = 'UTF-8') { if (strcasecmp($toCharset, $fromCharset) != 0) { @@ -79,3 +112,4 @@ public function convert($str, $toCharset, $fromCharset = 'UTF-8') return true; } } + diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 97fcda503..08119bf43 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -48,23 +48,57 @@ public function __construct() } } + /** + * Returns the length of the given string + * + * @param string $str + * @param string $charset + * @return int|false + */ public function strlen($str, $charset = 'UTF-8') { return mb_strlen($str, $charset); } + /** + * Returns the portion of string specified by the start and length parameters + * + * @param string $str + * @param int $offset + * @param int|null $length + * @param string $charset + * @return string|false + */ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') { return mb_substr($str, $offset, $length, $charset); } + /** + * Find the position of the first occurrence of a substring in a string + * + * @param string $haystack + * @param string $needle + * @param int $offset + * @param string $charset + * @return int|false + */ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') { return mb_strpos($haystack, $needle, $offset, $charset); } + /** + * Convert a string from one character encoding to another + * + * @param string $str + * @param string $toCharset + * @param string $fromCharset + * @return string|false + */ public function convert($str, $toCharset, $fromCharset = 'UTF-8') { return mb_convert_encoding($str, $toCharset, $fromCharset); } } + diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index b24b2f369..eb6a03ebc 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -19,28 +19,66 @@ */ class Native extends AbstractStringWrapper { + + /** + * Constructor + */ public function __construct() { $this->charsets = StringUtils::getSingleByteCharsets(); } + /** + * Returns the length of the given string + * + * @param string $str + * @param string $charset + * @return int|false + */ public function strlen($str, $charset = 'UTF-8') { return strlen($str); } + /** + * Returns the portion of string specified by the start and length parameters + * + * @param string $str + * @param int $offset + * @param int|null $length + * @param string $charset + * @return string|false + */ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') { return substr($str, $offset, $length); } + /** + * Find the position of the first occurrence of a substring in a string + * + * @param string $haystack + * @param string $needle + * @param int $offset + * @param string $charset + * @return int|false + */ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') { return strpos($haystack, $needle, $offset); } + /** + * Convert a string from one character encoding to another + * + * @param string $str + * @param string $toCharset + * @param string $fromCharset + * @return string|false + */ public function convert($str, $toCharset, $fromCharset = 'UTF-8') { return false; } } + diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index 6a05b1a10..eb7b80bbb 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -38,7 +38,7 @@ public function getSupportedCharsets(); * * @param string $str * @param string $charset - * @return int + * @return int|false */ public function strlen($str, $charset = 'UTF-8'); @@ -98,3 +98,4 @@ public function wordWrap($str, $width = 75, $break = "\n", $cut = false, $charse */ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $charset = 'UTF-8'); } + From 069b5b04a8db038b74438f178b2940f1fd79af88 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Tue, 27 Nov 2012 12:32:42 +0100 Subject: [PATCH 015/127] StringUtils: added tests --- test/StringUtilsTest.php | 79 ++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php index c38e6f221..ea7594679 100644 --- a/test/StringUtilsTest.php +++ b/test/StringUtilsTest.php @@ -22,8 +22,8 @@ namespace ZendTest\Stdlib; -use PHPUnit_Framework_TestCase as TestCase, - Zend\Stdlib\StringUtils; +use PHPUnit_Framework_TestCase as TestCase; +use Zend\Stdlib\StringUtils; class StringUtilsTest extends TestCase { @@ -47,24 +47,32 @@ public function tearDown() } - public function singleByCharsets() + public function getSingleByCharsets() { return array( array('AscII'), + array('7bit'), + array('8bit'), array('ISo-8859-1'), - ); - } - - public function nonSingleByteCharsets() - { - return array( - array('UTf-8'), - array('usC-2') + array('ISo-8859-2'), + array('ISo-8859-3'), + array('ISo-8859-4'), + array('ISo-8859-5'), + array('ISo-8859-6'), + array('ISo-8859-7'), + array('ISo-8859-8'), + array('ISo-8859-9'), + array('ISo-8859-10'), + array('ISo-8859-11'), + array('ISo-8859-13'), + array('ISo-8859-14'), + array('ISo-8859-15'), + array('ISo-8859-16'), ); } /** - * @dataProvider singleByCharsets + * @dataProvider getSingleByCharsets * @param string $charset */ public function testIsSingleByteCharsetReturnsTrue($charset) @@ -72,8 +80,18 @@ public function testIsSingleByteCharsetReturnsTrue($charset) $this->assertTrue(StringUtils::isSingleByteCharset($charset)); } + public function getNonSingleByteCharsets() + { + return array( + array('UTf-8'), + array('UTf-16'), + array('usC-2'), + array('CESU-8'), + ); + } + /** - * @dataProvider nonSingleByteCharsets + * @dataProvider getNonSingleByteCharsets * @param string $charset */ public function testIsSingleByteCharsetReturnsFalse($charset) @@ -118,10 +136,41 @@ public function testGetWrapper() $this->assertInstanceOf('Zend\Stdlib\StringWrapper\Iconv', $wrapper); } } catch (Exception $e) { - if (extension_loaded('mbstring') || extension_loaded('iconv') - ) { + if (extension_loaded('mbstring') || extension_loaded('iconv')) { $this->fail("Failed to get mbstring or iconv wrapper for UTF-8 and ISO-8859-1"); } } } + + public function getUtf8StringValidity() + { + return array( + // valid + array('', true), + array("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + . "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + . ' !"#$%&\'()*+,-./0123456789:;<=>?' + . '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' + . '`abcdefghijklmnopqrstuvwxyz{|}~', + true + ), + + // invalid + array(true, false), + array(123, false), + array(123.45, false), + array("\xFF", false), + array("\x90a", false), + ); + } + + /** + * @dataProvider getUtf8StringValidity + * @param string $str + * @param boolean $valid + */ + public function testIsValidUtf8($str, $valid) + { + $this->assertSame($valid, StringUtils::isValidUtf8($str)); + } } From 1d18478c3a706ddc05ed33209615038277028827 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Tue, 27 Nov 2012 12:33:51 +0100 Subject: [PATCH 016/127] StringUtilsTest: updated phpdoc --- test/StringUtilsTest.php | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php index ea7594679..94fcdd895 100644 --- a/test/StringUtilsTest.php +++ b/test/StringUtilsTest.php @@ -1,23 +1,11 @@ Date: Tue, 27 Nov 2012 12:48:25 +0100 Subject: [PATCH 017/127] StringUtils: cs --- src/StringUtils.php | 1 - src/StringWrapper/AbstractStringWrapper.php | 1 - src/StringWrapper/Iconv.php | 1 - src/StringWrapper/Intl.php | 1 - src/StringWrapper/MbString.php | 1 - src/StringWrapper/Native.php | 1 - src/StringWrapper/StringWrapperInterface.php | 1 - 7 files changed, 7 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 2af69f43e..a854d4ab1 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -164,4 +164,3 @@ public static function isValidUtf8($str) return is_string($str) && ($str === '' || preg_match('/^./su', $str) == 1); } } - diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 9eb122ea6..62e38a270 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -178,4 +178,3 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD return $return; } } - diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 73ba6dcc3..0e930c57d 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -99,4 +99,3 @@ public function convert($str, $toCharset, $fromCharset = 'UTF-8') return iconv($fromCharset, $toCharset, $str); } } - diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index e7e789bc5..b6954015b 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -112,4 +112,3 @@ public function convert($str, $toCharset, $fromCharset = 'UTF-8') return true; } } - diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 08119bf43..dfe2fbce4 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -101,4 +101,3 @@ public function convert($str, $toCharset, $fromCharset = 'UTF-8') return mb_convert_encoding($str, $toCharset, $fromCharset); } } - diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index eb6a03ebc..7854fa93a 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -81,4 +81,3 @@ public function convert($str, $toCharset, $fromCharset = 'UTF-8') return false; } } - diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index eb7b80bbb..f78da2e4d 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -98,4 +98,3 @@ public function wordWrap($str, $width = 75, $break = "\n", $cut = false, $charse */ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $charset = 'UTF-8'); } - From 7a4f013b8d5af52721486c9e69b47852d5342f98 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 15:13:42 +0100 Subject: [PATCH 018/127] StringUtils: tests + fixes + supported encodings for iconv and mbstring --- src/StringWrapper/AbstractStringWrapper.php | 15 +- src/StringWrapper/Iconv.php | 97 +++++- src/StringWrapper/Intl.php | 3 +- src/StringWrapper/MbString.php | 107 ++++++- src/StringWrapper/Native.php | 7 +- .../StringWrapper/CommonStringWrapperTest.php | 302 ++++++++++++++++++ test/StringWrapper/IconvTest.php | 34 ++ test/StringWrapper/IntlTest.php | 34 ++ test/StringWrapper/MbStringTest.php | 34 ++ test/StringWrapper/NativeTest.php | 24 ++ 10 files changed, 637 insertions(+), 20 deletions(-) create mode 100644 test/StringWrapper/CommonStringWrapperTest.php create mode 100644 test/StringWrapper/IconvTest.php create mode 100644 test/StringWrapper/IntlTest.php create mode 100644 test/StringWrapper/MbStringTest.php create mode 100644 test/StringWrapper/NativeTest.php diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 62e38a270..07298335a 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -10,6 +10,9 @@ namespace Zend\Stdlib\StringWrapper; +use Zend\Stdlib\Exception; +use Zend\Stdlib\StringUtils; + /** * @category Zend * @package Zend_Stdlib @@ -75,7 +78,11 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $cha throw new Exception\InvalidArgumentException('Cannot force cut when width is zero'); } - $charset = strtoupper($charset); + $charset = strtoupper($charset); + if (StringUtils::isSingleByteCharset($charset)) { + return wordwrap($string, $width, $break, $cut); + } + $stringWidth = $this->strlen($string, $charset); $breakWidth = $this->strlen($break, $charset); @@ -139,7 +146,11 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $cha */ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $charset = 'UTF-8') { - $charset = strtoupper($charset); + $charset = strtoupper($charset); + if (StringUtils::isSingleByteCharset($charset)) { + return str_pad($input, $padLength, $padString, $padType); + } + $return = ''; $lengthOfPadding = $padLength - $this->strlen($input, $charset); $padStringLength = $this->strlen($padString, $charset); diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 0e930c57d..887097333 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -17,19 +17,102 @@ */ class Iconv extends AbstractStringWrapper { - /** * List of supported character sets (upper case) * * @var string[] - * @link http://php.net/manual/mbstring.supported-encodings.php + * @link http://www.gnu.org/software/libiconv/ */ protected $charsets = array( - 'ASCII', '7BIT', '8BIT', - 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', - 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', - 'ISO-8859-11', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', - 'UTF-8', // TODO + // European languages + 'ASCII', + 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-7', + 'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', + 'KOI8-R', 'KOI8-U', 'KOI8-RU', + 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254' ,'CP1257', + 'CP850', 'CP866', 'CP1131', + 'MACROMAN', 'MACCENTRALEUROPE', 'MACICELAND', 'MACCROATIAN', 'MACROMANIA', + 'MACCYRILLIC', 'MACUKRAINE', 'MACGREEK', 'MACTURKISH', + 'MACINTOSH', + + // Semitic languages + 'ISO-8859-6', 'ISO-8859-8', + 'CP1255' , 'CP1256', 'CP862', + 'MACHEBREW', 'MACARABIC', + + // Japanese + 'EUC-JP', 'SHIFT_JIS', 'CP932', 'ISO-2022-JP', 'ISO-2022-JP-2', 'ISO-2022-JP-1', + + // Chinese + 'EUC-CN', 'HZ', 'GBK', 'CP936', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', + 'BIG5-HKSCS', 'BIG5-HKSCS:2004', 'BIG5-HKSCS:2001', 'BIG5-HKSCS:1999', + 'ISO-2022-CN', 'ISO-2022-CN-EXT', + + // Korean + 'EUC-KR', 'CP949', 'ISO-2022-KR', 'JOHAB', + + // Armenian + 'ARMSCII-8', + + // Georgian + 'GEORGIAN-ACADEMY', 'GEORGIAN-PS', + + // Tajik + 'KOI8-T', + + // Kazakh + 'PT154', 'RK1048', + + // Thai + 'ISO-8859-11', 'TIS-620', 'CP874', 'MACTHAI', + + // Laotian + 'MULELAO-1', 'CP1133', + + // Vietnamese + 'VISCII', 'TCVN', 'CP1258', + + // Platform specifics + 'HP-ROMAN8', 'NEXTSTEP', + + // Full Unicode + 'UTF-8', + 'UCS-2', 'UCS-2BE', 'UCS-2LE', + 'UCS-4', 'UCS-4BE', 'UCS-4LE', + 'UTF-16', 'UTF-16BE', 'UTF-16LE', + 'UTF-32', 'UTF-32BE', 'UTF-32LE', + 'UTF-7', + 'C99', 'JAVA', + + // Full Unicode, in terms of uint16_t or uint32_t (with machine dependent endianness and alignment) + // 'UCS-2-INTERNAL', 'UCS-4-INTERNAL', + + // Locale dependent, in terms of `char' or `wchar_t' (with machine dependent endianness and alignment, + // and with OS and locale dependent semantics) + // 'char', 'wchar_t', + // '', // The empty encoding name is equivalent to "char": it denotes the locale dependent character encoding. + + // When configured with the option --enable-extra-encodings, + // it also provides support for a few extra encodings: + + // European languages + 'CP437', 'CP737', 'CP775', 'CP852', 'CP853', 'CP855', 'CP857', 'CP858', + 'CP860', 'CP861', 'CP863', 'CP865', 'CP869', 'CP1125', + + // Semitic languages + 'CP864', + + // Japanese + 'EUC-JISX0213', 'Shift_JISX0213', 'ISO-2022-JP-3', + + // Chinese + 'BIG5-2003', // (experimental) + + // Turkmen + 'TDS565', + + // Platform specifics + 'ATARIST', 'RISCOS-LATIN1', ); /** diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index b6954015b..71a9919d9 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -17,7 +17,6 @@ */ class Intl extends AbstractStringWrapper { - /** * List of supported character sets (upper case) * @@ -109,6 +108,6 @@ public function convert($str, $toCharset, $fromCharset = 'UTF-8') return false; } - return true; + return $str; } } diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index dfe2fbce4..60bb257b6 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -17,7 +17,6 @@ */ class MbString extends AbstractStringWrapper { - /** * List of supported character sets (upper case) * @@ -25,13 +24,81 @@ class MbString extends AbstractStringWrapper * @link http://php.net/manual/mbstring.supported-encodings.php */ protected $charsets = array( - 'ASCII', '7BIT', '8BIT', - 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', - 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', - 'ISO-8859-11', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', - 'UCS-4', 'UCS-4BE', 'UCS-4LE', - 'UCS-2', 'UCS-2BE', 'UCS-2LE', - 'UTF-8', // TODO + 'UCS-4', + 'UCS-4BE', + 'UCS-4LE', + 'UCS-2', + 'UCS-2BE', + 'UCS-2LE', + 'UTF-32', + 'UTF-32BE', + 'UTF-32LE', + 'UTF-16', + 'UTF-16BE', + 'UTF-16LE', + 'UTF-7', + 'UTF7-IMAP', + 'UTF-8', + 'ASCII', + 'EUC-JP', + 'SJIS', + 'EUCJP-WIN', + 'SJIS-WIN', + 'ISO-2022-JP', + 'ISO-2022-JP-MS', + 'CP932', + 'CP51932', + 'SJIS-MAC', 'MACJAPANESE', // ** + 'SJIS-Mobile#DOCOMO', 'SJIS-DOCOMO', // ** + 'SJIS-Mobile#KDDI', 'SJIS-KDDI', // ** + 'SJIS-Mobile#SOFTBANK', 'SJIS-SOFTBANK', // ** + 'UTF-8-Mobile#DOCOMO', 'UTF-8-DOCOMO', // ** + 'UTF-8-Mobile#KDDI-A', // ** + 'UTF-8-Mobile#KDDI-B', 'UTF-8-KDDI', // ** + 'UTF-8-Mobile#SOFTBANK', 'UTF-8-SOFTBANK', // ** + 'ISO-2022-JP-MOBILE#KDDI', 'ISO-2022-JP-KDDI', // ** + 'JIS', + 'JIS-MS', + 'CP50220', + 'CP50220RAW', + 'CP50221', + 'CP50222', + 'ISO-8859-1', + 'ISO-8859-2', + 'ISO-8859-3', + 'ISO-8859-4', + 'ISO-8859-5', + 'ISO-8859-6', + 'ISO-8859-7', + 'ISO-8859-8', + 'ISO-8859-9', + 'ISO-8859-10', + 'ISO-8859-13', + 'ISO-8859-14', + 'ISO-8859-15', + // 'ISO-8859-16', + 'bYTE2BE', + 'bYTE2LE', + 'BYTE4BE', + 'BYTE4LE', + 'BASE64', + 'HTML-ENTITIES', + '7BIT', + '8BIT', + 'EUC-CN', + 'CP936', + 'GB18030', // ** + 'HZ', + 'EUC-TW', + 'CP950', + 'BIG-5', + 'EUC-KR', + 'UHC', 'CP949', + 'ISO-2022-KR', + 'WINDOWS-1251', 'CP1251', + 'WINDOWS-1252', 'CP1252', + 'CP866', 'IBM866', + 'KOI8-R' ); /** @@ -46,6 +113,30 @@ public function __construct() 'PHP extension "mbstring" is required for this wrapper' ); } + + // remove charsets not available before PHP-5.4 + if (version_compare(PHP_VERSION, '5.4', '<')) { + unset( + $this->charsets['SJIS-MAC'], + $this->charsets['MACJAPANESE'], + $this->charsets['SJIS-Mobile#DOCOMO'], + $this->charsets['SJIS-DOCOMO'], + $this->charsets['SJIS-Mobile#KDDI'], + $this->charsets['SJIS-KDDI'], + $this->charsets['SJIS-Mobile#SOFTBANK'], + $this->charsets['SJIS-SOFTBANK'], + $this->charsets['UTF-8-Mobile#DOCOMO'], + $this->charsets['UTF-8-DOCOMO'], + $this->charsets['UTF-8-Mobile#KDDI-A'], + $this->charsets['UTF-8-Mobile#KDDI-B'], + $this->charsets['UTF-8-KDDI'], + $this->charsets['UTF-8-Mobile#SOFTBANK'], + $this->charsets['UTF-8-SOFTBANK'], + $this->charsets['ISO-2022-JP-MOBILE#KDDI'], + $this->charsets['ISO-2022-JP-KDDI'], + $this->charsets['GB18030'] + ); + } } /** diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index 7854fa93a..aee15b736 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -78,6 +78,11 @@ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') */ public function convert($str, $toCharset, $fromCharset = 'UTF-8') { - return false; + if (strcasecmp($toCharset, $fromCharset) != 0) { + trigger_error("Can't convert '{$fromCharset}' to '{$toCharset}' using intl", E_WARNING); + return false; + } + + return $str; } } diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php new file mode 100644 index 000000000..ef44b2aef --- /dev/null +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -0,0 +1,302 @@ +stringWrapper instanceof StringWrapperInterface) ) { + $this->fail(sprintf( + "%s isn't an instance of %s", + get_class($this) . '::stringWrapper', + 'Zend\Stdlib\StringWrapper\StringWrapperInterface' + )); + } + } + + public function strlenProvider() + { + return array( + array('abcdefghijklmnopqrstuvwxyz', 'ascii', 26), + array('abcdefghijklmnopqrstuvwxyz', 'utf-8', 26), + array('äöüß', 'utf-8', 4), + ); + } + + /** + * @dataProvider strlenProvider + * @param string $string + * @param string $charset + * @param mixed $expected + */ + public function testStrlen($str, $charset, $expected) + { + if (!$this->stringWrapper->isCharsetSupported($charset)) { + $this->markTestSkipped( + "Charset {$charset} not supported by " . get_class($this->stringWrapper) + ); + } + + $result = $this->stringWrapper->strlen($str, $charset); + $this->assertSame($expected, $result); + } + + public function substrProvider() + { + return array( + array('abcdefghijkl', 1, 5, 'ascii', 'bcdef'), + array('abcdefghijkl', 1, 5, 'utf-8', 'bcdef'), + array('äöüß', 1, 2, 'utf-8', 'öü'), + ); + } + + /** + * @dataProvider substrProvider + * @param string $str + * @param int $offset + * @param int|null $length + * @param string $charset + * @param mixed $expected + */ + public function testSubstr($str, $offset, $length, $charset, $expected) + { + if (!$this->stringWrapper->isCharsetSupported($charset)) { + $this->markTestSkipped( + "Charset {$charset} not supported by " . get_class($this->stringWrapper) + ); + } + + $result = $this->stringWrapper->substr($str, $offset, $length, $charset); + $this->assertSame($expected, $result); + } + + public function strposProvider() + { + return array( + array('abcdefghijkl', 'g', 3, 'ascii', 6), + array('abcdefghijkl', 'g', 3, 'utf-8', 6), + array('äöüß', 'ü', 1, 'utf-8', 2), + ); + } + + /** + * @dataProvider strposProvider + * @param string $haystack + * @param string $needle + * @param int $offset + * @param string $charset + * @param mixed $expected + */ + public function testStrpos($haystack, $needle, $offset, $charset, $expected) + { + if (!$this->stringWrapper->isCharsetSupported($charset)) { + $this->markTestSkipped( + "Charset {$charset} not supported by " . get_class($this->stringWrapper) + ); + } + + $result = $this->stringWrapper->strpos($haystack, $needle, $offset, $charset); + $this->assertSame($expected, $result); + } + + public function convertProvider() + { + return array( + array('abc', 'ascii', 'ascii', 'abc'), + array('abc', 'utf-8', 'ascii', 'abc'), + array('abc', 'ascii', 'utf-8', 'abc'), + array('€', 'iso-8859-15', 'utf-8', "\xA4"), + array('€', 'iso-8859-16', 'utf-8', "\xA4"), // ISO-8859-16 is wrong @ mbstring + ); + } + + /** + * @dataProvider convertProvider + * @param string $str + * @param string $toCharset + * @param string $fromCharset + * @param mixed $expected + */ + public function testConvert($str, $toCharset, $fromCharset, $expected) + { + if (!$this->stringWrapper->isCharsetSupported($toCharset)) { + $this->markTestSkipped( + "Charset {$toCharset} not supported by " . get_class($this->stringWrapper) + ); + } elseif (!$this->stringWrapper->isCharsetSupported($fromCharset)) { + $this->markTestSkipped( + "Charset {$fromCharset} not supported by " . get_class($this->stringWrapper) + ); + } + + $result = $this->stringWrapper->convert($str, $toCharset, $fromCharset); + $this->assertSame($expected, $result); + } + + public function wordWrapProvider() + { + return array( + // Standard cut tests + array('äbüöcß', 2, ' ', true, 'utf-8', + 'äb üö cß'), + array('äbüöc ß äbüöcß', 2, ' ', true, 'utf-8', + 'äb üö c ß äb üö cß'), + array('Ä very long wöööööööööööörd.', 8, "\n", true, 'utf-8', + "Ä very\nlong\nwööööööö\nööööörd."), + array("Ä very\nlong wöööööööööööörd.", 8, "\n", false, 'utf-8', + "Ä very\nlong\nwöööööööööööörd."), + array("Ä very
long wöö
öööööööö
öörd.", 8, '
', false, 'utf-8', + "Ä very
long wöö
öööööööö
öörd."), + + // Alternative cut tests + array(' äüöäöü', 3, ' ', true, 'utf-8', + ' äüö äöü'), + array('äüöäöü ', 3, ' ', true, 'utf-8', + 'äüö äöü '), + array('äöüäöü ', 3, '-', true, 'utf-8', + 'äöü-äöü-'), + array('äüöäöü ', 3, ' ', true, 'utf-8', + 'äüö äöü '), + array('12345 ', 5, '-', false, 'utf-8', + '12345-'), + array('12345 ', 5, '-', false, 'utf-8', + '12345- '), + array('äüöäöü ', 3, ' ', true, 'utf-8', + 'äüö äöü '), + array('äüöäöü--', 3, '-', true, 'utf-8', + 'äüö-äöü--'), + array("äbü\töcß", 3, ' ', true, 'utf-8', + "äbü \töc ß"), + array("äbü\nößt", 3, ' ', true, 'utf-8', + "äbü \nöß t"), + array("äbü\nößte", 3, "\n", true, 'utf-8', + "äbü\nößt\ne"), + + // Break cut tests + array('foobar-foofoofoo', 8, '-', true, 'ascii', + 'foobar-foofoofo-o'), + array('foobar-foobar', 6, '-', true, 'ascii', + 'foobar-foobar'), + array('foobar-foobar', 7, '-', true, 'ascii', + 'foobar-foobar'), + array('foobar-', 7, '-', true, 'ascii', + 'foobar-'), + array('foobar-foobar', 5, '-', true, 'ascii', + 'fooba-r-fooba-r'), + + // Standard no-cut tests + array('äbüöcß', 2, ' ', false, 'utf-8', + 'äbüöcß'), + array('äbüöc ß äbüöcß', 2, "\n", false, 'utf-8', + "äbüöc\nß\näbüöcß"), + array('äöü äöü äöü', 5, "\n", false, 'utf-8', + "äöü\näöü\näöü"), + + // Break no-cut tests + array('foobar-foofoofoo', 8, '-', false, 'ascii', + 'foobar-foofoofoo'), + array('foobar-foobar', 6, '-', false, 'ascii', + 'foobar-foobar'), + array('foobar-foobar', 7, '-', false, 'ascii', + 'foobar-foobar'), + array('foobar-', 7, '-', false, 'ascii', + 'foobar-'), + array('foobar-foobar', 5, '-', false, 'ascii', + 'foobar-foobar'), + ); + } + + /** + * @dataProvider wordWrapProvider + * @param string $str + * @param integer $width + * @param string $break + * @param boolean $cut + * @param string $charset + * @param mixed $expected + */ + public function testWordWrap($string, $width, $break, $cut, $charset, $expected) + { + if (!$this->stringWrapper->isCharsetSupported($charset)) { + $this->markTestSkipped( + "Charset {$charset} not supported by " . get_class($this->stringWrapper) + ); + } + + $result = $this->stringWrapper->wordWrap($string, $width, $break, $cut, $charset); + $this->assertSame($expected, $result); + } + + public function testWordWrapInvalidArgument() + { + $this->setExpectedException( + 'Zend\Stdlib\Exception\InvalidArgumentException', + "Cannot force cut when width is zero" + ); + $this->stringWrapper->wordWrap('a', 0, "\n", true); + } + + public function strPadProvider() + { + return array( + // single-byte + array('aaa', 5, 'o', STR_PAD_LEFT, 'ascii', 'ooaaa'), + array('aaa', 6, 'o', STR_PAD_BOTH, 'ascii', 'oaaaoo'), + array('aaa', 5, 'o', STR_PAD_RIGHT, 'ascii', 'aaaoo'), + + // multi-byte + array('äää', 5, 'ö', STR_PAD_LEFT, 'utf-8', 'ööäää'), + array('äää', 6, 'ö', STR_PAD_BOTH, 'utf-8', 'öäääöö'), + array('äää', 5, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), + + // ZF-12186 + array('äääöö', 2, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), // PadInputLongerThanPadLength + array('äääöö', 5, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), // PadInputSameAsPadLength + array('äääöö', -2, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), // PadNegativePadLength + ); + } + + /** + * @dataProvider strPadProvider + * @param string $input + * @param integer $padLength + * @param string $padString + * @param integer $padType + * @param string $charset + * @param mixed $expected + * + * @group ZF-12186 + */ + public function testStrPad($input, $padLength, $padString, $padType, $charset, $expected) + { + if (!$this->stringWrapper->isCharsetSupported($charset)) { + $this->markTestSkipped( + "Charset {$charset} not supported by " . get_class($this->stringWrapper) + ); + } + + $result = $this->stringWrapper->strPad($input, $padLength, $padString, $padType, $charset); + $this->assertSame($expected, $result); + } +} diff --git a/test/StringWrapper/IconvTest.php b/test/StringWrapper/IconvTest.php new file mode 100644 index 000000000..92a83e1c6 --- /dev/null +++ b/test/StringWrapper/IconvTest.php @@ -0,0 +1,34 @@ +fail('Missing expected Zend\Stdlib\Exception\ExtensionNotLoadedException'); + } catch (Exception\ExtensionNotLoadedException $e) { + $this->markTestSkipped('Missing ext/iconv'); + } + } + + $this->stringWrapper = new Iconv(); + parent::setUp(); + } +} diff --git a/test/StringWrapper/IntlTest.php b/test/StringWrapper/IntlTest.php new file mode 100644 index 000000000..f764b3d98 --- /dev/null +++ b/test/StringWrapper/IntlTest.php @@ -0,0 +1,34 @@ +fail('Missing expected Zend\Stdlib\Exception\ExtensionNotLoadedException'); + } catch (Exception\ExtensionNotLoadedException $e) { + $this->markTestSkipped('Missing ext/intl'); + } + } + + $this->stringWrapper = new Intl(); + parent::setUp(); + } +} diff --git a/test/StringWrapper/MbStringTest.php b/test/StringWrapper/MbStringTest.php new file mode 100644 index 000000000..bd6ee7aec --- /dev/null +++ b/test/StringWrapper/MbStringTest.php @@ -0,0 +1,34 @@ +fail('Missing expected Zend\Stdlib\Exception\ExtensionNotLoadedException'); + } catch (Exception\ExtensionNotLoadedException $e) { + $this->markTestSkipped('Missing ext/mbstring'); + } + } + + $this->stringWrapper = new MbString(); + parent::setUp(); + } +} diff --git a/test/StringWrapper/NativeTest.php b/test/StringWrapper/NativeTest.php new file mode 100644 index 000000000..329a19ba3 --- /dev/null +++ b/test/StringWrapper/NativeTest.php @@ -0,0 +1,24 @@ +stringWrapper = new Native(); + parent::setUp(); + } +} From ccbf706dbd67cc87e5df098d9441b79f02843756 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 15:35:05 +0100 Subject: [PATCH 019/127] StringUtils: wording: charset -> encoding --- src/StringUtils.php | 36 +++++----- src/StringWrapper/AbstractStringWrapper.php | 62 ++++++++--------- src/StringWrapper/Iconv.php | 28 ++++---- src/StringWrapper/Intl.php | 36 +++++----- src/StringWrapper/MbString.php | 66 +++++++++---------- src/StringWrapper/Native.php | 24 +++---- src/StringWrapper/StringWrapperInterface.php | 36 +++++----- test/StringUtilsTest.php | 20 +++--- .../StringWrapper/CommonStringWrapperTest.php | 66 +++++++++---------- 9 files changed, 187 insertions(+), 187 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index a854d4ab1..6aa3f7937 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -36,11 +36,11 @@ abstract class StringUtils protected static $wrapperRegistry; /** - * A list of known single-byte charsets (upper-case) + * A list of known single-byte encodings (upper-case) * * @var string[] */ - protected static $singleByteCharsets = array( + protected static $singleByteEncodings = array( 'ASCII', '7BIT', '8BIT', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', @@ -106,20 +106,20 @@ public static function unregisterWrapper(StringWrapperInterface $wrapper) } /** - * Get the first string wrapper supporting one or more charsets + * Get the first string wrapper supporting one or more encodings * - * @param string $charset Charset supported by he string wrapper - * @param string $charsetN, ... Unlimited OPTIONAL number of additional charsets + * @param string $encoding Encoding supported by he string wrapper + * @param string $encodingN, ... Unlimited OPTIONAL number of additional encodings * @return StringWrapperInterface - * @throws Exception\RuntimeException If no wrapper supports all given charsets + * @throws Exception\RuntimeException If no wrapper supports all given encodings */ - public static function getWrapper($charset = 'UTF-8') + public static function getWrapper($encoding = 'UTF-8') { - $charsets = func_get_args(); + $$encodings = func_get_args(); foreach (static::getRegisteredWrappers() as $wrapper) { - foreach ($charsets as $charset) { - if (!$wrapper->isCharsetSupported($charset)) { + foreach ($encodings as $encoding) { + if (!$wrapper->isEncodingSupported($encoding)) { continue 2; } } @@ -128,29 +128,29 @@ public static function getWrapper($charset = 'UTF-8') } throw new Exception\RuntimeException( - 'No wrapper found supporting charset(s) ' . implode(', ', $charsets) + 'No wrapper found supporting encoding(s) ' . implode(', ', $encodings) ); } /** - * Get a list of all known single-byte charsets + * Get a list of all known single-byte encodings * * @return string[] */ - public static function getSingleByteCharsets() + public static function getSingleByteEncodings() { - return static::$singleByteCharsets; + return static::$singleByteEncodings; } /** - * Check if a given charset is a known single-byte charset + * Check if a given encoding is a known single-byte encoding * - * @param string $charset + * @param string $encoding * @return boolean */ - public static function isSingleByteCharset($charset) + public static function isSingleByteEncoding($encoding) { - return in_array(strtoupper($charset), static::$singleByteCharsets); + return in_array(strtoupper($encoding), static::$singleByteEncodings); } /** diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 07298335a..1f0bd2bbb 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -26,28 +26,28 @@ abstract class AbstractStringWrapper implements StringWrapperInterface * * @var string[] */ - protected $charsets = array(); + protected $encodings = array(); /** - * Check if the given charset is supported + * Check if the given encoding is supported * - * @param string $charset + * @param string $encoding * @return boolean */ - public function isCharsetSupported($charset) + public function isEncodingSupported($encoding) { - $charset = strtoupper($charset); - return in_array($charset, $this->charsets); + $encoding = strtoupper($encoding); + return in_array($encoding, $this->encodings); } /** - * Get a list of supported charsets + * Get a list of supported encodings * * @return string[] */ - public function getSupportedCharsets() + public function getSupportedEncodings() { - return $this->$charsets; + return $this->$encodings; } /** @@ -57,10 +57,10 @@ public function getSupportedCharsets() * @param integer $width * @param string $break * @param boolean $cut - * @param string $charset + * @param string $encoding * @return string */ - public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $charset = 'UTF-8') + public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $encoding = 'UTF-8') { $string = (string) $string; if ($string === '') { @@ -78,27 +78,27 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $cha throw new Exception\InvalidArgumentException('Cannot force cut when width is zero'); } - $charset = strtoupper($charset); - if (StringUtils::isSingleByteCharset($charset)) { + $encoding = strtoupper($encoding); + if (StringUtils::isSingleByteEncoding($encoding)) { return wordwrap($string, $width, $break, $cut); } - $stringWidth = $this->strlen($string, $charset); - $breakWidth = $this->strlen($break, $charset); + $stringWidth = $this->strlen($string, $encoding); + $breakWidth = $this->strlen($break, $encoding); $result = ''; $lastStart = $lastSpace = 0; for ($current = 0; $current < $stringWidth; $current++) { - $char = $this->substr($string, $current, 1, $charset); + $char = $this->substr($string, $current, 1, $encoding); $possibleBreak = $char; if ($breakWidth !== 1) { - $possibleBreak = $this->substr($string, $current, $breakWidth, $charset); + $possibleBreak = $this->substr($string, $current, $breakWidth, $encoding); } if ($possibleBreak === $break) { - $result .= $this->substr($string, $lastStart, $current - $lastStart + $breakWidth, $charset); + $result .= $this->substr($string, $lastStart, $current - $lastStart + $breakWidth, $encoding); $current += $breakWidth - 1; $lastStart = $lastSpace = $current + 1; continue; @@ -106,7 +106,7 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $cha if ($char === ' ') { if ($current - $lastStart >= $width) { - $result .= $this->substr($string, $lastStart, $current - $lastStart, $charset) . $break; + $result .= $this->substr($string, $lastStart, $current - $lastStart, $encoding) . $break; $lastStart = $current + 1; } @@ -115,20 +115,20 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $cha } if ($current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) { - $result .= $this->substr($string, $lastStart, $current - $lastStart, $charset) . $break; + $result .= $this->substr($string, $lastStart, $current - $lastStart, $encoding) . $break; $lastStart = $lastSpace = $current; continue; } if ($current - $lastStart >= $width && $lastStart < $lastSpace) { - $result .= $this->substr($string, $lastStart, $lastSpace - $lastStart, $charset) . $break; + $result .= $this->substr($string, $lastStart, $lastSpace - $lastStart, $encoding) . $break; $lastStart = $lastSpace = $lastSpace + 1; continue; } } if ($lastStart !== $current) { - $result .= $this->substr($string, $lastStart, $current - $lastStart, $charset); + $result .= $this->substr($string, $lastStart, $current - $lastStart, $encoding); } return $result; @@ -141,19 +141,19 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $cha * @param integer $padLength * @param string $padString * @param integer $padType - * @param string $charset + * @param string $encoding * @return string */ - public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $charset = 'UTF-8') + public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $encoding = 'UTF-8') { - $charset = strtoupper($charset); - if (StringUtils::isSingleByteCharset($charset)) { + $encoding = strtoupper($encoding); + if (StringUtils::isSingleByteEncoding($encoding)) { return str_pad($input, $padLength, $padString, $padType); } $return = ''; - $lengthOfPadding = $padLength - $this->strlen($input, $charset); - $padStringLength = $this->strlen($padString, $charset); + $lengthOfPadding = $padLength - $this->strlen($input, $encoding); + $padStringLength = $this->strlen($padString, $encoding); if ($padStringLength === 0 || $lengthOfPadding <= 0) { $return = $input; @@ -169,14 +169,14 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD $lastStringLeftLength = $lastStringRightLength = floor($lastStringLength / 2); $lastStringRightLength += $lastStringLength % 2; - $lastStringLeft = $this->substr($padString, 0, $lastStringLeftLength, $charset); - $lastStringRight = $this->substr($padString, 0, $lastStringRightLength, $charset); + $lastStringLeft = $this->substr($padString, 0, $lastStringLeftLength, $encoding); + $lastStringRight = $this->substr($padString, 0, $lastStringRightLength, $encoding); $return = str_repeat($padString, $repeatCountLeft) . $lastStringLeft . $input . str_repeat($padString, $repeatCountRight) . $lastStringRight; } else { - $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength, $charset); + $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength, $encoding); if ($padType === \STR_PAD_LEFT) { $return = str_repeat($padString, $repeatCount) . $lastString . $input; diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 887097333..01be679da 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -23,7 +23,7 @@ class Iconv extends AbstractStringWrapper * @var string[] * @link http://www.gnu.org/software/libiconv/ */ - protected $charsets = array( + protected $encodings = array( // European languages 'ASCII', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-7', @@ -133,12 +133,12 @@ public function __construct() * Returns the length of the given string * * @param string $str - * @param string $charset + * @param string $encoding * @return int|false */ - public function strlen($str, $charset = 'UTF-8') + public function strlen($str, $encoding = 'UTF-8') { - return iconv_strlen($str, $charset); + return iconv_strlen($str, $encoding); } /** @@ -147,12 +147,12 @@ public function strlen($str, $charset = 'UTF-8') * @param string $str * @param int $offset * @param int|null $length - * @param string $charset + * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') + public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') { - return iconv_substr($str, $offset, $length, $charset); + return iconv_substr($str, $offset, $length, $encoding); } /** @@ -161,24 +161,24 @@ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') * @param string $haystack * @param string $needle * @param int $offset - * @param string $charset + * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') { - return iconv_strpos($haystack, $needle, $offset, $charset); + return iconv_strpos($haystack, $needle, $offset, $encoding); } /** * Convert a string from one character encoding to another * * @param string $str - * @param string $toCharset - * @param string $fromCharset + * @param string $toEncoding + * @param string $fromEncoding * @return string|false */ - public function convert($str, $toCharset, $fromCharset = 'UTF-8') + public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') { - return iconv($fromCharset, $toCharset, $str); + return iconv($fromEncoding, $toEncoding, $str); } } diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index 71a9919d9..490ce7688 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -22,7 +22,7 @@ class Intl extends AbstractStringWrapper * * @var string[] */ - protected $charsets = array('UTF-8'); + protected $encodings = array('UTF-8'); /** * Constructor @@ -42,13 +42,13 @@ public function __construct() * Returns the length of the given string * * @param string $str - * @param string $charset + * @param string $encoding * @return int|false */ - public function strlen($str, $charset = 'UTF-8') + public function strlen($str, $encoding = 'UTF-8') { - if (strcasecmp($charset, 'UTF-8') != 0) { - trigger_error("Character set '{$charset}' not supported by intl"); + if (strcasecmp($encoding, 'UTF-8') != 0) { + trigger_error("Character set '{$encoding}' not supported by intl"); return false; } @@ -61,13 +61,13 @@ public function strlen($str, $charset = 'UTF-8') * @param string $str * @param int $offset * @param int|null $length - * @param string $charset + * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') + public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') { - if (strcasecmp($charset, 'UTF-8') != 0) { - trigger_error("Character set '{$charset}' not supported by intl"); + if (strcasecmp($encoding, 'UTF-8') != 0) { + trigger_error("Character set '{$encoding}' not supported by intl"); return false; } @@ -80,13 +80,13 @@ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') * @param string $haystack * @param string $needle * @param int $offset - * @param string $charset + * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') { - if (strcasecmp($charset, 'UTF-8') != 0) { - trigger_error("Character set '{$charset}' not supported by intl"); + if (strcasecmp($encoding, 'UTF-8') != 0) { + trigger_error("Character set '{$encoding}' not supported by intl"); return false; } @@ -97,14 +97,14 @@ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') * Convert a string from one character encoding to another * * @param string $str - * @param string $toCharset - * @param string $fromCharset + * @param string $toEncoding + * @param string $fromEncoding * @return string|false */ - public function convert($str, $toCharset, $fromCharset = 'UTF-8') + public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') { - if (strcasecmp($toCharset, $fromCharset) != 0) { - trigger_error("Can't convert '{$fromCharset}' to '{$toCharset}' using intl", E_WARNING); + if (strcasecmp($toEncoding, $fromEncoding) != 0) { + trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}' using intl", E_WARNING); return false; } diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 60bb257b6..46b5a88f5 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -23,7 +23,7 @@ class MbString extends AbstractStringWrapper * @var string[] * @link http://php.net/manual/mbstring.supported-encodings.php */ - protected $charsets = array( + protected $encodings = array( 'UCS-4', 'UCS-4BE', 'UCS-4LE', @@ -114,27 +114,27 @@ public function __construct() ); } - // remove charsets not available before PHP-5.4 + // remove encodings not available before PHP-5.4 if (version_compare(PHP_VERSION, '5.4', '<')) { unset( - $this->charsets['SJIS-MAC'], - $this->charsets['MACJAPANESE'], - $this->charsets['SJIS-Mobile#DOCOMO'], - $this->charsets['SJIS-DOCOMO'], - $this->charsets['SJIS-Mobile#KDDI'], - $this->charsets['SJIS-KDDI'], - $this->charsets['SJIS-Mobile#SOFTBANK'], - $this->charsets['SJIS-SOFTBANK'], - $this->charsets['UTF-8-Mobile#DOCOMO'], - $this->charsets['UTF-8-DOCOMO'], - $this->charsets['UTF-8-Mobile#KDDI-A'], - $this->charsets['UTF-8-Mobile#KDDI-B'], - $this->charsets['UTF-8-KDDI'], - $this->charsets['UTF-8-Mobile#SOFTBANK'], - $this->charsets['UTF-8-SOFTBANK'], - $this->charsets['ISO-2022-JP-MOBILE#KDDI'], - $this->charsets['ISO-2022-JP-KDDI'], - $this->charsets['GB18030'] + $this->encodings['SJIS-MAC'], + $this->encodings['MACJAPANESE'], + $this->encodings['SJIS-Mobile#DOCOMO'], + $this->encodings['SJIS-DOCOMO'], + $this->encodings['SJIS-Mobile#KDDI'], + $this->encodings['SJIS-KDDI'], + $this->encodings['SJIS-Mobile#SOFTBANK'], + $this->encodings['SJIS-SOFTBANK'], + $this->encodings['UTF-8-Mobile#DOCOMO'], + $this->encodings['UTF-8-DOCOMO'], + $this->encodings['UTF-8-Mobile#KDDI-A'], + $this->encodings['UTF-8-Mobile#KDDI-B'], + $this->encodings['UTF-8-KDDI'], + $this->encodings['UTF-8-Mobile#SOFTBANK'], + $this->encodings['UTF-8-SOFTBANK'], + $this->encodings['ISO-2022-JP-MOBILE#KDDI'], + $this->encodings['ISO-2022-JP-KDDI'], + $this->encodings['GB18030'] ); } } @@ -143,12 +143,12 @@ public function __construct() * Returns the length of the given string * * @param string $str - * @param string $charset + * @param string $encoding * @return int|false */ - public function strlen($str, $charset = 'UTF-8') + public function strlen($str, $encoding = 'UTF-8') { - return mb_strlen($str, $charset); + return mb_strlen($str, $encoding); } /** @@ -157,12 +157,12 @@ public function strlen($str, $charset = 'UTF-8') * @param string $str * @param int $offset * @param int|null $length - * @param string $charset + * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') + public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') { - return mb_substr($str, $offset, $length, $charset); + return mb_substr($str, $offset, $length, $encoding); } /** @@ -171,24 +171,24 @@ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') * @param string $haystack * @param string $needle * @param int $offset - * @param string $charset + * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') { - return mb_strpos($haystack, $needle, $offset, $charset); + return mb_strpos($haystack, $needle, $offset, $encoding); } /** * Convert a string from one character encoding to another * * @param string $str - * @param string $toCharset - * @param string $fromCharset + * @param string $toEncoding + * @param string $fromEncoding * @return string|false */ - public function convert($str, $toCharset, $fromCharset = 'UTF-8') + public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') { - return mb_convert_encoding($str, $toCharset, $fromCharset); + return mb_convert_encoding($str, $toEncoding, $fromEncoding); } } diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index aee15b736..ed0bf48f6 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -25,17 +25,17 @@ class Native extends AbstractStringWrapper */ public function __construct() { - $this->charsets = StringUtils::getSingleByteCharsets(); + $this->encodings = StringUtils::getSingleByteEncodings(); } /** * Returns the length of the given string * * @param string $str - * @param string $charset + * @param string $encoding * @return int|false */ - public function strlen($str, $charset = 'UTF-8') + public function strlen($str, $encoding = 'UTF-8') { return strlen($str); } @@ -46,10 +46,10 @@ public function strlen($str, $charset = 'UTF-8') * @param string $str * @param int $offset * @param int|null $length - * @param string $charset + * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') + public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') { return substr($str, $offset, $length); } @@ -60,10 +60,10 @@ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8') * @param string $haystack * @param string $needle * @param int $offset - * @param string $charset + * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') { return strpos($haystack, $needle, $offset); } @@ -72,14 +72,14 @@ public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8') * Convert a string from one character encoding to another * * @param string $str - * @param string $toCharset - * @param string $fromCharset + * @param string $toEncoding + * @param string $fromEncoding * @return string|false */ - public function convert($str, $toCharset, $fromCharset = 'UTF-8') + public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') { - if (strcasecmp($toCharset, $fromCharset) != 0) { - trigger_error("Can't convert '{$fromCharset}' to '{$toCharset}' using intl", E_WARNING); + if (strcasecmp($toEncoding, $fromEncoding) != 0) { + trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}' using intl", E_WARNING); return false; } diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index f78da2e4d..3929fb696 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -19,28 +19,28 @@ interface StringWrapperInterface { /** - * Check if the given charset is supported + * Check if the given encoding is supported * - * @param string $charset + * @param string $encoding * @return boolean */ - public function isCharsetSupported($charset); + public function isEncodingSupported($encoding); /** - * Get a list of supported charsets + * Get a list of supported encodings * * @return string[] */ - public function getSupportedCharsets(); + public function getSupportedEncodings(); /** * Returns the length of the given string * * @param string $str - * @param string $charset + * @param string $encoding * @return int|false */ - public function strlen($str, $charset = 'UTF-8'); + public function strlen($str, $encoding = 'UTF-8'); /** * Returns the portion of string specified by the start and length parameters @@ -48,10 +48,10 @@ public function strlen($str, $charset = 'UTF-8'); * @param string $str * @param int $offset * @param int|null $length - * @param string $charset + * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8'); + public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8'); /** * Find the position of the first occurrence of a substring in a string @@ -59,20 +59,20 @@ public function substr($str, $offset = 0, $length = null, $charset = 'UTF-8'); * @param string $haystack * @param string $needle * @param int $offset - * @param string $charset + * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $charset = 'UTF-8'); + public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8'); /** * Convert a string from one character encoding to another * * @param string $str - * @param string $toCharset - * @param string $fromCharset + * @param string $toEncoding + * @param string $fromEncoding * @return string|false */ - public function convert($str, $toCharset, $fromCharset = 'UTF-8'); + public function convert($str, $toEncoding, $fromEncoding = 'UTF-8'); /** * Wraps a string to a given number of characters @@ -81,10 +81,10 @@ public function convert($str, $toCharset, $fromCharset = 'UTF-8'); * @param integer $width * @param string $break * @param boolean $cut - * @param string $charset + * @param string $encoding * @return string */ - public function wordWrap($str, $width = 75, $break = "\n", $cut = false, $charset = 'UTF-8'); + public function wordWrap($str, $width = 75, $break = "\n", $cut = false, $encoding = 'UTF-8'); /** * Pad a string to a certain length with another string @@ -93,8 +93,8 @@ public function wordWrap($str, $width = 75, $break = "\n", $cut = false, $charse * @param integer $padLength * @param string $padString * @param integer $padType - * @param string $charset + * @param string $encoding * @return string */ - public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $charset = 'UTF-8'); + public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $encoding = 'UTF-8'); } diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php index 94fcdd895..156431dde 100644 --- a/test/StringUtilsTest.php +++ b/test/StringUtilsTest.php @@ -35,7 +35,7 @@ public function tearDown() } - public function getSingleByCharsets() + public function getSingleByEncodings() { return array( array('AscII'), @@ -60,15 +60,15 @@ public function getSingleByCharsets() } /** - * @dataProvider getSingleByCharsets - * @param string $charset + * @dataProvider getSingleByEncodings + * @param string $encoding */ - public function testIsSingleByteCharsetReturnsTrue($charset) + public function testIsSingleByteEncodingReturnsTrue($encoding) { - $this->assertTrue(StringUtils::isSingleByteCharset($charset)); + $this->assertTrue(StringUtils::isSingleByteEncoding($encoding)); } - public function getNonSingleByteCharsets() + public function getNonSingleByteEncodings() { return array( array('UTf-8'), @@ -79,12 +79,12 @@ public function getNonSingleByteCharsets() } /** - * @dataProvider getNonSingleByteCharsets - * @param string $charset + * @dataProvider getNonSingleByteEncodings + * @param string $encoding */ - public function testIsSingleByteCharsetReturnsFalse($charset) + public function testIsSingleByteEncodingReturnsFalse($encoding) { - $this->assertFalse(StringUtils::isSingleByteCharset($charset)); + $this->assertFalse(StringUtils::isSingleByteEncoding($encoding)); } public function testGetWrapper() diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php index ef44b2aef..4f606a1ae 100644 --- a/test/StringWrapper/CommonStringWrapperTest.php +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -47,18 +47,18 @@ public function strlenProvider() /** * @dataProvider strlenProvider * @param string $string - * @param string $charset + * @param string $encoding * @param mixed $expected */ - public function testStrlen($str, $charset, $expected) + public function testStrlen($str, $encoding, $expected) { - if (!$this->stringWrapper->isCharsetSupported($charset)) { + if (!$this->stringWrapper->isEncodingSupported($encoding)) { $this->markTestSkipped( - "Charset {$charset} not supported by " . get_class($this->stringWrapper) + "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) ); } - $result = $this->stringWrapper->strlen($str, $charset); + $result = $this->stringWrapper->strlen($str, $encoding); $this->assertSame($expected, $result); } @@ -76,18 +76,18 @@ public function substrProvider() * @param string $str * @param int $offset * @param int|null $length - * @param string $charset + * @param string $encoding * @param mixed $expected */ - public function testSubstr($str, $offset, $length, $charset, $expected) + public function testSubstr($str, $offset, $length, $encoding, $expected) { - if (!$this->stringWrapper->isCharsetSupported($charset)) { + if (!$this->stringWrapper->isEncodingSupported($encoding)) { $this->markTestSkipped( - "Charset {$charset} not supported by " . get_class($this->stringWrapper) + "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) ); } - $result = $this->stringWrapper->substr($str, $offset, $length, $charset); + $result = $this->stringWrapper->substr($str, $offset, $length, $encoding); $this->assertSame($expected, $result); } @@ -105,18 +105,18 @@ public function strposProvider() * @param string $haystack * @param string $needle * @param int $offset - * @param string $charset + * @param string $encoding * @param mixed $expected */ - public function testStrpos($haystack, $needle, $offset, $charset, $expected) + public function testStrpos($haystack, $needle, $offset, $encoding, $expected) { - if (!$this->stringWrapper->isCharsetSupported($charset)) { + if (!$this->stringWrapper->isEncodingSupported($encoding)) { $this->markTestSkipped( - "Charset {$charset} not supported by " . get_class($this->stringWrapper) + "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) ); } - $result = $this->stringWrapper->strpos($haystack, $needle, $offset, $charset); + $result = $this->stringWrapper->strpos($haystack, $needle, $offset, $encoding); $this->assertSame($expected, $result); } @@ -134,23 +134,23 @@ public function convertProvider() /** * @dataProvider convertProvider * @param string $str - * @param string $toCharset - * @param string $fromCharset + * @param string $toEncoding + * @param string $fromEncoding * @param mixed $expected */ - public function testConvert($str, $toCharset, $fromCharset, $expected) + public function testConvert($str, $toEncoding, $fromEncoding, $expected) { - if (!$this->stringWrapper->isCharsetSupported($toCharset)) { + if (!$this->stringWrapper->isEncodingSupported($toEncoding)) { $this->markTestSkipped( - "Charset {$toCharset} not supported by " . get_class($this->stringWrapper) + "Encoding {$toEncoding} not supported by " . get_class($this->stringWrapper) ); - } elseif (!$this->stringWrapper->isCharsetSupported($fromCharset)) { + } elseif (!$this->stringWrapper->isEncodingSupported($fromEncoding)) { $this->markTestSkipped( - "Charset {$fromCharset} not supported by " . get_class($this->stringWrapper) + "Encoding {$fromEncoding} not supported by " . get_class($this->stringWrapper) ); } - $result = $this->stringWrapper->convert($str, $toCharset, $fromCharset); + $result = $this->stringWrapper->convert($str, $toEncoding, $fromEncoding); $this->assertSame($expected, $result); } @@ -233,18 +233,18 @@ public function wordWrapProvider() * @param integer $width * @param string $break * @param boolean $cut - * @param string $charset + * @param string $encoding * @param mixed $expected */ - public function testWordWrap($string, $width, $break, $cut, $charset, $expected) + public function testWordWrap($string, $width, $break, $cut, $encoding, $expected) { - if (!$this->stringWrapper->isCharsetSupported($charset)) { + if (!$this->stringWrapper->isEncodingSupported($encoding)) { $this->markTestSkipped( - "Charset {$charset} not supported by " . get_class($this->stringWrapper) + "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) ); } - $result = $this->stringWrapper->wordWrap($string, $width, $break, $cut, $charset); + $result = $this->stringWrapper->wordWrap($string, $width, $break, $cut, $encoding); $this->assertSame($expected, $result); } @@ -283,20 +283,20 @@ public function strPadProvider() * @param integer $padLength * @param string $padString * @param integer $padType - * @param string $charset + * @param string $encoding * @param mixed $expected * * @group ZF-12186 */ - public function testStrPad($input, $padLength, $padString, $padType, $charset, $expected) + public function testStrPad($input, $padLength, $padString, $padType, $encoding, $expected) { - if (!$this->stringWrapper->isCharsetSupported($charset)) { + if (!$this->stringWrapper->isEncodingSupported($encoding)) { $this->markTestSkipped( - "Charset {$charset} not supported by " . get_class($this->stringWrapper) + "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) ); } - $result = $this->stringWrapper->strPad($input, $padLength, $padString, $padType, $charset); + $result = $this->stringWrapper->strPad($input, $padLength, $padString, $padType, $encoding); $this->assertSame($expected, $result); } } From 77e20ddd17d50bb1398858277df992b42f780b4e Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 15:44:02 +0100 Subject: [PATCH 020/127] fixed wrong typed variable in StringUtils::getWrapper --- src/StringUtils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 6aa3f7937..4714a47fc 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -115,7 +115,7 @@ public static function unregisterWrapper(StringWrapperInterface $wrapper) */ public static function getWrapper($encoding = 'UTF-8') { - $$encodings = func_get_args(); + $encodings = func_get_args(); foreach (static::getRegisteredWrappers() as $wrapper) { foreach ($encodings as $encoding) { From f46ba861aa528dab4f6d04474251958561ae88e3 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 16:20:14 +0100 Subject: [PATCH 021/127] StringUtils: cs --- src/StringUtils.php | 7 +++--- src/StringWrapper/Iconv.php | 4 ++-- src/StringWrapper/Intl.php | 2 +- src/StringWrapper/MbString.php | 24 ++++++++++---------- src/StringWrapper/Native.php | 2 +- src/StringWrapper/StringWrapperInterface.php | 2 +- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 4714a47fc..040ce301f 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -30,14 +30,14 @@ abstract class StringUtils /** * Ordered list of registered string wrapper instances - * + * * @var StringWrapperInterface[] */ protected static $wrapperRegistry; /** * A list of known single-byte encodings (upper-case) - * + * * @var string[] */ protected static $singleByteEncodings = array( @@ -45,9 +45,8 @@ abstract class StringUtils 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-11', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', - 'CP-1251', 'CP-1252' + 'CP-1251', 'CP-1252', // TODO - ); /** diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 01be679da..3de069ed0 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -112,7 +112,7 @@ class Iconv extends AbstractStringWrapper 'TDS565', // Platform specifics - 'ATARIST', 'RISCOS-LATIN1', + 'ATARIST', 'RISCOS-LATIN1', ); /** @@ -143,7 +143,7 @@ public function strlen($str, $encoding = 'UTF-8') /** * Returns the portion of string specified by the start and length parameters - * + * * @param string $str * @param int $offset * @param int|null $length diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index 490ce7688..0a0d2cac8 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -57,7 +57,7 @@ public function strlen($str, $encoding = 'UTF-8') /** * Returns the portion of string specified by the start and length parameters - * + * * @param string $str * @param int $offset * @param int|null $length diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 46b5a88f5..8331ba789 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -48,15 +48,15 @@ class MbString extends AbstractStringWrapper 'ISO-2022-JP-MS', 'CP932', 'CP51932', - 'SJIS-MAC', 'MACJAPANESE', // ** - 'SJIS-Mobile#DOCOMO', 'SJIS-DOCOMO', // ** - 'SJIS-Mobile#KDDI', 'SJIS-KDDI', // ** - 'SJIS-Mobile#SOFTBANK', 'SJIS-SOFTBANK', // ** - 'UTF-8-Mobile#DOCOMO', 'UTF-8-DOCOMO', // ** - 'UTF-8-Mobile#KDDI-A', // ** - 'UTF-8-Mobile#KDDI-B', 'UTF-8-KDDI', // ** - 'UTF-8-Mobile#SOFTBANK', 'UTF-8-SOFTBANK', // ** - 'ISO-2022-JP-MOBILE#KDDI', 'ISO-2022-JP-KDDI', // ** + 'SJIS-MAC', 'MACJAPANESE', + 'SJIS-Mobile#DOCOMO', 'SJIS-DOCOMO', + 'SJIS-Mobile#KDDI', 'SJIS-KDDI', + 'SJIS-Mobile#SOFTBANK', 'SJIS-SOFTBANK', + 'UTF-8-Mobile#DOCOMO', 'UTF-8-DOCOMO', + 'UTF-8-Mobile#KDDI-A', + 'UTF-8-Mobile#KDDI-B', 'UTF-8-KDDI', + 'UTF-8-Mobile#SOFTBANK', 'UTF-8-SOFTBANK', + 'ISO-2022-JP-MOBILE#KDDI', 'ISO-2022-JP-KDDI', 'JIS', 'JIS-MS', 'CP50220', @@ -87,7 +87,7 @@ class MbString extends AbstractStringWrapper '8BIT', 'EUC-CN', 'CP936', - 'GB18030', // ** + 'GB18030', 'HZ', 'EUC-TW', 'CP950', @@ -98,7 +98,7 @@ class MbString extends AbstractStringWrapper 'WINDOWS-1251', 'CP1251', 'WINDOWS-1252', 'CP1252', 'CP866', 'IBM866', - 'KOI8-R' + 'KOI8-R', ); /** @@ -153,7 +153,7 @@ public function strlen($str, $encoding = 'UTF-8') /** * Returns the portion of string specified by the start and length parameters - * + * * @param string $str * @param int $offset * @param int|null $length diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index ed0bf48f6..07601ba52 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -42,7 +42,7 @@ public function strlen($str, $encoding = 'UTF-8') /** * Returns the portion of string specified by the start and length parameters - * + * * @param string $str * @param int $offset * @param int|null $length diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index 3929fb696..c46570383 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -44,7 +44,7 @@ public function strlen($str, $encoding = 'UTF-8'); /** * Returns the portion of string specified by the start and length parameters - * + * * @param string $str * @param int $offset * @param int|null $length From caf59c17f321d5e7e994d96ab96cdf8b695bdfb1 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 16:51:40 +0100 Subject: [PATCH 022/127] StringUtils: implemented basic functionality into AbstractStringWrapper::convert --- src/StringWrapper/AbstractStringWrapper.php | 18 ++++++++++++++++++ src/StringWrapper/Intl.php | 18 ------------------ src/StringWrapper/Native.php | 20 +------------------- 3 files changed, 19 insertions(+), 37 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 1f0bd2bbb..b8fc2b61b 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -50,6 +50,24 @@ public function getSupportedEncodings() return $this->$encodings; } + /** + * Convert a string from one character encoding to another + * + * @param string $str + * @param string $toEncoding + * @param string $fromEncoding + * @return string|false + */ + public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') + { + if (strcasecmp($toEncoding, $fromEncoding) != 0) { + trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}'", E_WARNING); + return false; + } + + return $str; + } + /** * Wraps a string to a given number of characters * diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index 0a0d2cac8..e9c9ae9f5 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -92,22 +92,4 @@ public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') return grapheme_strpos($haystack, $needle, $offset); } - - /** - * Convert a string from one character encoding to another - * - * @param string $str - * @param string $toEncoding - * @param string $fromEncoding - * @return string|false - */ - public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') - { - if (strcasecmp($toEncoding, $fromEncoding) != 0) { - trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}' using intl", E_WARNING); - return false; - } - - return $str; - } } diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index 07601ba52..42b8f4ae5 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -67,22 +67,4 @@ public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') { return strpos($haystack, $needle, $offset); } - - /** - * Convert a string from one character encoding to another - * - * @param string $str - * @param string $toEncoding - * @param string $fromEncoding - * @return string|false - */ - public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') - { - if (strcasecmp($toEncoding, $fromEncoding) != 0) { - trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}' using intl", E_WARNING); - return false; - } - - return $str; - } -} +} From 1e3bb8471400d2ac6b3c3ed14ef16fa20ea97b0c Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 17:37:30 +0100 Subject: [PATCH 023/127] StringUtils: hopefully a little better encoding list --- src/StringWrapper/AbstractStringWrapper.php | 33 ++++++++++++++++----- src/StringWrapper/Iconv.php | 11 ++++--- src/StringWrapper/Native.php | 18 +++++++++-- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index b8fc2b61b..2ba662966 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -22,32 +22,31 @@ abstract class AbstractStringWrapper implements StringWrapperInterface { /** - * List of supported character sets (upper case) + * List of supported character encodings (upper case) * * @var string[] */ protected $encodings = array(); /** - * Check if the given encoding is supported + * Check if the given character encoding is supported * * @param string $encoding * @return boolean */ public function isEncodingSupported($encoding) { - $encoding = strtoupper($encoding); - return in_array($encoding, $this->encodings); + return in_array(strtoupper($encoding), $this->encodings); } /** - * Get a list of supported encodings + * Get a list of supported character encodings * * @return string[] */ public function getSupportedEncodings() { - return $this->$encodings; + return $this->encodings; } /** @@ -61,7 +60,7 @@ public function getSupportedEncodings() public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') { if (strcasecmp($toEncoding, $fromEncoding) != 0) { - trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}'", E_WARNING); + trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}'", \E_WARNING); return false; } @@ -78,7 +77,7 @@ public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') * @param string $encoding * @return string */ - public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $encoding = 'UTF-8') + public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $encoding = 'UTF-8') { $string = (string) $string; if ($string === '') { @@ -206,4 +205,22 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD return $return; } + + /** + * Get the internal used name of an encoding + * + * @param string $encoding + * @return string + * @throws Exception\InvalidArgumentException On an unsupported encoding + */ + protected function getInternalEncoding($encoding) + { + $encodingUpper = strtoupper($encoding); + if (!isset($this->encodingMap[$encodingUpper])) { + throw new Exception\InvalidArgumentException( + "Character encoding '{$encoding}' isn't supported by this string wrapper" + ); + } + return $this->encodingMap[$encodingUpper]; + } } diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 3de069ed0..3c97ad083 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -29,19 +29,18 @@ class Iconv extends AbstractStringWrapper 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-7', 'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', 'KOI8-R', 'KOI8-U', 'KOI8-RU', - 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254' ,'CP1257', - 'CP850', 'CP866', 'CP1131', + 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254', 'CP1257', 'CP850', 'CP866', 'CP1131', 'MACROMAN', 'MACCENTRALEUROPE', 'MACICELAND', 'MACCROATIAN', 'MACROMANIA', - 'MACCYRILLIC', 'MACUKRAINE', 'MACGREEK', 'MACTURKISH', - 'MACINTOSH', + 'MACCYRILLIC', 'MACUKRAINE', 'MACGREEK', 'MACTURKISH', 'MACINTOSH', // Semitic languages 'ISO-8859-6', 'ISO-8859-8', - 'CP1255' , 'CP1256', 'CP862', + 'CP1255', 'CP1256', 'CP862', 'MACHEBREW', 'MACARABIC', // Japanese - 'EUC-JP', 'SHIFT_JIS', 'CP932', 'ISO-2022-JP', 'ISO-2022-JP-2', 'ISO-2022-JP-1', + 'EUC-JP', 'SHIFT_JIS', 'CP932', + 'ISO-2022-JP', 'ISO-2022-JP-2', 'ISO-2022-JP-1', // Chinese 'EUC-CN', 'HZ', 'GBK', 'CP936', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index 42b8f4ae5..d7e13e9b7 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -19,13 +19,25 @@ */ class Native extends AbstractStringWrapper { + /** + * Check if the given encoding is supported + * + * @param string $encoding + * @return boolean + */ + public function isEncodingSupported($encoding) + { + return StringUtils::isSingleByteEncoding($encoding); + } /** - * Constructor + * Get a list of supported character encodings + * + * @return string[] */ - public function __construct() + public function getSupportedEncodings() { - $this->encodings = StringUtils::getSingleByteEncodings(); + return StringUtils::getSingleByteEncodings(); } /** From e415882c88651ea12350fee905adf6e35161a20e Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 17:41:10 +0100 Subject: [PATCH 024/127] StringUtils: hopefully a little better encoding list --- src/StringUtils.php | 14 +++++++------- src/StringWrapper/AbstractStringWrapper.php | 18 ------------------ src/StringWrapper/StringWrapperInterface.php | 4 ++-- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 040ce301f..2b1b227e8 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -36,7 +36,7 @@ abstract class StringUtils protected static $wrapperRegistry; /** - * A list of known single-byte encodings (upper-case) + * A list of known single-byte character encodings (upper-case) * * @var string[] */ @@ -105,12 +105,12 @@ public static function unregisterWrapper(StringWrapperInterface $wrapper) } /** - * Get the first string wrapper supporting one or more encodings + * Get the first string wrapper supporting one or more character encodings * - * @param string $encoding Encoding supported by he string wrapper - * @param string $encodingN, ... Unlimited OPTIONAL number of additional encodings + * @param string $encoding Character encoding supported by he string wrapper + * @param string $encodingN, ... Unlimited OPTIONAL number of additional character encodings * @return StringWrapperInterface - * @throws Exception\RuntimeException If no wrapper supports all given encodings + * @throws Exception\RuntimeException If no wrapper supports all given character encodings */ public static function getWrapper($encoding = 'UTF-8') { @@ -132,7 +132,7 @@ public static function getWrapper($encoding = 'UTF-8') } /** - * Get a list of all known single-byte encodings + * Get a list of all known single-byte character encodings * * @return string[] */ @@ -142,7 +142,7 @@ public static function getSingleByteEncodings() } /** - * Check if a given encoding is a known single-byte encoding + * Check if a given encoding is a known single-byte character encoding * * @param string $encoding * @return boolean diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 2ba662966..ac329357c 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -205,22 +205,4 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD return $return; } - - /** - * Get the internal used name of an encoding - * - * @param string $encoding - * @return string - * @throws Exception\InvalidArgumentException On an unsupported encoding - */ - protected function getInternalEncoding($encoding) - { - $encodingUpper = strtoupper($encoding); - if (!isset($this->encodingMap[$encodingUpper])) { - throw new Exception\InvalidArgumentException( - "Character encoding '{$encoding}' isn't supported by this string wrapper" - ); - } - return $this->encodingMap[$encodingUpper]; - } } diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index c46570383..f3f8ebe15 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -19,7 +19,7 @@ interface StringWrapperInterface { /** - * Check if the given encoding is supported + * Check if the given character encoding is supported * * @param string $encoding * @return boolean @@ -27,7 +27,7 @@ interface StringWrapperInterface public function isEncodingSupported($encoding); /** - * Get a list of supported encodings + * Get a list of supported character encodings * * @return string[] */ From 832179bdfc4125954f0f77fa33311b9e592edea2 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 17:46:58 +0100 Subject: [PATCH 025/127] StringUtils: optimations --- src/StringWrapper/AbstractStringWrapper.php | 49 ++++++++++----------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index ac329357c..bd9e7713f 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -75,7 +75,7 @@ public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') * @param string $break * @param boolean $cut * @param string $encoding - * @return string + * @return string|false */ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $encoding = 'UTF-8') { @@ -168,41 +168,38 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD return str_pad($input, $padLength, $padString, $padType); } - $return = ''; $lengthOfPadding = $padLength - $this->strlen($input, $encoding); $padStringLength = $this->strlen($padString, $encoding); if ($padStringLength === 0 || $lengthOfPadding <= 0) { - $return = $input; - } else { - $repeatCount = floor($lengthOfPadding / $padStringLength); + return $input; + } - if ($padType === \STR_PAD_BOTH) { - $lastStringLeft = ''; - $lastStringRight = ''; - $repeatCountLeft = $repeatCountRight = ($repeatCount - $repeatCount % 2) / 2; + $repeatCount = floor($lengthOfPadding / $padStringLength); - $lastStringLength = $lengthOfPadding - 2 * $repeatCountLeft * $padStringLength; - $lastStringLeftLength = $lastStringRightLength = floor($lastStringLength / 2); - $lastStringRightLength += $lastStringLength % 2; + if ($padType === \STR_PAD_BOTH) { + $lastStringLeft = ''; + $lastStringRight = ''; + $repeatCountLeft = $repeatCountRight = ($repeatCount - $repeatCount % 2) / 2; - $lastStringLeft = $this->substr($padString, 0, $lastStringLeftLength, $encoding); - $lastStringRight = $this->substr($padString, 0, $lastStringRightLength, $encoding); + $lastStringLength = $lengthOfPadding - 2 * $repeatCountLeft * $padStringLength; + $lastStringLeftLength = $lastStringRightLength = floor($lastStringLength / 2); + $lastStringRightLength += $lastStringLength % 2; - $return = str_repeat($padString, $repeatCountLeft) . $lastStringLeft - . $input - . str_repeat($padString, $repeatCountRight) . $lastStringRight; - } else { - $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength, $encoding); + $lastStringLeft = $this->substr($padString, 0, $lastStringLeftLength, $encoding); + $lastStringRight = $this->substr($padString, 0, $lastStringRightLength, $encoding); - if ($padType === \STR_PAD_LEFT) { - $return = str_repeat($padString, $repeatCount) . $lastString . $input; - } else { - $return = $input . str_repeat($padString, $repeatCount) . $lastString; - } + return str_repeat($padString, $repeatCountLeft) . $lastStringLeft + . $input + . str_repeat($padString, $repeatCountRight) . $lastStringRight; + } else { + $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength, $encoding); + + if ($padType === \STR_PAD_LEFT) { + return str_repeat($padString, $repeatCount) . $lastString . $input; + } else { + return $input . str_repeat($padString, $repeatCount) . $lastString; } } - - return $return; } } From 90c0cc0534e96f8837180e3c3b2bfd0d4e5660dc Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 19:49:28 +0100 Subject: [PATCH 026/127] StringUtils: cs --- src/StringWrapper/Native.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index d7e13e9b7..3aee7f13b 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -79,4 +79,4 @@ public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') { return strpos($haystack, $needle, $offset); } -} +} From 56d536f6990f736ddc0316c228033fbb128760a4 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 29 Nov 2012 21:09:12 +0100 Subject: [PATCH 027/127] StringUtils: MbString wrapper use of 'mb_list_encodings' --- src/StringWrapper/MbString.php | 102 +-------------------------------- 1 file changed, 2 insertions(+), 100 deletions(-) diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 8331ba789..a17241228 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -23,83 +23,7 @@ class MbString extends AbstractStringWrapper * @var string[] * @link http://php.net/manual/mbstring.supported-encodings.php */ - protected $encodings = array( - 'UCS-4', - 'UCS-4BE', - 'UCS-4LE', - 'UCS-2', - 'UCS-2BE', - 'UCS-2LE', - 'UTF-32', - 'UTF-32BE', - 'UTF-32LE', - 'UTF-16', - 'UTF-16BE', - 'UTF-16LE', - 'UTF-7', - 'UTF7-IMAP', - 'UTF-8', - 'ASCII', - 'EUC-JP', - 'SJIS', - 'EUCJP-WIN', - 'SJIS-WIN', - 'ISO-2022-JP', - 'ISO-2022-JP-MS', - 'CP932', - 'CP51932', - 'SJIS-MAC', 'MACJAPANESE', - 'SJIS-Mobile#DOCOMO', 'SJIS-DOCOMO', - 'SJIS-Mobile#KDDI', 'SJIS-KDDI', - 'SJIS-Mobile#SOFTBANK', 'SJIS-SOFTBANK', - 'UTF-8-Mobile#DOCOMO', 'UTF-8-DOCOMO', - 'UTF-8-Mobile#KDDI-A', - 'UTF-8-Mobile#KDDI-B', 'UTF-8-KDDI', - 'UTF-8-Mobile#SOFTBANK', 'UTF-8-SOFTBANK', - 'ISO-2022-JP-MOBILE#KDDI', 'ISO-2022-JP-KDDI', - 'JIS', - 'JIS-MS', - 'CP50220', - 'CP50220RAW', - 'CP50221', - 'CP50222', - 'ISO-8859-1', - 'ISO-8859-2', - 'ISO-8859-3', - 'ISO-8859-4', - 'ISO-8859-5', - 'ISO-8859-6', - 'ISO-8859-7', - 'ISO-8859-8', - 'ISO-8859-9', - 'ISO-8859-10', - 'ISO-8859-13', - 'ISO-8859-14', - 'ISO-8859-15', - // 'ISO-8859-16', - 'bYTE2BE', - 'bYTE2LE', - 'BYTE4BE', - 'BYTE4LE', - 'BASE64', - 'HTML-ENTITIES', - '7BIT', - '8BIT', - 'EUC-CN', - 'CP936', - 'GB18030', - 'HZ', - 'EUC-TW', - 'CP950', - 'BIG-5', - 'EUC-KR', - 'UHC', 'CP949', - 'ISO-2022-KR', - 'WINDOWS-1251', 'CP1251', - 'WINDOWS-1252', 'CP1252', - 'CP866', 'IBM866', - 'KOI8-R', - ); + protected $encodings = array(); /** * Constructor @@ -114,29 +38,7 @@ public function __construct() ); } - // remove encodings not available before PHP-5.4 - if (version_compare(PHP_VERSION, '5.4', '<')) { - unset( - $this->encodings['SJIS-MAC'], - $this->encodings['MACJAPANESE'], - $this->encodings['SJIS-Mobile#DOCOMO'], - $this->encodings['SJIS-DOCOMO'], - $this->encodings['SJIS-Mobile#KDDI'], - $this->encodings['SJIS-KDDI'], - $this->encodings['SJIS-Mobile#SOFTBANK'], - $this->encodings['SJIS-SOFTBANK'], - $this->encodings['UTF-8-Mobile#DOCOMO'], - $this->encodings['UTF-8-DOCOMO'], - $this->encodings['UTF-8-Mobile#KDDI-A'], - $this->encodings['UTF-8-Mobile#KDDI-B'], - $this->encodings['UTF-8-KDDI'], - $this->encodings['UTF-8-Mobile#SOFTBANK'], - $this->encodings['UTF-8-SOFTBANK'], - $this->encodings['ISO-2022-JP-MOBILE#KDDI'], - $this->encodings['ISO-2022-JP-KDDI'], - $this->encodings['GB18030'] - ); - } + $this->encodings = array_map('strtoupper', mb_list_encodings()); } /** From 7cf106aae74d50aa56082c410ddf8fb7fb9a44a6 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Fri, 30 Nov 2012 09:16:08 +0100 Subject: [PATCH 028/127] FIXME: Converting the euro sign from UTF-8 to ISO-8859-16 using the mbstring extension gives a wrong result --- src/StringWrapper/Intl.php | 15 --------------- src/StringWrapper/MbString.php | 6 ++++++ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index e9c9ae9f5..81f154943 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -47,11 +47,6 @@ public function __construct() */ public function strlen($str, $encoding = 'UTF-8') { - if (strcasecmp($encoding, 'UTF-8') != 0) { - trigger_error("Character set '{$encoding}' not supported by intl"); - return false; - } - return grapheme_strlen($str); } @@ -66,11 +61,6 @@ public function strlen($str, $encoding = 'UTF-8') */ public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') { - if (strcasecmp($encoding, 'UTF-8') != 0) { - trigger_error("Character set '{$encoding}' not supported by intl"); - return false; - } - return grapheme_substr($str, $offset, $length); } @@ -85,11 +75,6 @@ public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') */ public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') { - if (strcasecmp($encoding, 'UTF-8') != 0) { - trigger_error("Character set '{$encoding}' not supported by intl"); - return false; - } - return grapheme_strpos($haystack, $needle, $offset); } } diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index a17241228..849f3abc5 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -39,6 +39,12 @@ public function __construct() } $this->encodings = array_map('strtoupper', mb_list_encodings()); + + // FIXME: Converting € (UTF-8) to ISO-8859-16 gives a wrong result + $indexIso885916 = array_search('ISO-8859-16', $this->encodings, true); + if ($indexIso885916 !== false) { + unset($this->encodings[$indexIso885916]); + } } /** From 97f0f4c6966697f8b8aaab843803f29d3f9e1e02 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 25 Dec 2012 02:22:58 +0700 Subject: [PATCH 029/127] remove trailing_spaces --- src/Glob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Glob.php b/src/Glob.php index cda6d0a17..b01d38d80 100644 --- a/src/Glob.php +++ b/src/Glob.php @@ -44,7 +44,7 @@ public static function glob($pattern, $flags, $forceFallback = false) if (!defined('GLOB_BRACE') || $forceFallback) { return static::fallbackGlob($pattern, $flags); } - + return static::systemGlob($pattern, $flags); } From 8f2d7b25aa68a12c6d31451eb012f19dd1fda766 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Mon, 31 Dec 2012 16:33:37 +0100 Subject: [PATCH 030/127] Changed API to only check given encoding once and to better support the new Intl-UConverter of PHP 5.5 --- src/StringUtils.php | 57 ++--- src/StringWrapper/AbstractStringWrapper.php | 139 +++++++---- src/StringWrapper/Iconv.php | 34 ++- src/StringWrapper/Intl.php | 24 +- src/StringWrapper/MbString.php | 52 +++-- src/StringWrapper/Native.php | 22 +- src/StringWrapper/StringWrapperInterface.php | 40 ++-- .../StringWrapper/CommonStringWrapperTest.php | 217 ++++++++---------- test/StringWrapper/IconvTest.php | 16 +- test/StringWrapper/IntlTest.php | 16 +- test/StringWrapper/MbStringTest.php | 16 +- test/StringWrapper/NativeTest.php | 13 +- 12 files changed, 378 insertions(+), 268 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 2b1b227e8..68ce89bed 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -11,10 +11,6 @@ namespace Zend\Stdlib; use Zend\Stdlib\StringWrapper\StringWrapperInterface; -use Zend\Stdlib\StringWrapper\MbString as MbStringWrapper; -use Zend\Stdlib\StringWrapper\Iconv as IconvWrapper; -use Zend\Stdlib\StringWrapper\Intl as IntlWrapper; -use Zend\Stdlib\StringWrapper\Native as NativeWrapper; /** * Utility class for handling strings of different character encodings @@ -50,9 +46,9 @@ abstract class StringUtils ); /** - * Get registered wrappers + * Get registered wrapper classes * - * @return StringWrapperInterface[] + * @return string[] */ public static function getRegisteredWrappers() { @@ -60,74 +56,71 @@ public static function getRegisteredWrappers() static::$wrapperRegistry = array(); if (extension_loaded('intl')) { - static::$wrapperRegistry[] = new IntlWrapper(); + static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Intl'; } if (extension_loaded('mbstring')) { - static::$wrapperRegistry[] = new MbStringWrapper(); + static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\MbString'; } if (extension_loaded('iconv')) { - static::$wrapperRegistry[] = new IconvWrapper(); + static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Iconv'; } - static::$wrapperRegistry[] = new NativeWrapper(); + static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Native'; } return static::$wrapperRegistry; } /** - * Register a string wrapper + * Register a string wrapper class * - * @param StringWrapperInterface + * @param string $wrapper * @return void */ - public static function registerWrapper(StringWrapperInterface $wrapper) + public static function registerWrapper($wrapper) { + $wrapper = (string) $wrapper; if (!in_array($wrapper, static::$wrapperRegistry, true)) { static::$wrapperRegistry[] = $wrapper; } } /** - * Unregister a string wrapper + * Unregister a string wrapper class * - * @param StringWrapperInterface $wrapper + * @param string $wrapper * @return void */ - public static function unregisterWrapper(StringWrapperInterface $wrapper) + public static function unregisterWrapper($wrapper) { - $index = array_search($wrapper, static::$wrapperRegistry, true); + $index = array_search((string) $wrapper, static::$wrapperRegistry, true); if ($index !== false) { unset(static::$wrapperRegistry[$index]); } } /** - * Get the first string wrapper supporting one or more character encodings + * Get the first string wrapper supporting the given character encoding + * and supports to convert into the given convert encoding. * - * @param string $encoding Character encoding supported by he string wrapper - * @param string $encodingN, ... Unlimited OPTIONAL number of additional character encodings + * @param string $encoding Character encoding to support + * @param string|null $convertEncoding OPTIONAL character encoding to convert in * @return StringWrapperInterface - * @throws Exception\RuntimeException If no wrapper supports all given character encodings + * @throws Exception\RuntimeException If no wrapper supports given character encodings */ - public static function getWrapper($encoding = 'UTF-8') + public static function getWrapper($encoding = 'UTF-8', $convertEncoding = null) { - $encodings = func_get_args(); - - foreach (static::getRegisteredWrappers() as $wrapper) { - foreach ($encodings as $encoding) { - if (!$wrapper->isEncodingSupported($encoding)) { - continue 2; - } + foreach (static::getRegisteredWrappers() as $wrapperClass) { + if ($wrapperClass::isSupported($encoding, $convertEncoding)) { + return new $wrapperClass($encoding, $convertEncoding); } - - return $wrapper; } throw new Exception\RuntimeException( - 'No wrapper found supporting encoding(s) ' . implode(', ', $encodings) + 'No wrapper found supporting "' . $encoding . '"' + . (($convertEncoding !== null) ? ' and "' . $convertEncoding . '"' : '') ); } diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index bd9e7713f..69a658f2a 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -20,51 +20,108 @@ */ abstract class AbstractStringWrapper implements StringWrapperInterface { + /** + * The character encoding working on + * @var string|null + */ + protected $encoding; /** - * List of supported character encodings (upper case) - * - * @var string[] + * An optionally character encoding to convert to + * @var string|null */ - protected $encodings = array(); + protected $convertEncoding; /** - * Check if the given character encoding is supported + * Check if the given character encoding is supported by this wrapper + * and the character encoding to convert to is also supported. * - * @param string $encoding - * @return boolean + * @param string $encoding + * @param string|null $convertEncoding + */ + public static function isSupported($encoding, $convertEncoding = null) + { + $supportedEncodings = static::getSupportedEncodings(); + + if (!in_array(strtoupper($encoding), $supportedEncodings)) { + return false; + } + + if ($convertEncoding !== null && !in_array(strtoupper($convertEncoding), $supportedEncodings)) { + return false; + } + + return true; + } + + /** + * Constructor + * @param string $encoding Character encoding working on + * @param string|null $convertEncoding Character encoding to convert to + * @throws Exception\InvalidArgumentException */ - public function isEncodingSupported($encoding) + public function __construct($encoding, $convertEncoding = null) { - return in_array(strtoupper($encoding), $this->encodings); + $this->setEncoding($encoding, $convertEncoding); } /** - * Get a list of supported character encodings + * Set character encoding working with and convert to * - * @return string[] + * @param string $encoding The character encoding to work with + * @param string|null $convertEncoding The character encoding to convert to + * @return StringWrapperInterface */ - public function getSupportedEncodings() + public function setEncoding($encoding, $convertEncoding) { - return $this->encodings; + $supportedEncodings = static::getSupportedEncodings(); + + $encodingUpper = strtoupper($encoding); + if (!in_array($encodingUpper, $supportedEncodings)) { + throw new Exception\InvalidArgumentException( + 'Wrapper doesn\'t support character encoding "' . $encoding . '"' + ); + } + + + if ($convertEncoding !== null) { + $convertEncodingUpper = strtoupper($convertEncoding); + if (!in_array($convertEncodingUpper, $supportedEncodings)) { + throw new Exception\InvalidArgumentException( + 'Wrapper doesn\'t support character encoding "' . $convertEncoding . '"' + ); + } + + $this->convertEncoding = $convertEncodingUpper; + } else { + $this->convertEncoding = null; + } + $this->encoding = $encodingUpper; + + return $this; } /** * Convert a string from one character encoding to another * - * @param string $str - * @param string $toEncoding - * @param string $fromEncoding + * @param string $str + * @param boolean $backward * @return string|false */ - public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') + public function convert($str, $backward = false) { - if (strcasecmp($toEncoding, $fromEncoding) != 0) { - trigger_error("Can't convert '{$fromEncoding}' to '{$toEncoding}'", \E_WARNING); - return false; + $from = $backward ? $this->convertEncoding : $this->encoding; + $to = $backward ? $this->encoding : $this->convertEncoding; + + if ($to == $from) { + return $str; } - return $str; + throw new Exception\RuntimeException(sprintf( + 'Converting from "%s" to "%s" isn\'t supported by this string wrapper', + $from, + $to + )); } /** @@ -74,10 +131,9 @@ public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') * @param integer $width * @param string $break * @param boolean $cut - * @param string $encoding * @return string|false */ - public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $encoding = 'UTF-8') + public function wordWrap($string, $width = 75, $break = "\n", $cut = false) { $string = (string) $string; if ($string === '') { @@ -95,27 +151,26 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $enc throw new Exception\InvalidArgumentException('Cannot force cut when width is zero'); } - $encoding = strtoupper($encoding); - if (StringUtils::isSingleByteEncoding($encoding)) { + if (StringUtils::isSingleByteEncoding($this->encoding)) { return wordwrap($string, $width, $break, $cut); } - $stringWidth = $this->strlen($string, $encoding); - $breakWidth = $this->strlen($break, $encoding); + $stringWidth = $this->strlen($string); + $breakWidth = $this->strlen($break); $result = ''; $lastStart = $lastSpace = 0; for ($current = 0; $current < $stringWidth; $current++) { - $char = $this->substr($string, $current, 1, $encoding); + $char = $this->substr($string, $current, 1); $possibleBreak = $char; if ($breakWidth !== 1) { - $possibleBreak = $this->substr($string, $current, $breakWidth, $encoding); + $possibleBreak = $this->substr($string, $current, $breakWidth); } if ($possibleBreak === $break) { - $result .= $this->substr($string, $lastStart, $current - $lastStart + $breakWidth, $encoding); + $result .= $this->substr($string, $lastStart, $current - $lastStart + $breakWidth); $current += $breakWidth - 1; $lastStart = $lastSpace = $current + 1; continue; @@ -123,7 +178,7 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $enc if ($char === ' ') { if ($current - $lastStart >= $width) { - $result .= $this->substr($string, $lastStart, $current - $lastStart, $encoding) . $break; + $result .= $this->substr($string, $lastStart, $current - $lastStart) . $break; $lastStart = $current + 1; } @@ -132,20 +187,20 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $enc } if ($current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) { - $result .= $this->substr($string, $lastStart, $current - $lastStart, $encoding) . $break; + $result .= $this->substr($string, $lastStart, $current - $lastStart) . $break; $lastStart = $lastSpace = $current; continue; } if ($current - $lastStart >= $width && $lastStart < $lastSpace) { - $result .= $this->substr($string, $lastStart, $lastSpace - $lastStart, $encoding) . $break; + $result .= $this->substr($string, $lastStart, $lastSpace - $lastStart) . $break; $lastStart = $lastSpace = $lastSpace + 1; continue; } } if ($lastStart !== $current) { - $result .= $this->substr($string, $lastStart, $current - $lastStart, $encoding); + $result .= $this->substr($string, $lastStart, $current - $lastStart); } return $result; @@ -158,18 +213,16 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false, $enc * @param integer $padLength * @param string $padString * @param integer $padType - * @param string $encoding * @return string */ - public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $encoding = 'UTF-8') + public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT) { - $encoding = strtoupper($encoding); - if (StringUtils::isSingleByteEncoding($encoding)) { + if (StringUtils::isSingleByteEncoding($this->encoding)) { return str_pad($input, $padLength, $padString, $padType); } - $lengthOfPadding = $padLength - $this->strlen($input, $encoding); - $padStringLength = $this->strlen($padString, $encoding); + $lengthOfPadding = $padLength - $this->strlen($input); + $padStringLength = $this->strlen($padString); if ($padStringLength === 0 || $lengthOfPadding <= 0) { return $input; @@ -186,14 +239,14 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD $lastStringLeftLength = $lastStringRightLength = floor($lastStringLength / 2); $lastStringRightLength += $lastStringLength % 2; - $lastStringLeft = $this->substr($padString, 0, $lastStringLeftLength, $encoding); - $lastStringRight = $this->substr($padString, 0, $lastStringRightLength, $encoding); + $lastStringLeft = $this->substr($padString, 0, $lastStringLeftLength); + $lastStringRight = $this->substr($padString, 0, $lastStringRightLength); return str_repeat($padString, $repeatCountLeft) . $lastStringLeft . $input . str_repeat($padString, $repeatCountRight) . $lastStringRight; } else { - $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength, $encoding); + $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength); if ($padType === \STR_PAD_LEFT) { return str_repeat($padString, $repeatCount) . $lastString . $input; diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 3c97ad083..f4982fb12 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -10,6 +10,8 @@ namespace Zend\Stdlib\StringWrapper; +use Zend\Stdlib\Exception; + /** * @category Zend * @package Zend_Stdlib @@ -23,7 +25,7 @@ class Iconv extends AbstractStringWrapper * @var string[] * @link http://www.gnu.org/software/libiconv/ */ - protected $encodings = array( + protected static $encodings = array( // European languages 'ASCII', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-7', @@ -114,18 +116,30 @@ class Iconv extends AbstractStringWrapper 'ATARIST', 'RISCOS-LATIN1', ); + /** + * Get a list of supported character encodings + * + * @return string[] + */ + public static function getSupportedEncodings() + { + return static::$encodings; + } + /** * Constructor * * @throws Exception\ExtensionNotLoadedException */ - public function __construct() + public function __construct($encoding, $convertEncoding = null) { if (!extension_loaded('iconv')) { throw new Exception\ExtensionNotLoadedException( 'PHP extension "iconv" is required for this wrapper' ); } + + parent::__construct($encoding, $convertEncoding); } /** @@ -135,9 +149,9 @@ public function __construct() * @param string $encoding * @return int|false */ - public function strlen($str, $encoding = 'UTF-8') + public function strlen($str) { - return iconv_strlen($str, $encoding); + return iconv_strlen($str, $this->encoding); } /** @@ -149,9 +163,9 @@ public function strlen($str, $encoding = 'UTF-8') * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') + public function substr($str, $offset = 0, $length = null) { - return iconv_substr($str, $offset, $length, $encoding); + return iconv_substr($str, $offset, $length, $this->encoding); } /** @@ -163,9 +177,9 @@ public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0) { - return iconv_strpos($haystack, $needle, $offset, $encoding); + return iconv_strpos($haystack, $needle, $offset, $this->encoding); } /** @@ -176,8 +190,10 @@ public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') * @param string $fromEncoding * @return string|false */ - public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') + public function convert($str, $backword = false) { + $fromEncoding = $backword ? $this->convertEncoding : $this->encoding; + $toEncoding = $backword ? $this->encoding : $this->convertEncoding; return iconv($fromEncoding, $toEncoding, $str); } } diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index 81f154943..7b48accd6 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -10,6 +10,8 @@ namespace Zend\Stdlib\StringWrapper; +use Zend\Stdlib\Exception; + /** * @category Zend * @package Zend_Stdlib @@ -22,20 +24,32 @@ class Intl extends AbstractStringWrapper * * @var string[] */ - protected $encodings = array('UTF-8'); + protected static $encodings = array('UTF-8'); + + /** + * Get a list of supported character encodings + * + * @return string[] + */ + public static function getSupportedEncodings() + { + return static::$encodings; + } /** * Constructor * * @throws Exception\ExtensionNotLoadedException */ - public function __construct() + public function __construct($encoding, $convertEncoding = null) { if (!extension_loaded('intl')) { throw new Exception\ExtensionNotLoadedException( 'PHP extension "intl" is required for this wrapper' ); } + + parent::__construct($encoding, $convertEncoding); } /** @@ -45,7 +59,7 @@ public function __construct() * @param string $encoding * @return int|false */ - public function strlen($str, $encoding = 'UTF-8') + public function strlen($str) { return grapheme_strlen($str); } @@ -59,7 +73,7 @@ public function strlen($str, $encoding = 'UTF-8') * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') + public function substr($str, $offset = 0, $length = null) { return grapheme_substr($str, $offset, $length); } @@ -73,7 +87,7 @@ public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0) { return grapheme_strpos($haystack, $needle, $offset); } diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 849f3abc5..bf72a5a7c 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -10,6 +10,8 @@ namespace Zend\Stdlib\StringWrapper; +use Zend\Stdlib\Exception; + /** * @category Zend * @package Zend_Stdlib @@ -20,17 +22,37 @@ class MbString extends AbstractStringWrapper /** * List of supported character sets (upper case) * - * @var string[] + * @var null|string[] * @link http://php.net/manual/mbstring.supported-encodings.php */ - protected $encodings = array(); + protected static $encodings = null; + + /** + * Get a list of supported character encodings + * + * @return string[] + */ + public static function getSupportedEncodings() + { + if (static::$encodings === null) { + static::$encodings = array_map('strtoupper', mb_list_encodings()); + + // FIXME: Converting € (UTF-8) to ISO-8859-16 gives a wrong result + $indexIso885916 = array_search('ISO-8859-16', static::$encodings, true); + if ($indexIso885916 !== false) { + unset(static::$encodings[$indexIso885916]); + } + } + + return static::$encodings; + } /** * Constructor * * @throws Exception\ExtensionNotLoadedException */ - public function __construct() + public function __construct($encoding, $convertEncoding = null) { if (!extension_loaded('mbstring')) { throw new Exception\ExtensionNotLoadedException( @@ -38,13 +60,7 @@ public function __construct() ); } - $this->encodings = array_map('strtoupper', mb_list_encodings()); - - // FIXME: Converting € (UTF-8) to ISO-8859-16 gives a wrong result - $indexIso885916 = array_search('ISO-8859-16', $this->encodings, true); - if ($indexIso885916 !== false) { - unset($this->encodings[$indexIso885916]); - } + parent::__construct($encoding, $convertEncoding); } /** @@ -54,9 +70,9 @@ public function __construct() * @param string $encoding * @return int|false */ - public function strlen($str, $encoding = 'UTF-8') + public function strlen($str) { - return mb_strlen($str, $encoding); + return mb_strlen($str, $this->encoding); } /** @@ -68,9 +84,9 @@ public function strlen($str, $encoding = 'UTF-8') * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') + public function substr($str, $offset = 0, $length = null) { - return mb_substr($str, $offset, $length, $encoding); + return mb_substr($str, $offset, $length, $this->encoding); } /** @@ -82,9 +98,9 @@ public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0) { - return mb_strpos($haystack, $needle, $offset, $encoding); + return mb_strpos($haystack, $needle, $offset, $this->encoding); } /** @@ -95,8 +111,10 @@ public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') * @param string $fromEncoding * @return string|false */ - public function convert($str, $toEncoding, $fromEncoding = 'UTF-8') + public function convert($str, $backword = false) { + $fromEncoding = $backword ? $this->convertEncoding : $this->encoding; + $toEncoding = $backword ? $this->encoding : $this->convertEncoding; return mb_convert_encoding($str, $toEncoding, $fromEncoding); } } diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index 3aee7f13b..69468bd69 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -19,23 +19,12 @@ */ class Native extends AbstractStringWrapper { - /** - * Check if the given encoding is supported - * - * @param string $encoding - * @return boolean - */ - public function isEncodingSupported($encoding) - { - return StringUtils::isSingleByteEncoding($encoding); - } - /** * Get a list of supported character encodings * * @return string[] */ - public function getSupportedEncodings() + public static function getSupportedEncodings() { return StringUtils::getSingleByteEncodings(); } @@ -44,10 +33,9 @@ public function getSupportedEncodings() * Returns the length of the given string * * @param string $str - * @param string $encoding * @return int|false */ - public function strlen($str, $encoding = 'UTF-8') + public function strlen($str) { return strlen($str); } @@ -58,10 +46,9 @@ public function strlen($str, $encoding = 'UTF-8') * @param string $str * @param int $offset * @param int|null $length - * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') + public function substr($str, $offset = 0, $length = null) { return substr($str, $offset, $length); } @@ -72,10 +59,9 @@ public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8') * @param string $haystack * @param string $needle * @param int $offset - * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8') + public function strpos($haystack, $needle, $offset = 0) { return strpos($haystack, $needle, $offset); } diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index f3f8ebe15..f99dbf73c 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -17,30 +17,37 @@ */ interface StringWrapperInterface { - /** - * Check if the given character encoding is supported + * Check if the given character encoding is supported by this wrapper + * and the character encoding to convert to is also supported. * - * @param string $encoding - * @return boolean + * @param string $encoding + * @param string|null $convertEncoding */ - public function isEncodingSupported($encoding); + public static function isSupported($encoding, $convertEncoding = null); /** * Get a list of supported character encodings * * @return string[] */ - public function getSupportedEncodings(); + public static function getSupportedEncodings(); + + /** + * Constructor + * + * @param string $encoding Character encoding working on + * @param string|null $convertEncoding Character encoding to convert to + */ + public function __construct($encoding, $convertEncoding = null); /** * Returns the length of the given string * * @param string $str - * @param string $encoding * @return int|false */ - public function strlen($str, $encoding = 'UTF-8'); + public function strlen($str); /** * Returns the portion of string specified by the start and length parameters @@ -51,7 +58,7 @@ public function strlen($str, $encoding = 'UTF-8'); * @param string $encoding * @return string|false */ - public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8'); + public function substr($str, $offset = 0, $length = null); /** * Find the position of the first occurrence of a substring in a string @@ -62,17 +69,16 @@ public function substr($str, $offset = 0, $length = null, $encoding = 'UTF-8'); * @param string $encoding * @return int|false */ - public function strpos($haystack, $needle, $offset = 0, $encoding = 'UTF-8'); + public function strpos($haystack, $needle, $offset = 0); /** * Convert a string from one character encoding to another * - * @param string $str - * @param string $toEncoding - * @param string $fromEncoding + * @param string $str + * @param boolean $backward * @return string|false */ - public function convert($str, $toEncoding, $fromEncoding = 'UTF-8'); + public function convert($str, $backward = false); /** * Wraps a string to a given number of characters @@ -81,10 +87,9 @@ public function convert($str, $toEncoding, $fromEncoding = 'UTF-8'); * @param integer $width * @param string $break * @param boolean $cut - * @param string $encoding * @return string */ - public function wordWrap($str, $width = 75, $break = "\n", $cut = false, $encoding = 'UTF-8'); + public function wordWrap($str, $width = 75, $break = "\n", $cut = false); /** * Pad a string to a certain length with another string @@ -93,8 +98,7 @@ public function wordWrap($str, $width = 75, $break = "\n", $cut = false, $encodi * @param integer $padLength * @param string $padString * @param integer $padType - * @param string $encoding * @return string */ - public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT, $encoding = 'UTF-8'); + public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT); } diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php index 4f606a1ae..6bea2a0d6 100644 --- a/test/StringWrapper/CommonStringWrapperTest.php +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -17,286 +17,269 @@ abstract class CommonStringWrapperTest extends TestCase { - - /** - * An instance of the string wrapper to test - * @StringWrapperInterface - */ - protected $stringWrapper; - - public function setUp() - { - if ( !($this->stringWrapper instanceof StringWrapperInterface) ) { - $this->fail(sprintf( - "%s isn't an instance of %s", - get_class($this) . '::stringWrapper', - 'Zend\Stdlib\StringWrapper\StringWrapperInterface' - )); - } - } + abstract protected function getWrapper($encoding = null, $convertEncoding = null); public function strlenProvider() { return array( - array('abcdefghijklmnopqrstuvwxyz', 'ascii', 26), - array('abcdefghijklmnopqrstuvwxyz', 'utf-8', 26), - array('äöüß', 'utf-8', 4), + array('ascii', 'abcdefghijklmnopqrstuvwxyz', 26), + array('utf-8', 'abcdefghijklmnopqrstuvwxyz', 26), + array('utf-8', 'äöüß', 4), ); } /** * @dataProvider strlenProvider - * @param string $string * @param string $encoding + * @param string $string * @param mixed $expected */ - public function testStrlen($str, $encoding, $expected) + public function testStrlen($encoding, $str, $expected) { - if (!$this->stringWrapper->isEncodingSupported($encoding)) { - $this->markTestSkipped( - "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) - ); + $wrapper = $this->getWrapper($encoding); + if (!$wrapper) { + $this->markTestSkipped("Encoding {$encoding} not supported"); } - $result = $this->stringWrapper->strlen($str, $encoding); + $result = $wrapper->strlen($str); $this->assertSame($expected, $result); } public function substrProvider() { return array( - array('abcdefghijkl', 1, 5, 'ascii', 'bcdef'), - array('abcdefghijkl', 1, 5, 'utf-8', 'bcdef'), - array('äöüß', 1, 2, 'utf-8', 'öü'), + array('ascii', 'abcdefghijkl', 1, 5, 'bcdef'), + array('utf-8', 'abcdefghijkl', 1, 5, 'bcdef'), + array('utf-8', 'äöüß', 1, 2, 'öü'), ); } /** * @dataProvider substrProvider + * @param string $encoding * @param string $str * @param int $offset * @param int|null $length - * @param string $encoding * @param mixed $expected */ - public function testSubstr($str, $offset, $length, $encoding, $expected) + public function testSubstr($encoding, $str, $offset, $length, $expected) { - if (!$this->stringWrapper->isEncodingSupported($encoding)) { - $this->markTestSkipped( - "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) - ); + $wrapper = $this->getWrapper($encoding); + if (!$wrapper) { + $this->markTestSkipped("Encoding {$encoding} not supported"); } - $result = $this->stringWrapper->substr($str, $offset, $length, $encoding); + $result = $wrapper->substr($str, $offset, $length); $this->assertSame($expected, $result); } public function strposProvider() { return array( - array('abcdefghijkl', 'g', 3, 'ascii', 6), - array('abcdefghijkl', 'g', 3, 'utf-8', 6), - array('äöüß', 'ü', 1, 'utf-8', 2), + array('ascii', 'abcdefghijkl', 'g', 3, 6), + array('utf-8', 'abcdefghijkl', 'g', 3, 6), + array('utf-8', 'äöüß', 'ü', 1, 2), ); } /** * @dataProvider strposProvider + * @param string $encoding * @param string $haystack * @param string $needle * @param int $offset - * @param string $encoding * @param mixed $expected */ - public function testStrpos($haystack, $needle, $offset, $encoding, $expected) + public function testStrpos($encoding, $haystack, $needle, $offset, $expected) { - if (!$this->stringWrapper->isEncodingSupported($encoding)) { - $this->markTestSkipped( - "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) - ); + $wrapper = $this->getWrapper($encoding); + if (!$wrapper) { + $this->markTestSkipped("Encoding {$encoding} not supported"); } - $result = $this->stringWrapper->strpos($haystack, $needle, $offset, $encoding); + $result = $wrapper->strpos($haystack, $needle, $offset); $this->assertSame($expected, $result); } public function convertProvider() { return array( - array('abc', 'ascii', 'ascii', 'abc'), - array('abc', 'utf-8', 'ascii', 'abc'), - array('abc', 'ascii', 'utf-8', 'abc'), - array('€', 'iso-8859-15', 'utf-8', "\xA4"), - array('€', 'iso-8859-16', 'utf-8', "\xA4"), // ISO-8859-16 is wrong @ mbstring + array('ascii', 'ascii', 'abc', 'abc'), + array('ascii', 'utf-8', 'abc', 'abc'), + array('utf-8', 'ascii', 'abc', 'abc'), + array('utf-8', 'iso-8859-15', '€', "\xA4"), + array('utf-8', 'iso-8859-16', '€', "\xA4"), // ISO-8859-16 is wrong @ mbstring ); } /** * @dataProvider convertProvider * @param string $str - * @param string $toEncoding - * @param string $fromEncoding + * @param string $encoding + * @param string $convertEncoding * @param mixed $expected */ - public function testConvert($str, $toEncoding, $fromEncoding, $expected) + public function testConvert($encoding, $convertEncoding, $str, $expected) { - if (!$this->stringWrapper->isEncodingSupported($toEncoding)) { - $this->markTestSkipped( - "Encoding {$toEncoding} not supported by " . get_class($this->stringWrapper) - ); - } elseif (!$this->stringWrapper->isEncodingSupported($fromEncoding)) { - $this->markTestSkipped( - "Encoding {$fromEncoding} not supported by " . get_class($this->stringWrapper) - ); + $wrapper = $this->getWrapper($encoding, $convertEncoding); + if (!$wrapper) { + $this->markTestSkipped("Encoding {$encoding} or {$convertEncoding} not supported"); } - $result = $this->stringWrapper->convert($str, $toEncoding, $fromEncoding); + $result = $wrapper->convert($str); $this->assertSame($expected, $result); + + // backword + $result = $wrapper->convert($expected, true); + $this->assertSame($str, $result); } public function wordWrapProvider() { return array( // Standard cut tests - array('äbüöcß', 2, ' ', true, 'utf-8', + array('utf-8', 'äbüöcß', 2, ' ', true, 'äb üö cß'), - array('äbüöc ß äbüöcß', 2, ' ', true, 'utf-8', + array('utf-8', 'äbüöc ß äbüöcß', 2, ' ', true, 'äb üö c ß äb üö cß'), - array('Ä very long wöööööööööööörd.', 8, "\n", true, 'utf-8', + array('utf-8', 'Ä very long wöööööööööööörd.', 8, "\n", true, "Ä very\nlong\nwööööööö\nööööörd."), - array("Ä very\nlong wöööööööööööörd.", 8, "\n", false, 'utf-8', + array('utf-8', "Ä very\nlong wöööööööööööörd.", 8, "\n", false, "Ä very\nlong\nwöööööööööööörd."), - array("Ä very
long wöö
öööööööö
öörd.", 8, '
', false, 'utf-8', + array('utf-8', "Ä very
long wöö
öööööööö
öörd.", 8, '
', false, "Ä very
long wöö
öööööööö
öörd."), // Alternative cut tests - array(' äüöäöü', 3, ' ', true, 'utf-8', + array('utf-8', ' äüöäöü', 3, ' ', true, ' äüö äöü'), - array('äüöäöü ', 3, ' ', true, 'utf-8', + array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - array('äöüäöü ', 3, '-', true, 'utf-8', + array('utf-8', 'äöüäöü ', 3, '-', true, 'äöü-äöü-'), - array('äüöäöü ', 3, ' ', true, 'utf-8', + array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - array('12345 ', 5, '-', false, 'utf-8', + array('utf-8', '12345 ', 5, '-', false, '12345-'), - array('12345 ', 5, '-', false, 'utf-8', + array('utf-8', '12345 ', 5, '-', false, '12345- '), - array('äüöäöü ', 3, ' ', true, 'utf-8', + array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - array('äüöäöü--', 3, '-', true, 'utf-8', + array('utf-8', 'äüöäöü--', 3, '-', true, 'äüö-äöü--'), - array("äbü\töcß", 3, ' ', true, 'utf-8', + array('utf-8', "äbü\töcß", 3, ' ', true, "äbü \töc ß"), - array("äbü\nößt", 3, ' ', true, 'utf-8', + array('utf-8', "äbü\nößt", 3, ' ', true, "äbü \nöß t"), - array("äbü\nößte", 3, "\n", true, 'utf-8', + array('utf-8', "äbü\nößte", 3, "\n", true, "äbü\nößt\ne"), // Break cut tests - array('foobar-foofoofoo', 8, '-', true, 'ascii', + array('ascii', 'foobar-foofoofoo', 8, '-', true, 'foobar-foofoofo-o'), - array('foobar-foobar', 6, '-', true, 'ascii', + array('ascii', 'foobar-foobar', 6, '-', true, 'foobar-foobar'), - array('foobar-foobar', 7, '-', true, 'ascii', + array('ascii', 'foobar-foobar', 7, '-', true, 'foobar-foobar'), - array('foobar-', 7, '-', true, 'ascii', + array('ascii', 'foobar-', 7, '-', true, 'foobar-'), - array('foobar-foobar', 5, '-', true, 'ascii', + array('ascii', 'foobar-foobar', 5, '-', true, 'fooba-r-fooba-r'), // Standard no-cut tests - array('äbüöcß', 2, ' ', false, 'utf-8', + array('utf-8', 'äbüöcß', 2, ' ', false, 'äbüöcß'), - array('äbüöc ß äbüöcß', 2, "\n", false, 'utf-8', + array('utf-8', 'äbüöc ß äbüöcß', 2, "\n", false, "äbüöc\nß\näbüöcß"), - array('äöü äöü äöü', 5, "\n", false, 'utf-8', + array('utf-8', 'äöü äöü äöü', 5, "\n", false, "äöü\näöü\näöü"), // Break no-cut tests - array('foobar-foofoofoo', 8, '-', false, 'ascii', + array('ascii', 'foobar-foofoofoo', 8, '-', false, 'foobar-foofoofoo'), - array('foobar-foobar', 6, '-', false, 'ascii', + array('ascii', 'foobar-foobar', 6, '-', false, 'foobar-foobar'), - array('foobar-foobar', 7, '-', false, 'ascii', + array('ascii', 'foobar-foobar', 7, '-', false, 'foobar-foobar'), - array('foobar-', 7, '-', false, 'ascii', + array('ascii', 'foobar-', 7, '-', false, 'foobar-'), - array('foobar-foobar', 5, '-', false, 'ascii', + array('ascii', 'foobar-foobar', 5, '-', false, 'foobar-foobar'), ); } /** * @dataProvider wordWrapProvider + * @param string $encoding * @param string $str * @param integer $width * @param string $break * @param boolean $cut - * @param string $encoding * @param mixed $expected */ - public function testWordWrap($string, $width, $break, $cut, $encoding, $expected) + public function testWordWrap($encoding, $string, $width, $break, $cut, $expected) { - if (!$this->stringWrapper->isEncodingSupported($encoding)) { - $this->markTestSkipped( - "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) - ); + $wrapper = $this->getWrapper($encoding); + if (!$wrapper) { + $this->markTestSkipped("Encoding {$encoding} not supported"); } - $result = $this->stringWrapper->wordWrap($string, $width, $break, $cut, $encoding); + $result = $wrapper->wordWrap($string, $width, $break, $cut); $this->assertSame($expected, $result); } public function testWordWrapInvalidArgument() { + $wrapper = $this->getWrapper(); + if (!$wrapper) { + $this->fail("Can't instantiate wrapper"); + } + $this->setExpectedException( 'Zend\Stdlib\Exception\InvalidArgumentException', "Cannot force cut when width is zero" ); - $this->stringWrapper->wordWrap('a', 0, "\n", true); + $wrapper->wordWrap('a', 0, "\n", true); } public function strPadProvider() { return array( // single-byte - array('aaa', 5, 'o', STR_PAD_LEFT, 'ascii', 'ooaaa'), - array('aaa', 6, 'o', STR_PAD_BOTH, 'ascii', 'oaaaoo'), - array('aaa', 5, 'o', STR_PAD_RIGHT, 'ascii', 'aaaoo'), + array('ascii', 'aaa', 5, 'o', STR_PAD_LEFT, 'ooaaa'), + array('ascii', 'aaa', 6, 'o', STR_PAD_BOTH, 'oaaaoo'), + array('ascii', 'aaa', 5, 'o', STR_PAD_RIGHT, 'aaaoo'), // multi-byte - array('äää', 5, 'ö', STR_PAD_LEFT, 'utf-8', 'ööäää'), - array('äää', 6, 'ö', STR_PAD_BOTH, 'utf-8', 'öäääöö'), - array('äää', 5, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), + array('utf-8', 'äää', 5, 'ö', STR_PAD_LEFT, 'ööäää'), + array('utf-8', 'äää', 6, 'ö', STR_PAD_BOTH, 'öäääöö'), + array('utf-8', 'äää', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), // ZF-12186 - array('äääöö', 2, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), // PadInputLongerThanPadLength - array('äääöö', 5, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), // PadInputSameAsPadLength - array('äääöö', -2, 'ö', STR_PAD_RIGHT, 'utf-8', 'äääöö'), // PadNegativePadLength + array('utf-8', 'äääöö', 2, 'ö', STR_PAD_RIGHT, 'äääöö'), // PadInputLongerThanPadLength + array('utf-8', 'äääöö', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), // PadInputSameAsPadLength + array('utf-8', 'äääöö', -2, 'ö', STR_PAD_RIGHT, 'äääöö'), // PadNegativePadLength ); } /** * @dataProvider strPadProvider + * @param string $encoding * @param string $input * @param integer $padLength * @param string $padString * @param integer $padType - * @param string $encoding * @param mixed $expected * * @group ZF-12186 */ - public function testStrPad($input, $padLength, $padString, $padType, $encoding, $expected) + public function testStrPad($encoding, $input, $padLength, $padString, $padType, $expected) { - if (!$this->stringWrapper->isEncodingSupported($encoding)) { - $this->markTestSkipped( - "Encoding {$encoding} not supported by " . get_class($this->stringWrapper) - ); + $wrapper = $this->getWrapper($encoding); + if (!$wrapper) { + $this->markTestSkipped("Encoding {$encoding} not supported"); } - $result = $this->stringWrapper->strPad($input, $padLength, $padString, $padType, $encoding); + $result = $wrapper->strPad($input, $padLength, $padString, $padType); $this->assertSame($expected, $result); } } diff --git a/test/StringWrapper/IconvTest.php b/test/StringWrapper/IconvTest.php index 92a83e1c6..b1f3a0bba 100644 --- a/test/StringWrapper/IconvTest.php +++ b/test/StringWrapper/IconvTest.php @@ -21,14 +21,26 @@ public function setUp() { if (!extension_loaded('iconv')) { try { - new Iconv(); + new Iconv('utf-8'); $this->fail('Missing expected Zend\Stdlib\Exception\ExtensionNotLoadedException'); } catch (Exception\ExtensionNotLoadedException $e) { $this->markTestSkipped('Missing ext/iconv'); } } - $this->stringWrapper = new Iconv(); parent::setUp(); } + + protected function getWrapper($encoding = null, $convertEncoding = null) + { + if ($encoding === null) { + $supportedEncodings = Iconv::getSupportedEncodings(); + $encoding = array_shift($supportedEncodings); + } + + if (!Iconv::isSupported($encoding, $convertEncoding)) { + return false; + } + return new Iconv($encoding, $convertEncoding); + } } diff --git a/test/StringWrapper/IntlTest.php b/test/StringWrapper/IntlTest.php index f764b3d98..ab2ae0402 100644 --- a/test/StringWrapper/IntlTest.php +++ b/test/StringWrapper/IntlTest.php @@ -21,14 +21,26 @@ public function setUp() { if (!extension_loaded('intl')) { try { - new Intl(); + new Intl('utf-8'); $this->fail('Missing expected Zend\Stdlib\Exception\ExtensionNotLoadedException'); } catch (Exception\ExtensionNotLoadedException $e) { $this->markTestSkipped('Missing ext/intl'); } } - $this->stringWrapper = new Intl(); parent::setUp(); } + + protected function getWrapper($encoding = null, $convertEncoding = null) + { + if ($encoding === null) { + $supportedEncodings = Intl::getSupportedEncodings(); + $encoding = array_shift($supportedEncodings); + } + + if (!Intl::isSupported($encoding, $convertEncoding)) { + return false; + } + return new Intl($encoding, $convertEncoding); + } } diff --git a/test/StringWrapper/MbStringTest.php b/test/StringWrapper/MbStringTest.php index bd6ee7aec..fe4a5500d 100644 --- a/test/StringWrapper/MbStringTest.php +++ b/test/StringWrapper/MbStringTest.php @@ -21,14 +21,26 @@ public function setUp() { if (!extension_loaded('mbstring')) { try { - new MbString(); + new MbString('utf-8'); $this->fail('Missing expected Zend\Stdlib\Exception\ExtensionNotLoadedException'); } catch (Exception\ExtensionNotLoadedException $e) { $this->markTestSkipped('Missing ext/mbstring'); } } - $this->stringWrapper = new MbString(); parent::setUp(); } + + protected function getWrapper($encoding = null, $convertEncoding = null) + { + if ($encoding === null) { + $supportedEncodings = MbString::getSupportedEncodings(); + $encoding = array_shift($supportedEncodings); + } + + if (!MbString::isSupported($encoding, $convertEncoding)) { + return false; + } + return new MbString($encoding, $convertEncoding); + } } diff --git a/test/StringWrapper/NativeTest.php b/test/StringWrapper/NativeTest.php index 329a19ba3..8f3b64ccd 100644 --- a/test/StringWrapper/NativeTest.php +++ b/test/StringWrapper/NativeTest.php @@ -16,9 +16,16 @@ class NativeTest extends CommonStringWrapperTest { - public function setUp() + protected function getWrapper($encoding = null, $convertEncoding = null) { - $this->stringWrapper = new Native(); - parent::setUp(); + if ($encoding === null) { + $supportedEncodings = Native::getSupportedEncodings(); + $encoding = array_shift($supportedEncodings); + } + + if (!Native::isSupported($encoding, $convertEncoding)) { + return false; + } + return new Native($encoding, $convertEncoding); } } From fcc4099982a634221ffcfc2b5d3b65e765e5278a Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Mon, 31 Dec 2012 17:50:03 +0100 Subject: [PATCH 031/127] Updated consumers after API changes --- src/StringWrapper/AbstractStringWrapper.php | 2 +- src/StringWrapper/StringWrapperInterface.php | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 69a658f2a..89ad28ce6 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -72,7 +72,7 @@ public function __construct($encoding, $convertEncoding = null) * @param string|null $convertEncoding The character encoding to convert to * @return StringWrapperInterface */ - public function setEncoding($encoding, $convertEncoding) + public function setEncoding($encoding, $convertEncoding = null) { $supportedEncodings = static::getSupportedEncodings(); diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index f99dbf73c..bba34fe23 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -41,6 +41,15 @@ public static function getSupportedEncodings(); */ public function __construct($encoding, $convertEncoding = null); + /** + * Set character encoding working with and convert to + * + * @param string $encoding The character encoding to work with + * @param string|null $convertEncoding The character encoding to convert to + * @return StringWrapperInterface + */ + public function setEncoding($encoding, $convertEncoding = null); + /** * Returns the length of the given string * From 3f8e987db50fba3a6c403639f9130ddbdeaf8778 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 2 Jan 2013 18:34:32 +0100 Subject: [PATCH 032/127] It's 2013 --- src/StringUtils.php | 2 +- src/StringWrapper/AbstractStringWrapper.php | 2 +- src/StringWrapper/Iconv.php | 2 +- src/StringWrapper/Intl.php | 2 +- src/StringWrapper/MbString.php | 2 +- src/StringWrapper/Native.php | 2 +- src/StringWrapper/StringWrapperInterface.php | 2 +- test/StringUtilsTest.php | 2 +- test/StringWrapper/CommonStringWrapperTest.php | 2 +- test/StringWrapper/IconvTest.php | 2 +- test/StringWrapper/IntlTest.php | 2 +- test/StringWrapper/MbStringTest.php | 2 +- test/StringWrapper/NativeTest.php | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 68ce89bed..031800b70 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 89ad28ce6..4b4e8544c 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index f4982fb12..946624474 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index 7b48accd6..3669e002b 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index bf72a5a7c..4ae1f1b1c 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index 69468bd69..0f26fcb08 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index bba34fe23..35467cef0 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php index 156431dde..fefed5807 100644 --- a/test/StringUtilsTest.php +++ b/test/StringUtilsTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php index 6bea2a0d6..5ae04708a 100644 --- a/test/StringWrapper/CommonStringWrapperTest.php +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib * @subpackage StringWrapper diff --git a/test/StringWrapper/IconvTest.php b/test/StringWrapper/IconvTest.php index b1f3a0bba..2819b6b00 100644 --- a/test/StringWrapper/IconvTest.php +++ b/test/StringWrapper/IconvTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib * @subpackage StringWrapper diff --git a/test/StringWrapper/IntlTest.php b/test/StringWrapper/IntlTest.php index ab2ae0402..efa3fdddb 100644 --- a/test/StringWrapper/IntlTest.php +++ b/test/StringWrapper/IntlTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib * @subpackage StringWrapper diff --git a/test/StringWrapper/MbStringTest.php b/test/StringWrapper/MbStringTest.php index fe4a5500d..01f332bee 100644 --- a/test/StringWrapper/MbStringTest.php +++ b/test/StringWrapper/MbStringTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib * @subpackage StringWrapper diff --git a/test/StringWrapper/NativeTest.php b/test/StringWrapper/NativeTest.php index 8f3b64ccd..9a3716dbd 100644 --- a/test/StringWrapper/NativeTest.php +++ b/test/StringWrapper/NativeTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib * @subpackage StringWrapper From f3be23de92d016517212cb12133502d867d7b0b7 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 3 Jan 2013 15:23:07 +0100 Subject: [PATCH 033/127] else isn't needed, as the previous block returns on completion + removed call to strlen if length of padding is less than or equal 0 --- src/StringWrapper/AbstractStringWrapper.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 4b4e8544c..eebf006fa 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -222,9 +222,12 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD } $lengthOfPadding = $padLength - $this->strlen($input); - $padStringLength = $this->strlen($padString); + if ($lengthOfPadding <= 0) { + return $input; + } - if ($padStringLength === 0 || $lengthOfPadding <= 0) { + $padStringLength = $this->strlen($padString); + if ($padStringLength === 0) { return $input; } @@ -245,14 +248,14 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD return str_repeat($padString, $repeatCountLeft) . $lastStringLeft . $input . str_repeat($padString, $repeatCountRight) . $lastStringRight; - } else { - $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength); + } - if ($padType === \STR_PAD_LEFT) { - return str_repeat($padString, $repeatCount) . $lastString . $input; - } else { - return $input . str_repeat($padString, $repeatCount) . $lastString; - } + $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength); + + if ($padType === \STR_PAD_LEFT) { + return str_repeat($padString, $repeatCount) . $lastString . $input; } + + return $input . str_repeat($padString, $repeatCount) . $lastString; } } From 4e9d332c137ca52dd626eedfb83644d3da13a520 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 3 Jan 2013 15:41:34 +0100 Subject: [PATCH 034/127] StringWrapper::convert() Renamed second argument to and fixed phpdoc --- src/StringWrapper/AbstractStringWrapper.php | 11 +++++------ src/StringWrapper/Iconv.php | 11 +++++------ src/StringWrapper/MbString.php | 11 +++++------ src/StringWrapper/StringWrapperInterface.php | 4 ++-- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index eebf006fa..2f3bc1feb 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -105,18 +105,17 @@ public function setEncoding($encoding, $convertEncoding = null) * Convert a string from one character encoding to another * * @param string $str - * @param boolean $backward + * @param boolean $reverse * @return string|false */ - public function convert($str, $backward = false) + public function convert($str, $reverse = false) { - $from = $backward ? $this->convertEncoding : $this->encoding; - $to = $backward ? $this->encoding : $this->convertEncoding; - - if ($to == $from) { + if ($this->encoding === $this->convertEncoding) { return $str; } + $from = $reverse ? $this->convertEncoding : $this->encoding; + $to = $reverse ? $this->encoding : $this->convertEncoding; throw new Exception\RuntimeException(sprintf( 'Converting from "%s" to "%s" isn\'t supported by this string wrapper', $from, diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 946624474..abbecbd02 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -185,15 +185,14 @@ public function strpos($haystack, $needle, $offset = 0) /** * Convert a string from one character encoding to another * - * @param string $str - * @param string $toEncoding - * @param string $fromEncoding + * @param string $str + * @param boolean $reverse * @return string|false */ - public function convert($str, $backword = false) + public function convert($str, $reverse = false) { - $fromEncoding = $backword ? $this->convertEncoding : $this->encoding; - $toEncoding = $backword ? $this->encoding : $this->convertEncoding; + $fromEncoding = $reverse ? $this->convertEncoding : $this->encoding; + $toEncoding = $reverse ? $this->encoding : $this->convertEncoding; return iconv($fromEncoding, $toEncoding, $str); } } diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 4ae1f1b1c..72af7fe84 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -106,15 +106,14 @@ public function strpos($haystack, $needle, $offset = 0) /** * Convert a string from one character encoding to another * - * @param string $str - * @param string $toEncoding - * @param string $fromEncoding + * @param string $str + * @param boolean $reverse * @return string|false */ - public function convert($str, $backword = false) + public function convert($str, $reverse = false) { - $fromEncoding = $backword ? $this->convertEncoding : $this->encoding; - $toEncoding = $backword ? $this->encoding : $this->convertEncoding; + $fromEncoding = $reverse ? $this->convertEncoding : $this->encoding; + $toEncoding = $reverse ? $this->encoding : $this->convertEncoding; return mb_convert_encoding($str, $toEncoding, $fromEncoding); } } diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index 35467cef0..f0251d16f 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -84,10 +84,10 @@ public function strpos($haystack, $needle, $offset = 0); * Convert a string from one character encoding to another * * @param string $str - * @param boolean $backward + * @param boolean $reverse * @return string|false */ - public function convert($str, $backward = false); + public function convert($str, $reverse = false); /** * Wraps a string to a given number of characters From b19de9b20b99646fee11d5da83b5eca290df0287 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 3 Jan 2013 15:45:36 +0100 Subject: [PATCH 035/127] phpdoc --- src/StringWrapper/AbstractStringWrapper.php | 2 +- src/StringWrapper/Iconv.php | 2 +- src/StringWrapper/MbString.php | 2 +- src/StringWrapper/StringWrapperInterface.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 2f3bc1feb..9613f372a 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -102,7 +102,7 @@ public function setEncoding($encoding, $convertEncoding = null) } /** - * Convert a string from one character encoding to another + * Convert a string from defined encoding to the defined convert encoding * * @param string $str * @param boolean $reverse diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index abbecbd02..d1aaa03ac 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -183,7 +183,7 @@ public function strpos($haystack, $needle, $offset = 0) } /** - * Convert a string from one character encoding to another + * Convert a string from defined encoding to the defined convert encoding * * @param string $str * @param boolean $reverse diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 72af7fe84..8d8d49a75 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -104,7 +104,7 @@ public function strpos($haystack, $needle, $offset = 0) } /** - * Convert a string from one character encoding to another + * Convert a string from defined encoding to the defined convert encoding * * @param string $str * @param boolean $reverse diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index f0251d16f..4dc133fb1 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -81,7 +81,7 @@ public function substr($str, $offset = 0, $length = null); public function strpos($haystack, $needle, $offset = 0); /** - * Convert a string from one character encoding to another + * Convert a string from defined encoding to the defined convert encoding * * @param string $str * @param boolean $reverse From 0c8aeba1e5cf8b79fef4dd418863522a8ef86ed9 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 3 Jan 2013 16:19:24 +0100 Subject: [PATCH 036/127] The native string wrapper doesn't support to convert between encodings --- src/StringWrapper/AbstractStringWrapper.php | 3 +- src/StringWrapper/Native.php | 63 +++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 9613f372a..50621cd03 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -102,7 +102,7 @@ public function setEncoding($encoding, $convertEncoding = null) } /** - * Convert a string from defined encoding to the defined convert encoding + * Convert a string from defined character encoding to the defined convert encoding * * @param string $str * @param boolean $reverse @@ -114,6 +114,7 @@ public function convert($str, $reverse = false) return $str; } + var_dump($this->encoding, $this->convertEncoding); $from = $reverse ? $this->convertEncoding : $this->encoding; $to = $reverse ? $this->encoding : $this->convertEncoding; throw new Exception\RuntimeException(sprintf( diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index 0f26fcb08..8ddcf3d6c 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -10,6 +10,7 @@ namespace Zend\Stdlib\StringWrapper; +use Zend\Stdlib\Exception; use Zend\Stdlib\StringUtils; /** @@ -19,6 +20,30 @@ */ class Native extends AbstractStringWrapper { + /** + * Check if the given character encoding is supported by this wrapper + * and the character encoding to convert to is also supported. + * + * @param string $encoding + * @param string|null $convertEncoding + */ + public static function isSupported($encoding, $convertEncoding = null) + { + $encodingUpper = strtoupper($encoding); + $supportedEncodings = static::getSupportedEncodings(); + + if (!in_array($encodingUpper, $supportedEncodings)) { + return false; + } + + // This adapter doesn't support to convert between encodings + if ($convertEncoding !== null && $encodingUpper !== strtoupper($convertEncoding)) { + return false; + } + + return true; + } + /** * Get a list of supported character encodings * @@ -29,6 +54,44 @@ public static function getSupportedEncodings() return StringUtils::getSingleByteEncodings(); } + /** + * Set character encoding working with and convert to + * + * @param string $encoding The character encoding to work with + * @param string|null $convertEncoding The character encoding to convert to + * @return StringWrapperInterface + */ + public function setEncoding($encoding, $convertEncoding = null) + { + $supportedEncodings = static::getSupportedEncodings(); + + $encodingUpper = strtoupper($encoding); + if (!in_array($encodingUpper, $supportedEncodings)) { + throw new Exception\InvalidArgumentException( + 'Wrapper doesn\'t support character encoding "' . $encoding . '"' + ); + } + + if ($encodingUpper !== strtoupper($convertEncoding)) { + $this->convertEncoding = $encodingUpper; + } + + if ($convertEncoding !== null) { + if ($encodingUpper !== strtoupper($convertEncoding)) { + throw new Exception\InvalidArgumentException( + 'Wrapper doesn\'t support to convert between character encodings' + ); + } + + $this->convertEncoding = $encodingUpper; + } else { + $this->convertEncoding = null; + } + $this->encoding = $encodingUpper; + + return $this; + } + /** * Returns the length of the given string * From 6ecb74d29db33ddd54eccf22c277dc03fb7c8583 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 3 Jan 2013 16:24:23 +0100 Subject: [PATCH 037/127] Added note why encodings are typed in case-mix --- test/StringUtilsTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php index fefed5807..7bcde696c 100644 --- a/test/StringUtilsTest.php +++ b/test/StringUtilsTest.php @@ -38,9 +38,10 @@ public function tearDown() public function getSingleByEncodings() { return array( + // case-mix to check case-insensitivity array('AscII'), - array('7bit'), - array('8bit'), + array('7bIt'), + array('8Bit'), array('ISo-8859-1'), array('ISo-8859-2'), array('ISo-8859-3'), From 212a253fcb7b796449919608965d3609a538b61c Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 3 Jan 2013 23:28:04 +0100 Subject: [PATCH 038/127] added methods get[Convert]Encoding() and removed constructor from interface --- src/StringUtils.php | 4 +- src/StringWrapper/AbstractStringWrapper.php | 54 +++++++++++++------- src/StringWrapper/Iconv.php | 26 +++++++--- src/StringWrapper/Intl.php | 4 +- src/StringWrapper/MbString.php | 27 +++++++--- src/StringWrapper/Native.php | 8 +++ src/StringWrapper/StringWrapperInterface.php | 22 +++++--- test/StringWrapper/IconvTest.php | 5 +- test/StringWrapper/IntlTest.php | 5 +- test/StringWrapper/MbStringTest.php | 5 +- test/StringWrapper/NativeTest.php | 5 +- 11 files changed, 115 insertions(+), 50 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 031800b70..65e6004cc 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -114,7 +114,9 @@ public static function getWrapper($encoding = 'UTF-8', $convertEncoding = null) { foreach (static::getRegisteredWrappers() as $wrapperClass) { if ($wrapperClass::isSupported($encoding, $convertEncoding)) { - return new $wrapperClass($encoding, $convertEncoding); + $wrapper = new $wrapperClass($encoding, $convertEncoding); + $wrapper->setEncoding($encoding, $convertEncoding); + return $wrapper; } } diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 50621cd03..60e2730be 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -24,7 +24,7 @@ abstract class AbstractStringWrapper implements StringWrapperInterface * The character encoding working on * @var string|null */ - protected $encoding; + protected $encoding = 'UTF-8'; /** * An optionally character encoding to convert to @@ -54,17 +54,6 @@ public static function isSupported($encoding, $convertEncoding = null) return true; } - /** - * Constructor - * @param string $encoding Character encoding working on - * @param string|null $convertEncoding Character encoding to convert to - * @throws Exception\InvalidArgumentException - */ - public function __construct($encoding, $convertEncoding = null) - { - $this->setEncoding($encoding, $convertEncoding); - } - /** * Set character encoding working with and convert to * @@ -101,6 +90,28 @@ public function setEncoding($encoding, $convertEncoding = null) return $this; } + + /** + * Get the defined character encoding to work with + * + * @return string + * @throws Exception\LogicException If no encoding was defined + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Get the defined character encoding to convert to + * + * @return string|null + */ + public function getConvertEncoding() + { + return $this->convertEncoding; + } + /** * Convert a string from defined character encoding to the defined convert encoding * @@ -110,13 +121,20 @@ public function setEncoding($encoding, $convertEncoding = null) */ public function convert($str, $reverse = false) { - if ($this->encoding === $this->convertEncoding) { + $encoding = $this->getEncoding(); + $convertEncoding = $this->getConvertEncoding(); + if ($convertEncoding === null) { + throw new Exception\LogicException( + 'No convert encoding defined' + ); + } + + if ($encoding === $convertEncoding) { return $str; } - var_dump($this->encoding, $this->convertEncoding); - $from = $reverse ? $this->convertEncoding : $this->encoding; - $to = $reverse ? $this->encoding : $this->convertEncoding; + $from = $reverse ? $convertEncoding : $encoding; + $to = $reverse ? $encoding : $convertEncoding; throw new Exception\RuntimeException(sprintf( 'Converting from "%s" to "%s" isn\'t supported by this string wrapper', $from, @@ -151,7 +169,7 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false) throw new Exception\InvalidArgumentException('Cannot force cut when width is zero'); } - if (StringUtils::isSingleByteEncoding($this->encoding)) { + if (StringUtils::isSingleByteEncoding($this->getEncoding())) { return wordwrap($string, $width, $break, $cut); } @@ -217,7 +235,7 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false) */ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT) { - if (StringUtils::isSingleByteEncoding($this->encoding)) { + if (StringUtils::isSingleByteEncoding($this->getEncoding())) { return str_pad($input, $padLength, $padString, $padType); } diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index d1aaa03ac..2588dd185 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -131,15 +131,13 @@ public static function getSupportedEncodings() * * @throws Exception\ExtensionNotLoadedException */ - public function __construct($encoding, $convertEncoding = null) + public function __construct() { if (!extension_loaded('iconv')) { throw new Exception\ExtensionNotLoadedException( 'PHP extension "iconv" is required for this wrapper' ); } - - parent::__construct($encoding, $convertEncoding); } /** @@ -151,7 +149,7 @@ public function __construct($encoding, $convertEncoding = null) */ public function strlen($str) { - return iconv_strlen($str, $this->encoding); + return iconv_strlen($str, $this->getEncoding()); } /** @@ -165,7 +163,7 @@ public function strlen($str) */ public function substr($str, $offset = 0, $length = null) { - return iconv_substr($str, $offset, $length, $this->encoding); + return iconv_substr($str, $offset, $length, $this->getEncoding()); } /** @@ -179,7 +177,7 @@ public function substr($str, $offset = 0, $length = null) */ public function strpos($haystack, $needle, $offset = 0) { - return iconv_strpos($haystack, $needle, $offset, $this->encoding); + return iconv_strpos($haystack, $needle, $offset, $this->getEncoding()); } /** @@ -191,8 +189,20 @@ public function strpos($haystack, $needle, $offset = 0) */ public function convert($str, $reverse = false) { - $fromEncoding = $reverse ? $this->convertEncoding : $this->encoding; - $toEncoding = $reverse ? $this->encoding : $this->convertEncoding; + $encoding = $this->getEncoding(); + $convertEncoding = $this->getConvertEncoding(); + if ($convertEncoding === null) { + throw new Exception\LogicException( + 'No convert encoding defined' + ); + } + + if ($encoding === $convertEncoding) { + return $str; + } + + $fromEncoding = $reverse ? $convertEncoding : $encoding; + $toEncoding = $reverse ? $encoding : $convertEncoding; return iconv($fromEncoding, $toEncoding, $str); } } diff --git a/src/StringWrapper/Intl.php b/src/StringWrapper/Intl.php index 3669e002b..c7eacaa24 100644 --- a/src/StringWrapper/Intl.php +++ b/src/StringWrapper/Intl.php @@ -41,15 +41,13 @@ public static function getSupportedEncodings() * * @throws Exception\ExtensionNotLoadedException */ - public function __construct($encoding, $convertEncoding = null) + public function __construct() { if (!extension_loaded('intl')) { throw new Exception\ExtensionNotLoadedException( 'PHP extension "intl" is required for this wrapper' ); } - - parent::__construct($encoding, $convertEncoding); } /** diff --git a/src/StringWrapper/MbString.php b/src/StringWrapper/MbString.php index 8d8d49a75..62782dab6 100644 --- a/src/StringWrapper/MbString.php +++ b/src/StringWrapper/MbString.php @@ -52,15 +52,13 @@ public static function getSupportedEncodings() * * @throws Exception\ExtensionNotLoadedException */ - public function __construct($encoding, $convertEncoding = null) + public function __construct() { if (!extension_loaded('mbstring')) { throw new Exception\ExtensionNotLoadedException( 'PHP extension "mbstring" is required for this wrapper' ); } - - parent::__construct($encoding, $convertEncoding); } /** @@ -72,7 +70,7 @@ public function __construct($encoding, $convertEncoding = null) */ public function strlen($str) { - return mb_strlen($str, $this->encoding); + return mb_strlen($str, $this->getEncoding()); } /** @@ -86,7 +84,7 @@ public function strlen($str) */ public function substr($str, $offset = 0, $length = null) { - return mb_substr($str, $offset, $length, $this->encoding); + return mb_substr($str, $offset, $length, $this->getEncoding()); } /** @@ -100,7 +98,7 @@ public function substr($str, $offset = 0, $length = null) */ public function strpos($haystack, $needle, $offset = 0) { - return mb_strpos($haystack, $needle, $offset, $this->encoding); + return mb_strpos($haystack, $needle, $offset, $this->getEncoding()); } /** @@ -112,8 +110,21 @@ public function strpos($haystack, $needle, $offset = 0) */ public function convert($str, $reverse = false) { - $fromEncoding = $reverse ? $this->convertEncoding : $this->encoding; - $toEncoding = $reverse ? $this->encoding : $this->convertEncoding; + $encoding = $this->getEncoding(); + $convertEncoding = $this->getConvertEncoding(); + + if ($convertEncoding === null) { + throw new Exception\LogicException( + 'No convert encoding defined' + ); + } + + if ($encoding === $convertEncoding) { + return $str; + } + + $fromEncoding = $reverse ? $convertEncoding : $encoding; + $toEncoding = $reverse ? $encoding : $convertEncoding; return mb_convert_encoding($str, $toEncoding, $fromEncoding); } } diff --git a/src/StringWrapper/Native.php b/src/StringWrapper/Native.php index 8ddcf3d6c..375b46f28 100644 --- a/src/StringWrapper/Native.php +++ b/src/StringWrapper/Native.php @@ -20,6 +20,14 @@ */ class Native extends AbstractStringWrapper { + /** + * The character encoding working on + * (overwritten to change defaut encoding) + * + * @var string + */ + protected $encoding = 'ASCII'; + /** * Check if the given character encoding is supported by this wrapper * and the character encoding to convert to is also supported. diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index 4dc133fb1..401cda3fd 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -33,14 +33,6 @@ public static function isSupported($encoding, $convertEncoding = null); */ public static function getSupportedEncodings(); - /** - * Constructor - * - * @param string $encoding Character encoding working on - * @param string|null $convertEncoding Character encoding to convert to - */ - public function __construct($encoding, $convertEncoding = null); - /** * Set character encoding working with and convert to * @@ -50,6 +42,20 @@ public function __construct($encoding, $convertEncoding = null); */ public function setEncoding($encoding, $convertEncoding = null); + /** + * Get the defined character encoding to work with (upper case) + * + * @return string|null + */ + public function getEncoding(); + + /** + * Get the defined character encoding to convert to (upper case) + * + * @return string|null + */ + public function getConvertEncoding(); + /** * Returns the length of the given string * diff --git a/test/StringWrapper/IconvTest.php b/test/StringWrapper/IconvTest.php index 2819b6b00..ec3b0db24 100644 --- a/test/StringWrapper/IconvTest.php +++ b/test/StringWrapper/IconvTest.php @@ -41,6 +41,9 @@ protected function getWrapper($encoding = null, $convertEncoding = null) if (!Iconv::isSupported($encoding, $convertEncoding)) { return false; } - return new Iconv($encoding, $convertEncoding); + + $wrapper = new Iconv(); + $wrapper->setEncoding($encoding, $convertEncoding); + return $wrapper; } } diff --git a/test/StringWrapper/IntlTest.php b/test/StringWrapper/IntlTest.php index efa3fdddb..d3092f60b 100644 --- a/test/StringWrapper/IntlTest.php +++ b/test/StringWrapper/IntlTest.php @@ -41,6 +41,9 @@ protected function getWrapper($encoding = null, $convertEncoding = null) if (!Intl::isSupported($encoding, $convertEncoding)) { return false; } - return new Intl($encoding, $convertEncoding); + + $wrapper = new Intl(); + $wrapper->setEncoding($encoding, $convertEncoding); + return $wrapper; } } diff --git a/test/StringWrapper/MbStringTest.php b/test/StringWrapper/MbStringTest.php index 01f332bee..d024afaa6 100644 --- a/test/StringWrapper/MbStringTest.php +++ b/test/StringWrapper/MbStringTest.php @@ -41,6 +41,9 @@ protected function getWrapper($encoding = null, $convertEncoding = null) if (!MbString::isSupported($encoding, $convertEncoding)) { return false; } - return new MbString($encoding, $convertEncoding); + + $wrapper = new MbString(); + $wrapper->setEncoding($encoding, $convertEncoding); + return $wrapper; } } diff --git a/test/StringWrapper/NativeTest.php b/test/StringWrapper/NativeTest.php index 9a3716dbd..b54e41daa 100644 --- a/test/StringWrapper/NativeTest.php +++ b/test/StringWrapper/NativeTest.php @@ -26,6 +26,9 @@ protected function getWrapper($encoding = null, $convertEncoding = null) if (!Native::isSupported($encoding, $convertEncoding)) { return false; } - return new Native($encoding, $convertEncoding); + + $wrapper = new Native(); + $wrapper->setEncoding($encoding, $convertEncoding); + return $wrapper; } } From 5f991bfd04937b16a5dbcfad288fa202116bb142 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 3 Jan 2013 23:29:49 +0100 Subject: [PATCH 039/127] fixed phpdoc --- src/StringWrapper/StringWrapperInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index 401cda3fd..888f9c3d6 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -45,7 +45,7 @@ public function setEncoding($encoding, $convertEncoding = null); /** * Get the defined character encoding to work with (upper case) * - * @return string|null + * @return string */ public function getEncoding(); From 1d0e607d53cafff968c7a34582e586e1e5f89e2c Mon Sep 17 00:00:00 2001 From: ingo Date: Sat, 5 Jan 2013 04:53:31 +0100 Subject: [PATCH 040/127] Added tests --- test/HydratorTest.php | 4 +++ .../ClassMethodsInvalidParameter.php | 25 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/test/HydratorTest.php b/test/HydratorTest.php index f8cddf9ce..7717099cc 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -215,5 +215,9 @@ public function testHydratorClassMethodsWithServiceManager() { $hydrator = new ClassMethods(false); $datas = $hydrator->extract($this->classMethodsInvalidParameter); + + $this->assertTrue($datas['hasBar']); + $this->assertEquals('Bar', $datas['foo']); + $this->assertFalse($datas['isBla']); } } diff --git a/test/TestAsset/ClassMethodsInvalidParameter.php b/test/TestAsset/ClassMethodsInvalidParameter.php index 471577373..cf9338865 100644 --- a/test/TestAsset/ClassMethodsInvalidParameter.php +++ b/test/TestAsset/ClassMethodsInvalidParameter.php @@ -15,4 +15,29 @@ public function hasAlias($alias) { return $alias; } + + public function getTest($foo) + { + return $foo; + } + + public function isTest($bar) + { + return $bar; + } + + public function hasBar() + { + return true; + } + + public function getFoo() + { + return "Bar"; + } + + public function isBla() + { + return false; + } } From 0b94b67e570c91ae33435de38fdeb211e41189d9 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 6 Jan 2013 15:16:48 +0100 Subject: [PATCH 041/127] psr --- src/StringWrapper/AbstractStringWrapper.php | 1 - src/StringWrapper/Iconv.php | 149 +++++++++++++++----- 2 files changed, 117 insertions(+), 33 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 60e2730be..8b19605ae 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -90,7 +90,6 @@ public function setEncoding($encoding, $convertEncoding = null) return $this; } - /** * Get the defined character encoding to work with * diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 2588dd185..d81315790 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -28,83 +28,167 @@ class Iconv extends AbstractStringWrapper protected static $encodings = array( // European languages 'ASCII', - 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-7', - 'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', - 'KOI8-R', 'KOI8-U', 'KOI8-RU', - 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254', 'CP1257', 'CP850', 'CP866', 'CP1131', - 'MACROMAN', 'MACCENTRALEUROPE', 'MACICELAND', 'MACCROATIAN', 'MACROMANIA', - 'MACCYRILLIC', 'MACUKRAINE', 'MACGREEK', 'MACTURKISH', 'MACINTOSH', + 'ISO-8859-1', + 'ISO-8859-2', + 'ISO-8859-3', + 'ISO-8859-4', + 'ISO-8859-5', + 'ISO-8859-7', + 'ISO-8859-9', + 'ISO-8859-10', + 'ISO-8859-13', + 'ISO-8859-14', + 'ISO-8859-15', + 'ISO-8859-16', + 'KOI8-R', + 'KOI8-U', + 'KOI8-RU', + 'CP1250', + 'CP1251', + 'CP1252', + 'CP1253', + 'CP1254', + 'CP1257', + 'CP850', + 'CP866', + 'CP1131', + 'MACROMAN', + 'MACCENTRALEUROPE', + 'MACICELAND', + 'MACCROATIAN', + 'MACROMANIA', + 'MACCYRILLIC', + 'MACUKRAINE', + 'MACGREEK', + 'MACTURKISH', + 'MACINTOSH', // Semitic languages - 'ISO-8859-6', 'ISO-8859-8', - 'CP1255', 'CP1256', 'CP862', - 'MACHEBREW', 'MACARABIC', + 'ISO-8859-6', + 'ISO-8859-8', + 'CP1255', + 'CP1256', + 'CP862', + 'MACHEBREW', + 'MACARABIC', // Japanese - 'EUC-JP', 'SHIFT_JIS', 'CP932', - 'ISO-2022-JP', 'ISO-2022-JP-2', 'ISO-2022-JP-1', + 'EUC-JP', + 'SHIFT_JIS', + 'CP932', + 'ISO-2022-JP', + 'ISO-2022-JP-2', + 'ISO-2022-JP-1', // Chinese - 'EUC-CN', 'HZ', 'GBK', 'CP936', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', - 'BIG5-HKSCS', 'BIG5-HKSCS:2004', 'BIG5-HKSCS:2001', 'BIG5-HKSCS:1999', - 'ISO-2022-CN', 'ISO-2022-CN-EXT', + 'EUC-CN', + 'HZ', + 'GBK', + 'CP936', + 'GB18030', + 'EUC-TW', + 'BIG5', + 'CP950', + 'BIG5-HKSCS', + 'BIG5-HKSCS:2004', + 'BIG5-HKSCS:2001', + 'BIG5-HKSCS:1999', + 'ISO-2022-CN', + 'ISO-2022-CN-EXT', // Korean - 'EUC-KR', 'CP949', 'ISO-2022-KR', 'JOHAB', + 'EUC-KR', + 'CP949', + 'ISO-2022-KR', + 'JOHAB', // Armenian 'ARMSCII-8', // Georgian - 'GEORGIAN-ACADEMY', 'GEORGIAN-PS', + 'GEORGIAN-ACADEMY', + 'GEORGIAN-PS', // Tajik 'KOI8-T', // Kazakh - 'PT154', 'RK1048', + 'PT154', + 'RK1048', // Thai - 'ISO-8859-11', 'TIS-620', 'CP874', 'MACTHAI', + 'ISO-8859-11', + 'TIS-620', + 'CP874', + 'MACTHAI', // Laotian - 'MULELAO-1', 'CP1133', + 'MULELAO-1', + 'CP1133', // Vietnamese - 'VISCII', 'TCVN', 'CP1258', + 'VISCII', + 'TCVN', + 'CP1258', // Platform specifics - 'HP-ROMAN8', 'NEXTSTEP', + 'HP-ROMAN8', + 'NEXTSTEP', // Full Unicode 'UTF-8', - 'UCS-2', 'UCS-2BE', 'UCS-2LE', - 'UCS-4', 'UCS-4BE', 'UCS-4LE', - 'UTF-16', 'UTF-16BE', 'UTF-16LE', - 'UTF-32', 'UTF-32BE', 'UTF-32LE', + 'UCS-2', + 'UCS-2BE', + 'UCS-2LE', + 'UCS-4', + 'UCS-4BE', + 'UCS-4LE', + 'UTF-16', + 'UTF-16BE', + 'UTF-16LE', + 'UTF-32', + 'UTF-32BE', + 'UTF-32LE', 'UTF-7', - 'C99', 'JAVA', + 'C99', + 'JAVA', // Full Unicode, in terms of uint16_t or uint32_t (with machine dependent endianness and alignment) - // 'UCS-2-INTERNAL', 'UCS-4-INTERNAL', + // 'UCS-2-INTERNAL', + // 'UCS-4-INTERNAL', // Locale dependent, in terms of `char' or `wchar_t' (with machine dependent endianness and alignment, // and with OS and locale dependent semantics) - // 'char', 'wchar_t', + // 'char', + // 'wchar_t', // '', // The empty encoding name is equivalent to "char": it denotes the locale dependent character encoding. // When configured with the option --enable-extra-encodings, // it also provides support for a few extra encodings: // European languages - 'CP437', 'CP737', 'CP775', 'CP852', 'CP853', 'CP855', 'CP857', 'CP858', - 'CP860', 'CP861', 'CP863', 'CP865', 'CP869', 'CP1125', + 'CP437', + 'CP737', + 'CP775', + 'CP852', + 'CP853', + 'CP855', + 'CP857', + 'CP858', + 'CP860', + 'CP861', + 'CP863', + 'CP865', + 'CP869', + 'CP1125', // Semitic languages 'CP864', // Japanese - 'EUC-JISX0213', 'Shift_JISX0213', 'ISO-2022-JP-3', + 'EUC-JISX0213', + 'Shift_JISX0213', + 'ISO-2022-JP-3', // Chinese 'BIG5-2003', // (experimental) @@ -113,7 +197,8 @@ class Iconv extends AbstractStringWrapper 'TDS565', // Platform specifics - 'ATARIST', 'RISCOS-LATIN1', + 'ATARIST', + 'RISCOS-LATIN1', ); /** From f48fd28848c1783a2ebdc0b19c8bb69b56a0087b Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 6 Jan 2013 15:21:56 +0100 Subject: [PATCH 042/127] added StringUtils::resetRegisteredWrappers() for testing purposes --- src/StringUtils.php | 12 +++++++++++- test/StringUtilsTest.php | 17 +---------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/StringUtils.php b/src/StringUtils.php index 65e6004cc..47e362692 100644 --- a/src/StringUtils.php +++ b/src/StringUtils.php @@ -29,7 +29,7 @@ abstract class StringUtils * * @var StringWrapperInterface[] */ - protected static $wrapperRegistry; + protected static $wrapperRegistry = null; /** * A list of known single-byte character encodings (upper-case) @@ -101,6 +101,16 @@ public static function unregisterWrapper($wrapper) } } + /** + * Reset all registered wrappers so the default wrappers will be used + * + * @return void + */ + public static function resetRegisteredWrappers() + { + static::$wrapperRegistry = null; + } + /** * Get the first string wrapper supporting the given character encoding * and supports to convert into the given convert encoding. diff --git a/test/StringUtilsTest.php b/test/StringUtilsTest.php index 7bcde696c..bb27a59bf 100644 --- a/test/StringUtilsTest.php +++ b/test/StringUtilsTest.php @@ -15,24 +15,9 @@ class StringUtilsTest extends TestCase { - - protected $bufferedWrappers; - - public function setUp() - { - $this->bufferedWrappers = StringUtils::getRegisteredWrappers(); - } - public function tearDown() { - // reset registered wrappers - foreach (StringUtils::getRegisteredWrappers() as $wrapper) { - StringUtils::unregisterWrapper($wrapper); - } - foreach ($this->bufferedWrappers as $wrapper) { - StringUtils::registerWrapper($wrapper); - } - + StringUtils::resetRegisteredWrappers(); } public function getSingleByEncodings() From 2e6bd008637da6ce8a73114944ad1a0db2e6e0bf Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 6 Jan 2013 15:24:40 +0100 Subject: [PATCH 043/127] Global namespace not needed for constants --- src/StringWrapper/AbstractStringWrapper.php | 6 +++--- src/StringWrapper/StringWrapperInterface.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 8b19605ae..5fb8e85b5 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -232,7 +232,7 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false) * @param integer $padType * @return string */ - public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT) + public function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT) { if (StringUtils::isSingleByteEncoding($this->getEncoding())) { return str_pad($input, $padLength, $padString, $padType); @@ -250,7 +250,7 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD $repeatCount = floor($lengthOfPadding / $padStringLength); - if ($padType === \STR_PAD_BOTH) { + if ($padType === STR_PAD_BOTH) { $lastStringLeft = ''; $lastStringRight = ''; $repeatCountLeft = $repeatCountRight = ($repeatCount - $repeatCount % 2) / 2; @@ -269,7 +269,7 @@ public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength); - if ($padType === \STR_PAD_LEFT) { + if ($padType === STR_PAD_LEFT) { return str_repeat($padString, $repeatCount) . $lastString . $input; } diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index 888f9c3d6..bcba9ec48 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -115,5 +115,5 @@ public function wordWrap($str, $width = 75, $break = "\n", $cut = false); * @param integer $padType * @return string */ - public function strPad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT); + public function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT); } From e145bfab82b770743212c12e3d5d7954e528aef3 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 6 Jan 2013 15:31:14 +0100 Subject: [PATCH 044/127] File and class level docblocks --- src/Exception/ExtensionNotLoadedException.php | 15 +++++++++++++++ src/Exception/RuntimeException.php | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/Exception/ExtensionNotLoadedException.php b/src/Exception/ExtensionNotLoadedException.php index 40ceaf4ee..2270b5e00 100644 --- a/src/Exception/ExtensionNotLoadedException.php +++ b/src/Exception/ExtensionNotLoadedException.php @@ -1,7 +1,22 @@ Date: Sun, 6 Jan 2013 15:34:47 +0100 Subject: [PATCH 045/127] Removed not neccessary variable comversion as there is no strict comparison on it --- src/StringWrapper/AbstractStringWrapper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 5fb8e85b5..933482c73 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -163,7 +163,6 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false) } $width = (int) $width; - $cut = (bool) $cut; if ($width === 0 && $cut) { throw new Exception\InvalidArgumentException('Cannot force cut when width is zero'); } From 9e2e9319b8c0b7e02c8c9a41da5c41afdef64f32 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 6 Jan 2013 16:03:05 +0100 Subject: [PATCH 046/127] Added short describtions on tests using data providers --- .../StringWrapper/CommonStringWrapperTest.php | 120 ++++++++++++------ 1 file changed, 80 insertions(+), 40 deletions(-) diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php index 5ae04708a..cc58f9a70 100644 --- a/test/StringWrapper/CommonStringWrapperTest.php +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -138,77 +138,107 @@ public function wordWrapProvider() { return array( // Standard cut tests - array('utf-8', 'äbüöcß', 2, ' ', true, + array('Word wrap cut single-line', + 'utf-8', 'äbüöcß', 2, ' ', true, 'äb üö cß'), - array('utf-8', 'äbüöc ß äbüöcß', 2, ' ', true, + array('Word wrap cut multi-line', + 'utf-8', 'äbüöc ß äbüöcß', 2, ' ', true, 'äb üö c ß äb üö cß'), - array('utf-8', 'Ä very long wöööööööööööörd.', 8, "\n", true, + array('Word wrap cut multi-line short words', + 'utf-8', 'Ä very long wöööööööööööörd.', 8, "\n", true, "Ä very\nlong\nwööööööö\nööööörd."), - array('utf-8', "Ä very\nlong wöööööööööööörd.", 8, "\n", false, + array('Word wrap cut multi-line with previous new lines', + 'utf-8', "Ä very\nlong wöööööööööööörd.", 8, "\n", false, "Ä very\nlong\nwöööööööööööörd."), - array('utf-8', "Ä very
long wöö
öööööööö
öörd.", 8, '
', false, + array('Word wrap long break', + 'utf-8', "Ä very
long wöö
öööööööö
öörd.", 8, '
', false, "Ä very
long wöö
öööööööö
öörd."), // Alternative cut tests - array('utf-8', ' äüöäöü', 3, ' ', true, + array('Word wrap cut beginning single space', + 'utf-8', ' äüöäöü', 3, ' ', true, ' äüö äöü'), - array('utf-8', 'äüöäöü ', 3, ' ', true, + array('Word wrap cut ending single space', + 'utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - array('utf-8', 'äöüäöü ', 3, '-', true, + array('Word wrap cut ending single space with non space divider', + 'utf-8', 'äöüäöü ', 3, '-', true, 'äöü-äöü-'), - array('utf-8', 'äüöäöü ', 3, ' ', true, + array('Word wrap cut ending two spaces', + 'utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - array('utf-8', '12345 ', 5, '-', false, + array('Word wrap no cut ending single space', + 'utf-8', '12345 ', 5, '-', false, '12345-'), - array('utf-8', '12345 ', 5, '-', false, + array('Word wrap no cut ending two spaces', + 'utf-8', '12345 ', 5, '-', false, '12345- '), - array('utf-8', 'äüöäöü ', 3, ' ', true, + array('Word wrap cut ending three spaces', + 'utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - array('utf-8', 'äüöäöü--', 3, '-', true, + array('Word wrap cut ending two breaks', + 'utf-8', 'äüöäöü--', 3, '-', true, 'äüö-äöü--'), - array('utf-8', "äbü\töcß", 3, ' ', true, + array('Word wrap cut tab', + 'utf-8', "äbü\töcß", 3, ' ', true, "äbü \töc ß"), - array('utf-8', "äbü\nößt", 3, ' ', true, + array('Word wrap cut new-line with space', + 'utf-8', "äbü\nößt", 3, ' ', true, "äbü \nöß t"), - array('utf-8', "äbü\nößte", 3, "\n", true, + array('Word wrap cut new-line with new-line', + 'utf-8', "äbü\nößte", 3, "\n", true, "äbü\nößt\ne"), // Break cut tests - array('ascii', 'foobar-foofoofoo', 8, '-', true, + array('Word wrap cut break before', + 'ascii', 'foobar-foofoofoo', 8, '-', true, 'foobar-foofoofo-o'), - array('ascii', 'foobar-foobar', 6, '-', true, + array('Word wrap cut break with', + 'ascii', 'foobar-foobar', 6, '-', true, 'foobar-foobar'), - array('ascii', 'foobar-foobar', 7, '-', true, + array('Word wrap cut break within', + 'ascii', 'foobar-foobar', 7, '-', true, 'foobar-foobar'), - array('ascii', 'foobar-', 7, '-', true, + array('Word wrap cut break within end', + 'ascii', 'foobar-', 7, '-', true, 'foobar-'), - array('ascii', 'foobar-foobar', 5, '-', true, + array('Word wrap cut break after', + 'ascii', 'foobar-foobar', 5, '-', true, 'fooba-r-fooba-r'), // Standard no-cut tests - array('utf-8', 'äbüöcß', 2, ' ', false, + array('Word wrap no cut single-line', + 'utf-8', 'äbüöcß', 2, ' ', false, 'äbüöcß'), - array('utf-8', 'äbüöc ß äbüöcß', 2, "\n", false, + array('Word wrap no cut multi-line', + 'utf-8', 'äbüöc ß äbüöcß', 2, "\n", false, "äbüöc\nß\näbüöcß"), - array('utf-8', 'äöü äöü äöü', 5, "\n", false, + array('Word wrap no cut multi-word', + 'utf-8', 'äöü äöü äöü', 5, "\n", false, "äöü\näöü\näöü"), // Break no-cut tests - array('ascii', 'foobar-foofoofoo', 8, '-', false, + array('Word wrap no cut break before', + 'ascii', 'foobar-foofoofoo', 8, '-', false, 'foobar-foofoofoo'), - array('ascii', 'foobar-foobar', 6, '-', false, + array('Word wrap no cut break with', + 'ascii', 'foobar-foobar', 6, '-', false, 'foobar-foobar'), - array('ascii', 'foobar-foobar', 7, '-', false, + array('Word wrap no cut break within', + 'ascii', 'foobar-foobar', 7, '-', false, 'foobar-foobar'), - array('ascii', 'foobar-', 7, '-', false, + array('Word wrap no cut break within end', + 'ascii', 'foobar-', 7, '-', false, 'foobar-'), - array('ascii', 'foobar-foobar', 5, '-', false, + array('Word wrap no cut break after', + 'ascii', 'foobar-foobar', 5, '-', false, 'foobar-foobar'), ); } /** * @dataProvider wordWrapProvider + * @param string $shortDesc * @param string $encoding * @param string $str * @param integer $width @@ -216,7 +246,7 @@ public function wordWrapProvider() * @param boolean $cut * @param mixed $expected */ - public function testWordWrap($encoding, $string, $width, $break, $cut, $expected) + public function testWordWrap($shortDesc, $encoding, $string, $width, $break, $cut, $expected) { $wrapper = $this->getWrapper($encoding); if (!$wrapper) { @@ -245,24 +275,34 @@ public function strPadProvider() { return array( // single-byte - array('ascii', 'aaa', 5, 'o', STR_PAD_LEFT, 'ooaaa'), - array('ascii', 'aaa', 6, 'o', STR_PAD_BOTH, 'oaaaoo'), - array('ascii', 'aaa', 5, 'o', STR_PAD_RIGHT, 'aaaoo'), + array('Left padding - single byte', + 'ascii', 'aaa', 5, 'o', STR_PAD_LEFT, 'ooaaa'), + array('Center padding - single byte', + 'ascii', 'aaa', 6, 'o', STR_PAD_BOTH, 'oaaaoo'), + array('Right padding - single byte', + 'ascii', 'aaa', 5, 'o', STR_PAD_RIGHT, 'aaaoo'), // multi-byte - array('utf-8', 'äää', 5, 'ö', STR_PAD_LEFT, 'ööäää'), - array('utf-8', 'äää', 6, 'ö', STR_PAD_BOTH, 'öäääöö'), - array('utf-8', 'äää', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), + array('Left padding - multi-byte', + 'utf-8', 'äää', 5, 'ö', STR_PAD_LEFT, 'ööäää'), + array('Center padding - multi byte', + 'utf-8', 'äää', 6, 'ö', STR_PAD_BOTH, 'öäääöö'), + array('Right padding - multi-byte', + 'utf-8', 'äää', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), // ZF-12186 - array('utf-8', 'äääöö', 2, 'ö', STR_PAD_RIGHT, 'äääöö'), // PadInputLongerThanPadLength - array('utf-8', 'äääöö', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), // PadInputSameAsPadLength - array('utf-8', 'äääöö', -2, 'ö', STR_PAD_RIGHT, 'äääöö'), // PadNegativePadLength + array('Input longer than pad length', + 'utf-8', 'äääöö', 2, 'ö', STR_PAD_RIGHT, 'äääöö'), + array('Input same as pad length', + 'utf-8', 'äääöö', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), + array('Negative pad length', + 'utf-8', 'äääöö', -2, 'ö', STR_PAD_RIGHT, 'äääöö'), ); } /** * @dataProvider strPadProvider + * @param string $shortDesc * @param string $encoding * @param string $input * @param integer $padLength @@ -272,7 +312,7 @@ public function strPadProvider() * * @group ZF-12186 */ - public function testStrPad($encoding, $input, $padLength, $padString, $padType, $expected) + public function testStrPad($shortDesc, $encoding, $input, $padLength, $padString, $padType, $expected) { $wrapper = $this->getWrapper($encoding); if (!$wrapper) { From 8ee4281ed02a9555f6a37b44f7a4bfd4ae29332b Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 6 Jan 2013 18:22:32 +0100 Subject: [PATCH 047/127] added comment for a commented out block --- src/StringWrapper/Iconv.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index d81315790..118b5e082 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -153,15 +153,17 @@ class Iconv extends AbstractStringWrapper 'C99', 'JAVA', + /* Commented out because that's internal encodings not existing in real world // Full Unicode, in terms of uint16_t or uint32_t (with machine dependent endianness and alignment) - // 'UCS-2-INTERNAL', - // 'UCS-4-INTERNAL', + 'UCS-2-INTERNAL', + 'UCS-4-INTERNAL', // Locale dependent, in terms of `char' or `wchar_t' (with machine dependent endianness and alignment, // and with OS and locale dependent semantics) - // 'char', - // 'wchar_t', - // '', // The empty encoding name is equivalent to "char": it denotes the locale dependent character encoding. + 'char', + 'wchar_t', + '', // The empty encoding name is equivalent to "char": it denotes the locale dependent character encoding. + */ // When configured with the option --enable-extra-encodings, // it also provides support for a few extra encodings: From 54016c4292f43b7fbbf39c4aefbf7eb97efe3da4 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sun, 6 Jan 2013 20:44:51 +0100 Subject: [PATCH 048/127] Use array keys as description for data provider --- .../StringWrapper/CommonStringWrapperTest.php | 190 ++++++++---------- 1 file changed, 81 insertions(+), 109 deletions(-) diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php index cc58f9a70..454809b33 100644 --- a/test/StringWrapper/CommonStringWrapperTest.php +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -138,107 +138,80 @@ public function wordWrapProvider() { return array( // Standard cut tests - array('Word wrap cut single-line', - 'utf-8', 'äbüöcß', 2, ' ', true, - 'äb üö cß'), - array('Word wrap cut multi-line', - 'utf-8', 'äbüöc ß äbüöcß', 2, ' ', true, - 'äb üö c ß äb üö cß'), - array('Word wrap cut multi-line short words', - 'utf-8', 'Ä very long wöööööööööööörd.', 8, "\n", true, - "Ä very\nlong\nwööööööö\nööööörd."), - array('Word wrap cut multi-line with previous new lines', - 'utf-8', "Ä very\nlong wöööööööööööörd.", 8, "\n", false, - "Ä very\nlong\nwöööööööööööörd."), - array('Word wrap long break', - 'utf-8', "Ä very
long wöö
öööööööö
öörd.", 8, '
', false, - "Ä very
long wöö
öööööööö
öörd."), + 'word-wrap-cut-single-line' => + array('utf-8', 'äbüöcß', 2, ' ', true, 'äb üö cß'), + 'word-wrap-cut-multi-line' => + array('utf-8', 'äbüöc ß äbüöcß', 2, ' ', true, 'äb üö c ß äb üö cß'), + 'word-wrap-cut-multi-line-short-words' => + array('utf-8', 'Ä very long wöööööööööööörd.', 8, "\n", true, + "Ä very\nlong\nwööööööö\nööööörd."), + 'word-wrap-cut-multi-line-with-previous-new-lines' => + array('utf-8', "Ä very\nlong wöööööööööööörd.", 8, "\n", false, + "Ä very\nlong\nwöööööööööööörd."), + 'word-wrap-long-break' => + array('utf-8', "Ä very
long wöö
öööööööö
öörd.", 8, '
', false, + "Ä very
long wöö
öööööööö
öörd."), // Alternative cut tests - array('Word wrap cut beginning single space', - 'utf-8', ' äüöäöü', 3, ' ', true, - ' äüö äöü'), - array('Word wrap cut ending single space', - 'utf-8', 'äüöäöü ', 3, ' ', true, - 'äüö äöü '), - array('Word wrap cut ending single space with non space divider', - 'utf-8', 'äöüäöü ', 3, '-', true, - 'äöü-äöü-'), - array('Word wrap cut ending two spaces', - 'utf-8', 'äüöäöü ', 3, ' ', true, - 'äüö äöü '), - array('Word wrap no cut ending single space', - 'utf-8', '12345 ', 5, '-', false, - '12345-'), - array('Word wrap no cut ending two spaces', - 'utf-8', '12345 ', 5, '-', false, - '12345- '), - array('Word wrap cut ending three spaces', - 'utf-8', 'äüöäöü ', 3, ' ', true, - 'äüö äöü '), - array('Word wrap cut ending two breaks', - 'utf-8', 'äüöäöü--', 3, '-', true, - 'äüö-äöü--'), - array('Word wrap cut tab', - 'utf-8', "äbü\töcß", 3, ' ', true, - "äbü \töc ß"), - array('Word wrap cut new-line with space', - 'utf-8', "äbü\nößt", 3, ' ', true, - "äbü \nöß t"), - array('Word wrap cut new-line with new-line', - 'utf-8', "äbü\nößte", 3, "\n", true, - "äbü\nößt\ne"), + 'word-wrap-cut-beginning-single-space' => + array('utf-8', ' äüöäöü', 3, ' ', true, ' äüö äöü'), + 'word-wrap-cut-ending-single-space' => + array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), + 'word-wrap-cut-ending-single-space-with-non-space-divider' => + array('utf-8', 'äöüäöü ', 3, '-', true, 'äöü-äöü-'), + 'word-wrap-cut-ending-two-spaces' => + array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), + 'word-wrap-no-cut-ending-single-space' => + array('utf-8', '12345 ', 5, '-', false, '12345-'), + 'word-wrap-no-cut-ending-two-spaces' => + array('utf-8', '12345 ', 5, '-', false, '12345- '), + 'word-wrap-cut-ending-three-spaces' => + array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), + 'word-wrap-cut-ending-two-breaks' => + array('utf-8', 'äüöäöü--', 3, '-', true, 'äüö-äöü--'), + 'word-wrap-cut-tab' => + array('utf-8', "äbü\töcß", 3, ' ', true, "äbü \töc ß"), + 'word-wrap-cut-new-line-with-space' => + array('utf-8', "äbü\nößt", 3, ' ', true, "äbü \nöß t"), + 'word-wrap-cut-new-line-with-new-line' => + array('utf-8', "äbü\nößte", 3, "\n", true, "äbü\nößt\ne"), // Break cut tests - array('Word wrap cut break before', - 'ascii', 'foobar-foofoofoo', 8, '-', true, - 'foobar-foofoofo-o'), - array('Word wrap cut break with', - 'ascii', 'foobar-foobar', 6, '-', true, - 'foobar-foobar'), - array('Word wrap cut break within', - 'ascii', 'foobar-foobar', 7, '-', true, - 'foobar-foobar'), - array('Word wrap cut break within end', - 'ascii', 'foobar-', 7, '-', true, - 'foobar-'), - array('Word wrap cut break after', - 'ascii', 'foobar-foobar', 5, '-', true, - 'fooba-r-fooba-r'), + 'word-wrap-cut-break-before' => + array('ascii', 'foobar-foofoofoo', 8, '-', true, 'foobar-foofoofo-o'), + 'word-wrap-cut-break-with' => + array('ascii', 'foobar-foobar', 6, '-', true, 'foobar-foobar'), + 'word-wrap-cut-break-within' => + array('ascii', 'foobar-foobar', 7, '-', true, 'foobar-foobar'), + 'word-wrap-cut-break-within-end' => + array('ascii', 'foobar-', 7, '-', true, 'foobar-'), + 'word-wrap-cut-break-after' => + array('ascii', 'foobar-foobar', 5, '-', true, 'fooba-r-fooba-r'), // Standard no-cut tests - array('Word wrap no cut single-line', - 'utf-8', 'äbüöcß', 2, ' ', false, - 'äbüöcß'), - array('Word wrap no cut multi-line', - 'utf-8', 'äbüöc ß äbüöcß', 2, "\n", false, - "äbüöc\nß\näbüöcß"), - array('Word wrap no cut multi-word', - 'utf-8', 'äöü äöü äöü', 5, "\n", false, - "äöü\näöü\näöü"), + 'word-wrap-no-cut-single-line' => + array('utf-8', 'äbüöcß', 2, ' ', false, 'äbüöcß'), + 'word-wrap-no-cut-multi-line' => + array('utf-8', 'äbüöc ß äbüöcß', 2, "\n", false, "äbüöc\nß\näbüöcß"), + 'word-wrap-no-cut-multi-word' => + array('utf-8', 'äöü äöü äöü', 5, "\n", false, "äöü\näöü\näöü"), // Break no-cut tests - array('Word wrap no cut break before', - 'ascii', 'foobar-foofoofoo', 8, '-', false, - 'foobar-foofoofoo'), - array('Word wrap no cut break with', - 'ascii', 'foobar-foobar', 6, '-', false, - 'foobar-foobar'), - array('Word wrap no cut break within', - 'ascii', 'foobar-foobar', 7, '-', false, - 'foobar-foobar'), - array('Word wrap no cut break within end', - 'ascii', 'foobar-', 7, '-', false, - 'foobar-'), - array('Word wrap no cut break after', - 'ascii', 'foobar-foobar', 5, '-', false, - 'foobar-foobar'), + 'word-wrap-no-cut-break-before' => + array('ascii', 'foobar-foofoofoo', 8, '-', false, 'foobar-foofoofoo'), + 'word-wrap-no-cut-break-with' => + array('ascii', 'foobar-foobar', 6, '-', false, 'foobar-foobar'), + 'word-wrap-no-cut-break-within' => + array('ascii', 'foobar-foobar', 7, '-', false, 'foobar-foobar'), + 'word-wrap-no-cut-break-within-end' => + array('ascii', 'foobar-', 7, '-', false, 'foobar-'), + 'word-wrap-no-cut-break-after' => + array('ascii', 'foobar-foobar', 5, '-', false, 'foobar-foobar'), ); } /** * @dataProvider wordWrapProvider - * @param string $shortDesc * @param string $encoding * @param string $str * @param integer $width @@ -246,7 +219,7 @@ public function wordWrapProvider() * @param boolean $cut * @param mixed $expected */ - public function testWordWrap($shortDesc, $encoding, $string, $width, $break, $cut, $expected) + public function testWordWrap($encoding, $string, $width, $break, $cut, $expected) { $wrapper = $this->getWrapper($encoding); if (!$wrapper) { @@ -275,34 +248,33 @@ public function strPadProvider() { return array( // single-byte - array('Left padding - single byte', - 'ascii', 'aaa', 5, 'o', STR_PAD_LEFT, 'ooaaa'), - array('Center padding - single byte', - 'ascii', 'aaa', 6, 'o', STR_PAD_BOTH, 'oaaaoo'), - array('Right padding - single byte', - 'ascii', 'aaa', 5, 'o', STR_PAD_RIGHT, 'aaaoo'), + 'left-padding_single-byte' => + array('ascii', 'aaa', 5, 'o', STR_PAD_LEFT, 'ooaaa'), + 'center-padding_single-byte' => + array('ascii', 'aaa', 6, 'o', STR_PAD_BOTH, 'oaaaoo'), + 'right-padding_single-byte' => + array('ascii', 'aaa', 5, 'o', STR_PAD_RIGHT, 'aaaoo'), // multi-byte - array('Left padding - multi-byte', - 'utf-8', 'äää', 5, 'ö', STR_PAD_LEFT, 'ööäää'), - array('Center padding - multi byte', - 'utf-8', 'äää', 6, 'ö', STR_PAD_BOTH, 'öäääöö'), - array('Right padding - multi-byte', - 'utf-8', 'äää', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), + 'left-padding_multi-byte' => + array('utf-8', 'äää', 5, 'ö', STR_PAD_LEFT, 'ööäää'), + 'center-padding_multi-byte' => + array('utf-8', 'äää', 6, 'ö', STR_PAD_BOTH, 'öäääöö'), + 'right-padding_multi-byte' => + array('utf-8', 'äää', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), // ZF-12186 - array('Input longer than pad length', - 'utf-8', 'äääöö', 2, 'ö', STR_PAD_RIGHT, 'äääöö'), - array('Input same as pad length', - 'utf-8', 'äääöö', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), - array('Negative pad length', - 'utf-8', 'äääöö', -2, 'ö', STR_PAD_RIGHT, 'äääöö'), + 'input-longer-than-pad-length' => + array('utf-8', 'äääöö', 2, 'ö', STR_PAD_RIGHT, 'äääöö'), + 'input-same-as-pad-length' => + array('utf-8', 'äääöö', 5, 'ö', STR_PAD_RIGHT, 'äääöö'), + 'negative-pad-length' => + array('utf-8', 'äääöö', -2, 'ö', STR_PAD_RIGHT, 'äääöö'), ); } /** * @dataProvider strPadProvider - * @param string $shortDesc * @param string $encoding * @param string $input * @param integer $padLength @@ -312,7 +284,7 @@ public function strPadProvider() * * @group ZF-12186 */ - public function testStrPad($shortDesc, $encoding, $input, $padLength, $padString, $padType, $expected) + public function testStrPad($encoding, $input, $padLength, $padString, $padType, $expected) { $wrapper = $this->getWrapper($encoding); if (!$wrapper) { From 874aec176dc49e288664fd4d578d6a371ef53d2a Mon Sep 17 00:00:00 2001 From: ingo Date: Mon, 7 Jan 2013 00:59:43 +0100 Subject: [PATCH 049/127] Unit tests and error handling --- src/Hydrator/ClassMethods.php | 2 - src/Hydrator/Filter/FilterComposite.php | 41 ++++++++++- test/TestAsset/FilterCompositeTest.php | 90 +++++++++++++++++++------ 3 files changed, 110 insertions(+), 23 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 003424512..bff9f3fe7 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -78,7 +78,6 @@ public function setOptions($options) public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys) { $this->underscoreSeparatedKeys = $underscoreSeparatedKeys; - return $this; } @@ -88,7 +87,6 @@ public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys) public function getUnderscoreSeparatedKeys() { return $this->underscoreSeparatedKeys; - } /** diff --git a/src/Hydrator/Filter/FilterComposite.php b/src/Hydrator/Filter/FilterComposite.php index 87f3efcf1..e21e8af06 100644 --- a/src/Hydrator/Filter/FilterComposite.php +++ b/src/Hydrator/Filter/FilterComposite.php @@ -9,6 +9,8 @@ */ namespace Zend\Stdlib\Hydrator\Filter; +use Zend\Stdlib\Exception\InvalidArgumentException; + /** * @category Zend * @package Zend_Stdlib @@ -36,9 +38,39 @@ class FilterComposite implements FilterInterface /** * Define default Filter + * + * @throws InvalidArgumentException */ public function __construct($orFilter = array(), $andFilter = array()) { + array_walk($orFilter, + function($value, $key) { + if( + !is_callable($value) && + !$value instanceof FilterInterface + ) { + throw new InvalidArgumentException( + 'The value of ' . $key . ' should be either a callable or ' . + 'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface' + ); + } + } + ); + + array_walk($andFilter, + function($value, $key) { + if( + !is_callable($value) && + !$value instanceof FilterInterface + ) { + throw new InvalidArgumentException( + 'The value of ' . $key . ' should be either a callable or ' . + 'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface' + ); + } + } + ); + $this->orFilter = new \ArrayObject($orFilter); $this->andFilter = new \ArrayObject($andFilter); } @@ -62,6 +94,7 @@ public function __construct($orFilter = array(), $andFilter = array()) * @param string $name * @param callable|FilterInterface $filter * @param int $condition Can be either FilterComposite::CONDITION_OR or FilterComposite::CONDITION_AND + * @throws InvalidArgumentException */ public function addFilter($name, $filter, $condition = self::CONDITION_OR) { @@ -71,10 +104,14 @@ public function addFilter($name, $filter, $condition = self::CONDITION_OR) ) { if ($condition === self::CONDITION_OR) { $this->orFilter[$name] = $filter; - } - if ($condition === self::CONDITION_AND) { + } elseif ($condition === self::CONDITION_AND) { $this->andFilter[$name] = $filter; } + } else { + throw new InvalidArgumentException( + 'The value of ' . $name . ' should be either a callable or ' . + 'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface' + ); } } diff --git a/test/TestAsset/FilterCompositeTest.php b/test/TestAsset/FilterCompositeTest.php index 9eaa21e5e..6efbbfaa7 100644 --- a/test/TestAsset/FilterCompositeTest.php +++ b/test/TestAsset/FilterCompositeTest.php @@ -12,56 +12,56 @@ use Zend\Stdlib\Hydrator\Filter\FilterComposite; -class ValidationCompositeTest extends \PHPUnit_Framework_TestCase +class FilterCompositeTest extends \PHPUnit_Framework_TestCase { - protected $validatorComposite; + protected $filterComposite; public function setUp() { - $this->validatorComposite = new FilterComposite(); + $this->filterComposite = new FilterComposite(); } public function testValidationAdd() { - $this->assertTrue($this->validatorComposite->filter("foo")); - $this->validatorComposite->addFilter("has", + $this->assertTrue($this->filterComposite->filter("foo")); + $this->filterComposite->addFilter("has", function($property) { return false; } ); - $this->assertFalse($this->validatorComposite->filter("foo")); + $this->assertFalse($this->filterComposite->filter("foo")); } public function testValidationRemove() { - $this->validatorComposite->addFilter("has", + $this->filterComposite->addFilter("has", function($property) { return false; } ); - $this->assertFalse($this->validatorComposite->filter("foo")); - $this->validatorComposite->removeFilter("has"); - $this->assertTrue($this->validatorComposite->filter("foo")); + $this->assertFalse($this->filterComposite->filter("foo")); + $this->filterComposite->removeFilter("has"); + $this->assertTrue($this->filterComposite->filter("foo")); } public function testValidationHas() { - $this->validatorComposite->addFilter("has", + $this->filterComposite->addFilter("has", function($property) { return false; } ); - $this->assertFalse($this->validatorComposite->filter("foo")); - $this->assertTrue($this->validatorComposite->hasFilter("has")); + $this->assertFalse($this->filterComposite->filter("foo")); + $this->assertTrue($this->filterComposite->hasFilter("has")); } public function testComplexValidation() { - $this->validatorComposite->addFilter("has", new \Zend\Stdlib\Hydrator\Filter\HasFilter()); - $this->validatorComposite->addFilter("get", new \Zend\Stdlib\Hydrator\Filter\GetFilter()); - $this->validatorComposite->addFilter("is", new \Zend\Stdlib\Hydrator\Filter\IsFilter()); + $this->filterComposite->addFilter("has", new \Zend\Stdlib\Hydrator\Filter\HasFilter()); + $this->filterComposite->addFilter("get", new \Zend\Stdlib\Hydrator\Filter\GetFilter()); + $this->filterComposite->addFilter("is", new \Zend\Stdlib\Hydrator\Filter\IsFilter()); - $this->validatorComposite->addFilter("exclude", + $this->filterComposite->addFilter("exclude", function($property) { $method = substr($property, strpos($property, '::')); @@ -73,7 +73,59 @@ function($property) { }, FilterComposite::CONDITION_AND ); - $this->assertTrue($this->validatorComposite->filter('getFooBar')); - $this->assertFalse($this->validatorComposite->filter('getServiceLocator')); + $this->assertTrue($this->filterComposite->filter('getFooBar')); + $this->assertFalse($this->filterComposite->filter('getServiceLocator')); + } + + public function testConstructorInjection() + { + $andCondition = array( + 'servicelocator' => function($property) { + if($property === 'getServiceLocator') { + return false; + } + return true; + }, + 'foobar' => function($property) { + if($property === 'getFooBar') { + return false; + } + return true; + } + ); + $orCondition = array( + 'has' => new \Zend\Stdlib\Hydrator\Filter\HasFilter(), + 'get' => new \Zend\Stdlib\Hydrator\Filter\GetFilter() + ); + $filterComposite = new FilterComposite($orCondition, $andCondition); + + $this->assertFalse($filterComposite->filter('getFooBar')); + $this->assertFalse($filterComposite->filter('geTFooBar')); + $this->assertFalse($filterComposite->filter('getServiceLocator')); + $this->assertTrue($filterComposite->filter('getFoo')); + $this->assertTrue($filterComposite->filter('hasFoo')); + } + + /** + * @expectedException Zend\Stdlib\Exception\InvalidArgumentException + * @expectedExceptionMessage The value of test should be either a callable + * or an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface + */ + public function testInvalidParameterConstructorInjection() + { + $andCondition = array('foo' => 'bar'); + $orCondition = array('test' => 'blubb'); + + new FilterComposite($orCondition, $andCondition); + } + + /** + * @expectedException Zend\Stdlib\Exception\InvalidArgumentException + * @expectedExceptionMessage The value of foo should be either a callable + * or an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface + */ + public function testInvalidFilterInjection() + { + $this->filterComposite->addFilter('foo', 'bar'); } } From b3909fb68e45275d418db422f7a9d3faadac1d60 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Mon, 7 Jan 2013 20:28:07 +0100 Subject: [PATCH 050/127] Make sure StringWrapper::convert don't substring return value on invalid character + test --- src/StringWrapper/Iconv.php | 5 ++++- test/StringWrapper/CommonStringWrapperTest.php | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/StringWrapper/Iconv.php b/src/StringWrapper/Iconv.php index 118b5e082..0cc8464eb 100644 --- a/src/StringWrapper/Iconv.php +++ b/src/StringWrapper/Iconv.php @@ -290,6 +290,9 @@ public function convert($str, $reverse = false) $fromEncoding = $reverse ? $convertEncoding : $encoding; $toEncoding = $reverse ? $encoding : $convertEncoding; - return iconv($fromEncoding, $toEncoding, $str); + + // automatically add "//IGNORE" to not stop converting on invalid characters + // invalid characters triggers a notice anyway + return iconv($fromEncoding, $toEncoding . '//IGNORE', $str); } } diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php index 454809b33..8fe180ba3 100644 --- a/test/StringWrapper/CommonStringWrapperTest.php +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -12,6 +12,7 @@ namespace ZendTest\Stdlib\StringWrapper; use PHPUnit_Framework_TestCase as TestCase; +use Zend\Stdlib\ErrorHandler; use Zend\Stdlib\Exception; use Zend\Stdlib\StringWrapper\StringWrapperInterface; @@ -134,6 +135,22 @@ public function testConvert($encoding, $convertEncoding, $str, $expected) $this->assertSame($str, $result); } + public function testConvertDontSubstringsOnInvalidCharacter() + { + $wrapper = $this->getWrapper('UTF-8', 'ASCII'); + if (!$wrapper) { + $this->markTestSkipped("Converting UTF-8 to ASCII not supported"); + } + + // NOTE: This call could trigger a notice/warning/error + // but that isn't part of this test + ErrorHandler::start(E_NOTICE); + $result = $wrapper->convert($wrapper->convert("foo \xDEx bar"), true); + ErrorHandler::stop(); + + $this->assertSame("foo x bar", $result); + } + public function wordWrapProvider() { return array( From 7392f83af171070f33393b74206724b7a33aa535 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Mon, 7 Jan 2013 20:29:56 +0100 Subject: [PATCH 051/127] removed unneccissary 'word-wrap-' prefix --- .../StringWrapper/CommonStringWrapperTest.php | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/test/StringWrapper/CommonStringWrapperTest.php b/test/StringWrapper/CommonStringWrapperTest.php index 8fe180ba3..3640431d8 100644 --- a/test/StringWrapper/CommonStringWrapperTest.php +++ b/test/StringWrapper/CommonStringWrapperTest.php @@ -155,74 +155,74 @@ public function wordWrapProvider() { return array( // Standard cut tests - 'word-wrap-cut-single-line' => + 'cut-single-line' => array('utf-8', 'äbüöcß', 2, ' ', true, 'äb üö cß'), - 'word-wrap-cut-multi-line' => + 'cut-multi-line' => array('utf-8', 'äbüöc ß äbüöcß', 2, ' ', true, 'äb üö c ß äb üö cß'), - 'word-wrap-cut-multi-line-short-words' => + 'cut-multi-line-short-words' => array('utf-8', 'Ä very long wöööööööööööörd.', 8, "\n", true, "Ä very\nlong\nwööööööö\nööööörd."), - 'word-wrap-cut-multi-line-with-previous-new-lines' => + 'cut-multi-line-with-previous-new-lines' => array('utf-8', "Ä very\nlong wöööööööööööörd.", 8, "\n", false, "Ä very\nlong\nwöööööööööööörd."), - 'word-wrap-long-break' => + 'long-break' => array('utf-8', "Ä very
long wöö
öööööööö
öörd.", 8, '
', false, "Ä very
long wöö
öööööööö
öörd."), // Alternative cut tests - 'word-wrap-cut-beginning-single-space' => + 'cut-beginning-single-space' => array('utf-8', ' äüöäöü', 3, ' ', true, ' äüö äöü'), - 'word-wrap-cut-ending-single-space' => + 'cut-ending-single-space' => array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - 'word-wrap-cut-ending-single-space-with-non-space-divider' => + 'cut-ending-single-space-with-non-space-divider' => array('utf-8', 'äöüäöü ', 3, '-', true, 'äöü-äöü-'), - 'word-wrap-cut-ending-two-spaces' => + 'cut-ending-two-spaces' => array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - 'word-wrap-no-cut-ending-single-space' => + 'no-cut-ending-single-space' => array('utf-8', '12345 ', 5, '-', false, '12345-'), - 'word-wrap-no-cut-ending-two-spaces' => + 'no-cut-ending-two-spaces' => array('utf-8', '12345 ', 5, '-', false, '12345- '), - 'word-wrap-cut-ending-three-spaces' => + 'cut-ending-three-spaces' => array('utf-8', 'äüöäöü ', 3, ' ', true, 'äüö äöü '), - 'word-wrap-cut-ending-two-breaks' => + 'cut-ending-two-breaks' => array('utf-8', 'äüöäöü--', 3, '-', true, 'äüö-äöü--'), - 'word-wrap-cut-tab' => + 'cut-tab' => array('utf-8', "äbü\töcß", 3, ' ', true, "äbü \töc ß"), - 'word-wrap-cut-new-line-with-space' => + 'cut-new-line-with-space' => array('utf-8', "äbü\nößt", 3, ' ', true, "äbü \nöß t"), - 'word-wrap-cut-new-line-with-new-line' => + 'cut-new-line-with-new-line' => array('utf-8', "äbü\nößte", 3, "\n", true, "äbü\nößt\ne"), // Break cut tests - 'word-wrap-cut-break-before' => + 'cut-break-before' => array('ascii', 'foobar-foofoofoo', 8, '-', true, 'foobar-foofoofo-o'), - 'word-wrap-cut-break-with' => + 'cut-break-with' => array('ascii', 'foobar-foobar', 6, '-', true, 'foobar-foobar'), - 'word-wrap-cut-break-within' => + 'cut-break-within' => array('ascii', 'foobar-foobar', 7, '-', true, 'foobar-foobar'), - 'word-wrap-cut-break-within-end' => + 'cut-break-within-end' => array('ascii', 'foobar-', 7, '-', true, 'foobar-'), - 'word-wrap-cut-break-after' => + 'cut-break-after' => array('ascii', 'foobar-foobar', 5, '-', true, 'fooba-r-fooba-r'), // Standard no-cut tests - 'word-wrap-no-cut-single-line' => + 'no-cut-single-line' => array('utf-8', 'äbüöcß', 2, ' ', false, 'äbüöcß'), - 'word-wrap-no-cut-multi-line' => + 'no-cut-multi-line' => array('utf-8', 'äbüöc ß äbüöcß', 2, "\n", false, "äbüöc\nß\näbüöcß"), - 'word-wrap-no-cut-multi-word' => + 'no-cut-multi-word' => array('utf-8', 'äöü äöü äöü', 5, "\n", false, "äöü\näöü\näöü"), // Break no-cut tests - 'word-wrap-no-cut-break-before' => + 'no-cut-break-before' => array('ascii', 'foobar-foofoofoo', 8, '-', false, 'foobar-foofoofoo'), - 'word-wrap-no-cut-break-with' => + 'no-cut-break-with' => array('ascii', 'foobar-foobar', 6, '-', false, 'foobar-foobar'), - 'word-wrap-no-cut-break-within' => + 'no-cut-break-within' => array('ascii', 'foobar-foobar', 7, '-', false, 'foobar-foobar'), - 'word-wrap-no-cut-break-within-end' => + 'no-cut-break-within-end' => array('ascii', 'foobar-', 7, '-', false, 'foobar-'), - 'word-wrap-no-cut-break-after' => + 'no-cut-break-after' => array('ascii', 'foobar-foobar', 5, '-', false, 'foobar-foobar'), ); } From 85dd79a63ff5bf36a3400965c390104e2b9c0cd9 Mon Sep 17 00:00:00 2001 From: ingo Date: Tue, 8 Jan 2013 00:38:56 +0100 Subject: [PATCH 052/127] Fixed reviews --- src/Hydrator/ClassMethods.php | 10 +++--- src/Hydrator/Filter/FilterComposite.php | 47 ++++++++++++++----------- test/HydratorTest.php | 2 +- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index bff9f3fe7..54d3be736 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -10,11 +10,11 @@ namespace Zend\Stdlib\Hydrator; -use Zend\Stdlib\Exception, - Zend\Stdlib\Hydrator\Filter\FilterComposite, - Zend\Stdlib\Hydrator\Filter\IsFilter, - Zend\Stdlib\Hydrator\Filter\GetFilter, - Zend\Stdlib\Hydrator\Filter\HasFilter; +use Zend\Stdlib\Exception; +use Zend\Stdlib\Hydrator\Filter\FilterComposite; +use Zend\Stdlib\Hydrator\Filter\GetFilter; +use Zend\Stdlib\Hydrator\Filter\HasFilter; +use Zend\Stdlib\Hydrator\Filter\IsFilter; /** * @category Zend diff --git a/src/Hydrator/Filter/FilterComposite.php b/src/Hydrator/Filter/FilterComposite.php index e21e8af06..03767936b 100644 --- a/src/Hydrator/Filter/FilterComposite.php +++ b/src/Hydrator/Filter/FilterComposite.php @@ -9,6 +9,7 @@ */ namespace Zend\Stdlib\Hydrator\Filter; +use ArrayObject; use Zend\Stdlib\Exception\InvalidArgumentException; /** @@ -19,11 +20,12 @@ class FilterComposite implements FilterInterface { /** - * @var \ArrayObject + * @var ArrayObject */ protected $orFilter; + /** - * @var \ArrayObject + * @var ArrayObject */ protected $andFilter; @@ -31,6 +33,7 @@ class FilterComposite implements FilterInterface * Constant to add with "or" conditition */ const CONDITION_OR = 1; + /** * Constant to add with "and" conditition */ @@ -46,8 +49,8 @@ public function __construct($orFilter = array(), $andFilter = array()) array_walk($orFilter, function($value, $key) { if( - !is_callable($value) && - !$value instanceof FilterInterface + !is_callable($value) + && !$value instanceof FilterInterface ) { throw new InvalidArgumentException( 'The value of ' . $key . ' should be either a callable or ' . @@ -60,8 +63,8 @@ function($value, $key) { array_walk($andFilter, function($value, $key) { if( - !is_callable($value) && - !$value instanceof FilterInterface + !is_callable($value) + && !$value instanceof FilterInterface ) { throw new InvalidArgumentException( 'The value of ' . $key . ' should be either a callable or ' . @@ -71,8 +74,8 @@ function($value, $key) { } ); - $this->orFilter = new \ArrayObject($orFilter); - $this->andFilter = new \ArrayObject($andFilter); + $this->orFilter = new ArrayObject($orFilter); + $this->andFilter = new ArrayObject($andFilter); } /** @@ -95,30 +98,31 @@ function($value, $key) { * @param callable|FilterInterface $filter * @param int $condition Can be either FilterComposite::CONDITION_OR or FilterComposite::CONDITION_AND * @throws InvalidArgumentException + * @return FilterComposite */ public function addFilter($name, $filter, $condition = self::CONDITION_OR) { - if ( - is_callable($filter) || - $filter instanceof FilterInterface - ) { - if ($condition === self::CONDITION_OR) { - $this->orFilter[$name] = $filter; - } elseif ($condition === self::CONDITION_AND) { - $this->andFilter[$name] = $filter; - } - } else { + if ( !is_callable($filter) && !($filter instanceof FilterInterface) ) { throw new InvalidArgumentException( 'The value of ' . $name . ' should be either a callable or ' . 'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface' ); } + + if ($condition === self::CONDITION_OR) { + $this->orFilter[$name] = $filter; + } elseif ($condition === self::CONDITION_AND) { + $this->andFilter[$name] = $filter; + } + + return $this; } /** * Remove a filter from the composition * * @param $name string Identifier for the filter + * @return FilterComposite */ public function removeFilter($name) { @@ -129,6 +133,8 @@ public function removeFilter($name) if( isset($this->andFilter[$name])) { unset($this->andFilter[$name]); } + + return $this; } /** @@ -139,8 +145,7 @@ public function removeFilter($name) */ public function hasFilter($name) { - return - isset($this->orFilter[$name]) || isset($this->andFilter[$name]); + return isset($this->orFilter[$name]) || isset($this->andFilter[$name]); } /** @@ -170,6 +175,7 @@ public function filter($property) $returnValue = true; break; } + continue; } else { if ( $filter->filter($property) === true) { $returnValue = true; @@ -184,6 +190,7 @@ public function filter($property) if( $filter($property) === false) { return false; } + continue; } else { if( $filter->filter($property) === false) { return false; diff --git a/test/HydratorTest.php b/test/HydratorTest.php index d16193ef0..4f178daf2 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -274,7 +274,7 @@ public function testHydratorClassMethodsManipulateFilter() $this->assertFalse(isset($datas['hasBar'])); //method is hasBar } - public function testHydratorClassMethodsWithCostumFilter() + public function testHydratorClassMethodsWithCustomFilter() { $hydrator = new ClassMethods(false); $datas = $hydrator->extract($this->classMethodsCamelCase); From 02528a748582445a594aaac0fc5ae3fcc40b0d65 Mon Sep 17 00:00:00 2001 From: ingo Date: Tue, 8 Jan 2013 01:11:17 +0100 Subject: [PATCH 053/127] Moved filter implementation to abstract hydrator --- src/Hydrator/AbstractHydrator.php | 61 +++++++++++++++++++++++++++++++ src/Hydrator/ClassMethods.php | 58 ----------------------------- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/src/Hydrator/AbstractHydrator.php b/src/Hydrator/AbstractHydrator.php index 056ade4b0..5d5dd56a4 100644 --- a/src/Hydrator/AbstractHydrator.php +++ b/src/Hydrator/AbstractHydrator.php @@ -12,6 +12,7 @@ use ArrayObject; use Zend\Stdlib\Exception; +use Zend\Stdlib\Hydrator\Filter\FilterComposite; use Zend\Stdlib\Hydrator\StrategyEnabledInterface; use Zend\Stdlib\Hydrator\Strategy\StrategyInterface; @@ -29,12 +30,19 @@ abstract class AbstractHydrator implements HydratorInterface, StrategyEnabledInt */ protected $strategies; + /** + * Composite to filter the methods, that need to be hydrated + * @var Filter\FilterComposite + */ + protected $filterComposite; + /** * Initializes a new instance of this class. */ public function __construct() { $this->strategies = new ArrayObject(); + $this->filterComposite = new FilterComposite(); } /** @@ -128,4 +136,57 @@ public function hydrateValue($name, $value) } return $value; } + + /** + * Add a new filter to take care of what needs to be hydrated. + * To exclude e.g. the method getServiceLocator: + * + * + * $composite->addFilter("servicelocator", + * function($property) { + * list($class, $method) = explode('::', $property); + * if ($method === 'getServiceLocator') { + * return false; + * } + * return true; + * }, FilterComposite::CONDITION_AND + * ); + * + * + * @param string $name Index in the composite + * @param callable|Zend\Stdlib\Hydrator\Filter\FilterInterface $filter + * @param int $condition + * @return Filter\FilterComposite + */ + public function addFilter($name, $filter, $condition = FilterComposite::CONDITION_OR) + { + return $this->filterComposite->addFilter($name, $filter, $condition); + } + + /** + * Check whether a specific filter exists at key $name or not + * + * @param string $name Index in the composite + * @return bool + */ + public function hasFilter($name) + { + return $this->filterComposite->hasFilter($name); + } + + /** + * Remove a filter from the composition. + * To not extract "has" methods, you simply need to unregister it + * + * + * $filterComposite->removeFilter('has'); + * + * + * @param $name + * @return Filter\FilterComposite + */ + public function removeFilter($name) + { + return $this->filterComposite->removeFilter($name); + } } diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 54d3be736..4cb37c4e4 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -11,7 +11,6 @@ namespace Zend\Stdlib\Hydrator; use Zend\Stdlib\Exception; -use Zend\Stdlib\Hydrator\Filter\FilterComposite; use Zend\Stdlib\Hydrator\Filter\GetFilter; use Zend\Stdlib\Hydrator\Filter\HasFilter; use Zend\Stdlib\Hydrator\Filter\IsFilter; @@ -29,12 +28,6 @@ class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface */ protected $underscoreSeparatedKeys = true; - /** - * Composite to filter the methods, that need to be hydrated - * @var Filter\FilterComposite - */ - protected $filterComposite; - /** * Define if extract values will use camel case or name with underscore * @param boolean|array $underscoreSeparatedKeys @@ -44,7 +37,6 @@ public function __construct($underscoreSeparatedKeys = true) parent::__construct(); $this->setUnderscoreSeparatedKeys($underscoreSeparatedKeys); - $this->filterComposite = new FilterComposite(); $this->filterComposite->addFilter("is", new IsFilter()); $this->filterComposite->addFilter("has", new HasFilter()); $this->filterComposite->addFilter("get", new GetFilter()); @@ -174,54 +166,4 @@ public function hydrate(array $data, $object) return $object; } - /** - * Add a new filter to take care of what needs to be hydrated. - * To exclude e.g. the method getServiceLocator: - * - * - * $composite->addFilter("servicelocator", - * function($property) { - * list($class, $method) = explode('::', $property); - * if ($method === 'getServiceLocator') { - * return false; - * } - * return true; - * }, FilterComposite::CONDITION_AND - * ); - * - * - * @param string $name Index in the composite - * @param callable|Zend\Stdlib\Hydrator\Filter\FilterInterface $filter - * @param int $condition - */ - public function addFilter($name, $filter, $condition = FilterComposite::CONDITION_OR) - { - $this->filterComposite->addFilter($name, $filter, $condition); - } - - /** - * Check whether a specific filter exists at key $name or not - * - * @param string $name Index in the composite - * @return bool - */ - public function hasFilter($name) - { - return $this->filterComposite->hasFilter($name); - } - - /** - * Remove a filter from the composition. - * To not extract "has" methods, you simply need to unregister it - * - * - * $filterComposite->removeFilter('has'); - * - * - * @param $name - */ - public function removeFilter($name) - { - $this->filterComposite->removeFilter($name); - } } From 09d682ec4c2d3c88a706cf96463ae3697d9dc3a3 Mon Sep 17 00:00:00 2001 From: ingo Date: Tue, 8 Jan 2013 22:09:42 +0100 Subject: [PATCH 054/127] Fixed complex composite --- src/Hydrator/Filter/FilterComposite.php | 11 ++++-- test/TestAsset/FilterCompositeTest.php | 49 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Hydrator/Filter/FilterComposite.php b/src/Hydrator/Filter/FilterComposite.php index 03767936b..00a99477a 100644 --- a/src/Hydrator/Filter/FilterComposite.php +++ b/src/Hydrator/Filter/FilterComposite.php @@ -158,16 +158,21 @@ public function hasFilter($name) */ public function filter($property) { + $andCount = count($this->andFilter); + $orCount = count($this->orFilter); // return true if no filters are registered if ( - count($this->orFilter) === 0 && - count($this->andFilter) === 0 + $orCount === 0 && + $andCount === 0 ) { return true; + } elseif ($orCount === 0 && $andCount !== 0) { + $returnValue = true; + } else { + $returnValue = false; } // Check if 1 from the or filters return true - $returnValue = false; foreach($this->orFilter as $filter) { if (is_callable($filter)) { if( $filter($property) === true) diff --git a/test/TestAsset/FilterCompositeTest.php b/test/TestAsset/FilterCompositeTest.php index 6efbbfaa7..cf278afac 100644 --- a/test/TestAsset/FilterCompositeTest.php +++ b/test/TestAsset/FilterCompositeTest.php @@ -106,6 +106,55 @@ public function testConstructorInjection() $this->assertTrue($filterComposite->filter('hasFoo')); } + public function testWithOnlyAndFiltersAdded() + { + $filter = new FilterComposite(); + $filter->addFilter("foobarbaz", function($property) { + return true; + }, FilterComposite::CONDITION_AND); + $filter->addFilter("foobar", function($property) { + return true; + }, FilterComposite::CONDITION_AND); + $this->assertTrue($filter->filter("foo")); + } + + public function testWithOnlyOrFiltersAdded() + { + $filter = new FilterComposite(); + $filter->addFilter("foobarbaz", function($property) { + return true; + }); + $filter->addFilter("foobar", function($property) { + return false; + }); + $this->assertTrue($filter->filter("foo")); + } + + public function testWithComplexCompositeAdded() + { + $filter1 = new FilterComposite(); + $filter1->addFilter("foobarbaz", function($property) { + return true; + }); + $filter1->addFilter("foobar", function($property) { + return false; + }); + $filter2 = new FilterComposite(); + $filter2->addFilter("bar", function($property) { + return true; + }, FilterComposite::CONDITION_AND); + $filter2->addFilter("barblubb", function($property) { + return true; + }, FilterComposite::CONDITION_AND); + $this->assertTrue($filter1->filter("foo")); + $this->assertTrue($filter2->filter("foo")); + $filter1->addFilter("bar", $filter2); + $this->assertTrue($filter1->filter("blubb")); + + $filter1->addFilter("blubb", function($property) { return false; }, FilterComposite::CONDITION_AND); + $this->assertFalse($filter1->filter("test")); + } + /** * @expectedException Zend\Stdlib\Exception\InvalidArgumentException * @expectedExceptionMessage The value of test should be either a callable From d23d89d0cbeb2b122e88f765c6790bd041773605 Mon Sep 17 00:00:00 2001 From: ingo Date: Tue, 8 Jan 2013 23:37:41 +0100 Subject: [PATCH 055/127] Added filter to arrayserializable --- src/Hydrator/AbstractHydrator.php | 10 +++++ src/Hydrator/ArraySerializable.php | 9 ++++- test/HydratorTest.php | 59 ++++++++++++++++++++++++++++ test/TestAsset/ArraySerializable.php | 54 +++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 test/TestAsset/ArraySerializable.php diff --git a/src/Hydrator/AbstractHydrator.php b/src/Hydrator/AbstractHydrator.php index 5d5dd56a4..19ac954d7 100644 --- a/src/Hydrator/AbstractHydrator.php +++ b/src/Hydrator/AbstractHydrator.php @@ -137,6 +137,16 @@ public function hydrateValue($name, $value) return $value; } + /** + * Get the filter instance + * + * @return Filter\FilterComposite + */ + public function getFilter() + { + return $this->filterComposite; + } + /** * Add a new filter to take care of what needs to be hydrated. * To exclude e.g. the method getServiceLocator: diff --git a/src/Hydrator/ArraySerializable.php b/src/Hydrator/ArraySerializable.php index fbe214db9..da16c4981 100644 --- a/src/Hydrator/ArraySerializable.php +++ b/src/Hydrator/ArraySerializable.php @@ -39,9 +39,14 @@ public function extract($object) $self = $this; $data = $object->getArrayCopy(); - array_walk($data, function (&$value, $name) use ($self) { - $value = $self->extractValue($name, $value); + array_walk($data, function (&$value, $name) use ($self, &$data) { + if (!$self->getFilter()->filter($name)) { + unset($data[$name]); + } else { + $value = $self->extractValue($name, $value); + } }); + #var_dump($data); return $data; } diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 4f178daf2..44dc16f3a 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -293,4 +293,63 @@ function($property) { $datas = $hydrator->extract($this->classMethodsCamelCase); $this->assertFalse(isset($datas['hasFoo'])); } + + public function testArraySerializableFilter() + { + $hydrator = new \Zend\Stdlib\Hydrator\ArraySerializable(); + $serializable = new \ZendTest\Stdlib\TestAsset\ArraySerializable(); + $this->assertSame( + array( + "foo" => "bar", + "bar" => "foo", + "blubb" => "baz", + "quo" => "blubb" + ), + $hydrator->extract($serializable) + ); + + $hydrator->addFilter("foo", function($property) { + if ($property == "foo") { + return false; + } + return true; + }); + + $this->assertSame( + array( + "bar" => "foo", + "blubb" => "baz", + "quo" => "blubb" + ), + $hydrator->extract($serializable) + ); + + $hydrator->addFilter("len", function($property) { + if (strlen($property) !== 3) { + return false; + } + return true; + }, FilterComposite::CONDITION_AND); + + $this->assertSame( + array( + "bar" => "foo", + "quo" => "blubb" + ), + $hydrator->extract($serializable) + ); + + $hydrator->removeFilter("len"); + $hydrator->removeFilter("foo"); + + $this->assertSame( + array( + "foo" => "bar", + "bar" => "foo", + "blubb" => "baz", + "quo" => "blubb" + ), + $hydrator->extract($serializable) + ); + } } diff --git a/test/TestAsset/ArraySerializable.php b/test/TestAsset/ArraySerializable.php new file mode 100644 index 000000000..498099c5f --- /dev/null +++ b/test/TestAsset/ArraySerializable.php @@ -0,0 +1,54 @@ +data = array( + "foo" => "bar", + "bar" => "foo", + "blubb" => "baz", + "quo" => "blubb" + ); + } + + /** + * Exchange internal values from provided array + * + * @param array $array + * @return void + */ + public function exchangeArray(array $array) + { + $this->data = $array; + } + + /** + * Return an array representation of the object + * + * @return array + */ + public function getArrayCopy() + { + return $this->data; + } +} + From d7c2600e4a5325687463998af21465b5080f1250 Mon Sep 17 00:00:00 2001 From: ingo Date: Tue, 8 Jan 2013 23:54:00 +0100 Subject: [PATCH 056/127] Filter feature to object property hydrator --- src/Hydrator/ObjectProperty.php | 8 +++++-- test/HydratorTest.php | 20 +++++++++++++++--- test/TestAsset/ObjectProperty.php | 35 +++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 test/TestAsset/ObjectProperty.php diff --git a/src/Hydrator/ObjectProperty.php b/src/Hydrator/ObjectProperty.php index a77e1e792..dd5f1a0dd 100644 --- a/src/Hydrator/ObjectProperty.php +++ b/src/Hydrator/ObjectProperty.php @@ -38,8 +38,12 @@ public function extract($object) $self = $this; $data = get_object_vars($object); - array_walk($data, function (&$value, $name) use ($self) { - $value = $self->extractValue($name, $value); + array_walk($data, function (&$value, $name) use ($self, &$data) { + if (!$self->getFilter()->filter($name)) { + unset($data[$name]); + } else { + $value = $self->extractValue($name, $value); + } }); return $data; } diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 44dc16f3a..f51b09355 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -12,14 +12,19 @@ use Zend\Stdlib\Hydrator\ClassMethods; use Zend\Stdlib\Hydrator\Reflection; +use Zend\Stdlib\Hydrator\ObjectProperty; +use Zend\Stdlib\Hydrator\ArraySerializable; use Zend\Stdlib\Hydrator\Filter\FilterComposite; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCase; use ZendTest\Stdlib\TestAsset\ClassMethodsUnderscore; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCaseMissing; use ZendTest\Stdlib\TestAsset\Reflection as ReflectionAsset; +use ZendTest\Stdlib\TestAsset\ObjectProperty as ObjectPropertyAsset; +use ZendTest\Stdlib\TestAsset\ArraySerializable as ArraySerializableAsset; use Zend\Stdlib\Hydrator\Strategy\DefaultStrategy; use Zend\Stdlib\Hydrator\Strategy\SerializableStrategy; + /** * @category Zend * @package Zend_Stdlib @@ -294,10 +299,11 @@ function($property) { $this->assertFalse(isset($datas['hasFoo'])); } - public function testArraySerializableFilter() + /** + * @dataProvider filterProvider + */ + public function testArraySerializableFilter($hydrator, $serializable) { - $hydrator = new \Zend\Stdlib\Hydrator\ArraySerializable(); - $serializable = new \ZendTest\Stdlib\TestAsset\ArraySerializable(); $this->assertSame( array( "foo" => "bar", @@ -352,4 +358,12 @@ public function testArraySerializableFilter() $hydrator->extract($serializable) ); } + + public function filterProvider() + { + return array( + array(new ObjectProperty(), new ObjectPropertyAsset), + array(new ArraySerializable(), new ArraySerializableAsset) + ); + } } diff --git a/test/TestAsset/ObjectProperty.php b/test/TestAsset/ObjectProperty.php new file mode 100644 index 000000000..6b73900ee --- /dev/null +++ b/test/TestAsset/ObjectProperty.php @@ -0,0 +1,35 @@ +foo = "bar"; + $this->bar = "foo"; + $this->blubb = "baz"; + $this->quo = "blubb"; + } + +} + From 7be4274ae18df4782c40a104aeb62c5655fcb819 Mon Sep 17 00:00:00 2001 From: ingo Date: Tue, 8 Jan 2013 23:56:33 +0100 Subject: [PATCH 057/127] Fixed code style --- src/Hydrator/Filter/FilterComposite.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Hydrator/Filter/FilterComposite.php b/src/Hydrator/Filter/FilterComposite.php index 00a99477a..cae986bc0 100644 --- a/src/Hydrator/Filter/FilterComposite.php +++ b/src/Hydrator/Filter/FilterComposite.php @@ -162,8 +162,8 @@ public function filter($property) $orCount = count($this->orFilter); // return true if no filters are registered if ( - $orCount === 0 && - $andCount === 0 + $orCount === 0 + && $andCount === 0 ) { return true; } elseif ($orCount === 0 && $andCount !== 0) { From bbbe6bf42d455e8835c324f7db3f6bf4c85e1786 Mon Sep 17 00:00:00 2001 From: ingo Date: Wed, 9 Jan 2013 00:37:25 +0100 Subject: [PATCH 058/127] Added filter to reflection --- src/Hydrator/Reflection.php | 3 +++ test/HydratorTest.php | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Hydrator/Reflection.php b/src/Hydrator/Reflection.php index b372665d1..d46abce7d 100644 --- a/src/Hydrator/Reflection.php +++ b/src/Hydrator/Reflection.php @@ -37,6 +37,9 @@ public function extract($object) $result = array(); foreach (self::getReflProperties($object) as $property) { $propertyName = $property->getName(); + if (!$this->filterComposite->filter($propertyName)) { + continue; + } $value = $property->getValue($object); $result[$propertyName] = $this->extractValue($propertyName, $value); diff --git a/test/HydratorTest.php b/test/HydratorTest.php index f51b09355..17ceef560 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -19,6 +19,7 @@ use ZendTest\Stdlib\TestAsset\ClassMethodsUnderscore; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCaseMissing; use ZendTest\Stdlib\TestAsset\Reflection as ReflectionAsset; +use ZendTest\Stdlib\TestAsset\ReflectionFilter; use ZendTest\Stdlib\TestAsset\ObjectProperty as ObjectPropertyAsset; use ZendTest\Stdlib\TestAsset\ArraySerializable as ArraySerializableAsset; use Zend\Stdlib\Hydrator\Strategy\DefaultStrategy; @@ -363,7 +364,8 @@ public function filterProvider() { return array( array(new ObjectProperty(), new ObjectPropertyAsset), - array(new ArraySerializable(), new ArraySerializableAsset) + array(new ArraySerializable(), new ArraySerializableAsset), + array(new Reflection(), new ReflectionFilter) ); } } From e822d1f216155ccaa50821ebdf212f21bd082b3a Mon Sep 17 00:00:00 2001 From: ingo Date: Wed, 9 Jan 2013 01:09:12 +0100 Subject: [PATCH 059/127] Added number of parameter filter. Fixed zendframework/zf2#3352 --- src/Hydrator/ClassMethods.php | 3 + src/Hydrator/Filter/FilterInterface.php | 7 +++ .../Filter/NumberOfParameterFilter.php | 60 +++++++++++++++++++ test/HydratorTest.php | 17 ++++++ .../ClassMethodsInvalidParameter.php | 43 +++++++++++++ test/TestAsset/ReflectionFilter.php | 35 +++++++++++ 6 files changed, 165 insertions(+) create mode 100644 src/Hydrator/Filter/NumberOfParameterFilter.php create mode 100644 test/TestAsset/ClassMethodsInvalidParameter.php create mode 100644 test/TestAsset/ReflectionFilter.php diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 4cb37c4e4..d78dfb847 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -11,9 +11,11 @@ namespace Zend\Stdlib\Hydrator; use Zend\Stdlib\Exception; +use Zend\Stdlib\Hydrator\Filter\FilterComposite; use Zend\Stdlib\Hydrator\Filter\GetFilter; use Zend\Stdlib\Hydrator\Filter\HasFilter; use Zend\Stdlib\Hydrator\Filter\IsFilter; +use Zend\Stdlib\Hydrator\Filter\NumberOfParameterFilter; /** * @category Zend @@ -40,6 +42,7 @@ public function __construct($underscoreSeparatedKeys = true) $this->filterComposite->addFilter("is", new IsFilter()); $this->filterComposite->addFilter("has", new HasFilter()); $this->filterComposite->addFilter("get", new GetFilter()); + $this->filterComposite->addFilter("parameter", new NumberOfParameterFilter(), FilterComposite::CONDITION_AND); } /** diff --git a/src/Hydrator/Filter/FilterInterface.php b/src/Hydrator/Filter/FilterInterface.php index 961ac6102..fe70feb84 100644 --- a/src/Hydrator/Filter/FilterInterface.php +++ b/src/Hydrator/Filter/FilterInterface.php @@ -16,5 +16,12 @@ */ interface FilterInterface { + /** + * Should return true, if the given filter + * does not match + * + * @param string $property The name of the property + * @return bool + */ public function filter($property); } diff --git a/src/Hydrator/Filter/NumberOfParameterFilter.php b/src/Hydrator/Filter/NumberOfParameterFilter.php new file mode 100644 index 000000000..2a0479b5a --- /dev/null +++ b/src/Hydrator/Filter/NumberOfParameterFilter.php @@ -0,0 +1,60 @@ +numberOfParameters = 0; + } + + /** + * @param string $property the name of the property + * @throws InvalidArgumentException + */ + public function filter($property) + { + try { + $reflectionMethod = new ReflectionMethod($property); + } catch( ReflectionException $exception) { + throw new InvalidArgumentException( + "Method $property doesn't exist" + ); + } + + if ($reflectionMethod->getNumberOfParameters() !== $this->numberOfParameters) { + return false; + } + + return true; + } +} + diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 17ceef560..261c6b146 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -18,6 +18,7 @@ use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCase; use ZendTest\Stdlib\TestAsset\ClassMethodsUnderscore; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCaseMissing; +use ZendTest\Stdlib\TestAsset\ClassMethodsInvalidParameter; use ZendTest\Stdlib\TestAsset\Reflection as ReflectionAsset; use ZendTest\Stdlib\TestAsset\ReflectionFilter; use ZendTest\Stdlib\TestAsset\ObjectProperty as ObjectPropertyAsset; @@ -50,6 +51,11 @@ class HydratorTest extends \PHPUnit_Framework_TestCase */ protected $classMethodsUnderscore; + /** + * @var ClassMethodsInvalidParameter + */ + protected $classMethodsInvalidParameter; + /** * @var ReflectionAsset */ @@ -61,6 +67,7 @@ public function setUp() $this->classMethodsCamelCaseMissing = new ClassMethodsCamelCaseMissing(); $this->classMethodsUnderscore = new ClassMethodsUnderscore(); $this->reflection = new ReflectionAsset; + $this->classMethodsInvalidParameter = new ClassMethodsInvalidParameter(); } public function testInitiateValues() @@ -368,4 +375,14 @@ public function filterProvider() array(new Reflection(), new ReflectionFilter) ); } + + public function testHydratorClassMethodsWithInvalidNumberOfParameters() + { + $hydrator = new ClassMethods(false); + $datas = $hydrator->extract($this->classMethodsInvalidParameter); + + $this->assertTrue($datas['hasBar']); + $this->assertEquals('Bar', $datas['foo']); + $this->assertFalse($datas['isBla']); + } } diff --git a/test/TestAsset/ClassMethodsInvalidParameter.php b/test/TestAsset/ClassMethodsInvalidParameter.php new file mode 100644 index 000000000..cf9338865 --- /dev/null +++ b/test/TestAsset/ClassMethodsInvalidParameter.php @@ -0,0 +1,43 @@ +foo = "bar"; + $this->bar = "foo"; + $this->blubb = "baz"; + $this->quo = "blubb"; + } + +} + From dc54cde6dc3376f49d0cceb46c8a4ad1cb3bfc07 Mon Sep 17 00:00:00 2001 From: David Kidd Date: Wed, 9 Jan 2013 09:38:04 -0500 Subject: [PATCH 060/127] Refactored Zend\Stdlib\DateTime::createISO8601Date to Zend\Stdlib\DateTime::createFromISO8601, updated documentation --- src/DateTime.php | 6 ++++-- test/DateTimeTest.php | 7 +++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/DateTime.php b/src/DateTime.php index 397793899..ba388e135 100644 --- a/src/DateTime.php +++ b/src/DateTime.php @@ -23,13 +23,15 @@ class DateTime extends \DateTime { /** - * Creates a DateTime object from a string and (optional) timezone. + * The DateTime::ISO8601 constant used by php's native DateTime object does + * not allow for fractions of a second. This function better handles ISO8601 + * formatted date strings. * * @param string $time * @param DateTimeZone $timezone * @return mixed */ - public static function createISO8601Date($time, DateTimeZone $timezone = null){ + public static function createFromISO8601($time, DateTimeZone $timezone = null){ $format = self::ISO8601; if (isset($time[19]) && $time[19] === '.') { $format = 'Y-m-d\TH:i:s.uO'; diff --git a/test/DateTimeTest.php b/test/DateTimeTest.php index a401ecc91..e981f948e 100644 --- a/test/DateTimeTest.php +++ b/test/DateTimeTest.php @@ -5,7 +5,7 @@ * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License - * @package Zend_Feed + * @package Zend_Stdlib */ namespace ZendTest\Stdlib; @@ -27,7 +27,7 @@ public function testCreatesIS08601WithoutFractionalSeconds() { $time = '2009-03-07T08:03:50Z'; - $date = DateTime::createISO8601Date($time); + $date = DateTime::createFromISO8601($time); $this->assertEquals( \DateTime::createFromFormat(\DateTime::ISO8601, $time), $date); } @@ -36,11 +36,10 @@ public function testCreatesIS08601WithFractionalSeconds() { $time = '2009-03-07T08:03:50.012Z'; - $date = DateTime::createISO8601Date($time); + $date = DateTime::createFromISO8601($time); $standard = \DateTime::createFromFormat('Y-m-d\TH:i:s.uO', $time); $this->assertEquals( $standard, $date); } - } \ No newline at end of file From 7d1820b470f05145c6cb5b3125dcb5ab47fcb556 Mon Sep 17 00:00:00 2001 From: David Kidd Date: Wed, 9 Jan 2013 10:49:44 -0500 Subject: [PATCH 061/127] Fixed annotation of ZendTest\DateTimeTest --- test/DateTimeTest.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/test/DateTimeTest.php b/test/DateTimeTest.php index e981f948e..5929da034 100644 --- a/test/DateTimeTest.php +++ b/test/DateTimeTest.php @@ -13,13 +13,12 @@ use Zend\Stdlib\DateTime; /** -* @category Zend -* @package Zend_Feed -* @subpackage UnitTests -* @group Zend_Feed -* @group Zend_Feed_Reader -*/ -class AtomTest extends \PHPUnit_Framework_TestCase + * @category Zend + * @package Zend_Stdlib + * @subpackage UnitTests + * @group Zend_Stdlib + */ +class DateTimeTest extends \PHPUnit_Framework_TestCase { public $dateTime; From 45016f956c4d9868daf4b9dd3b28fccfc718e1ae Mon Sep 17 00:00:00 2001 From: David Kidd Date: Wed, 9 Jan 2013 12:47:41 -0500 Subject: [PATCH 062/127] Ran php-cs-fixer on Zend\Stdlib\DateTime.php and ZendTest\Stdlib\DateTimeTest.php --- src/DateTime.php | 22 ++++++++++++---------- test/DateTimeTest.php | 16 ++++++++-------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/DateTime.php b/src/DateTime.php index ba388e135..a3d8a651d 100644 --- a/src/DateTime.php +++ b/src/DateTime.php @@ -20,27 +20,29 @@ * @category Zend * @package Zend_Stdlib */ -class DateTime extends \DateTime { - +class DateTime extends \DateTime +{ /** * The DateTime::ISO8601 constant used by php's native DateTime object does * not allow for fractions of a second. This function better handles ISO8601 * formatted date strings. - * - * @param string $time - * @param DateTimeZone $timezone + * + * @param string $time + * @param DateTimeZone $timezone * @return mixed */ - public static function createFromISO8601($time, DateTimeZone $timezone = null){ + public static function createFromISO8601($time, DateTimeZone $timezone = null) + { $format = self::ISO8601; if (isset($time[19]) && $time[19] === '.') { $format = 'Y-m-d\TH:i:s.uO'; } - - if( $timezone !== null ) + + if ($timezone !== null) { return self::createFromFormat($format, $time, $timezone); + } return self::createFromFormat($format, $time); } - -} \ No newline at end of file + +} diff --git a/test/DateTimeTest.php b/test/DateTimeTest.php index 5929da034..45d4f8909 100644 --- a/test/DateTimeTest.php +++ b/test/DateTimeTest.php @@ -21,24 +21,24 @@ class DateTimeTest extends \PHPUnit_Framework_TestCase { public $dateTime; - + public function testCreatesIS08601WithoutFractionalSeconds() { $time = '2009-03-07T08:03:50Z'; - + $date = DateTime::createFromISO8601($time); - + $this->assertEquals( \DateTime::createFromFormat(\DateTime::ISO8601, $time), $date); } - + public function testCreatesIS08601WithFractionalSeconds() { $time = '2009-03-07T08:03:50.012Z'; - + $date = DateTime::createFromISO8601($time); - + $standard = \DateTime::createFromFormat('Y-m-d\TH:i:s.uO', $time); - + $this->assertEquals( $standard, $date); } -} \ No newline at end of file +} From d33133a5e30be0a8ba38843411216e84b219b80a Mon Sep 17 00:00:00 2001 From: Maks3w Date: Wed, 9 Jan 2013 20:53:45 +0100 Subject: [PATCH 063/127] [zendframework/zf2#3375] Update copyright year --- src/DateTime.php | 2 +- test/DateTimeTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DateTime.php b/src/DateTime.php index a3d8a651d..032fc94ff 100644 --- a/src/DateTime.php +++ b/src/DateTime.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ diff --git a/test/DateTimeTest.php b/test/DateTimeTest.php index 45d4f8909..f6c2e0553 100644 --- a/test/DateTimeTest.php +++ b/test/DateTimeTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @package Zend_Stdlib */ From 25fa34ad67c1bbb67eadcdabcceed53c72d803ad Mon Sep 17 00:00:00 2001 From: ingo Date: Fri, 11 Jan 2013 01:20:50 +0100 Subject: [PATCH 064/127] Implemented FilterProviderInterface and MethodMatchFilter --- src/Hydrator/ClassMethods.php | 19 ++++- .../Filter/FilterProviderInterface.php | 25 +++++++ src/Hydrator/Filter/MethodMatchFilter.php | 53 ++++++++++++++ test/HydratorTest.php | 11 +++ .../ClassMethodsFilterProviderInterface.php | 70 +++++++++++++++++++ 5 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 src/Hydrator/Filter/FilterProviderInterface.php create mode 100644 src/Hydrator/Filter/MethodMatchFilter.php create mode 100644 test/TestAsset/ClassMethodsFilterProviderInterface.php diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index d78dfb847..0c6ffb142 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -12,6 +12,8 @@ use Zend\Stdlib\Exception; use Zend\Stdlib\Hydrator\Filter\FilterComposite; +use Zend\Stdlib\Hydrator\Filter\FilterProviderInterface; +use Zend\Stdlib\Hydrator\Filter\MethodMatchFilter; use Zend\Stdlib\Hydrator\Filter\GetFilter; use Zend\Stdlib\Hydrator\Filter\HasFilter; use Zend\Stdlib\Hydrator\Filter\IsFilter; @@ -101,6 +103,21 @@ public function extract($object) )); } + $filter = null; + if ($object instanceof FilterProviderInterface) { + $filter = $object->getFilter(); + if ($filter instanceof FilterComposite) + { + $filter->addFilter( + "getfilter", + new MethodMatchFilter("getFilter"), + FilterComposite::CONDITION_AND + ); + } + } else { + $filter = $this->filterComposite; + } + $transform = function ($letters) { $letter = array_shift($letters); return '_' . strtolower($letter); @@ -110,7 +127,7 @@ public function extract($object) foreach ($methods as $method) { if ( - !$this->filterComposite->filter( + !$filter->filter( get_class($object) . '::' . $method ) ) { diff --git a/src/Hydrator/Filter/FilterProviderInterface.php b/src/Hydrator/Filter/FilterProviderInterface.php new file mode 100644 index 000000000..562b6fb6f --- /dev/null +++ b/src/Hydrator/Filter/FilterProviderInterface.php @@ -0,0 +1,25 @@ +method = $method; + $this->exclude = $exclude; + } + + public function filter($property) + { + $pos = strpos($property, '::'); + if ($pos !== false) { + $pos += 2; + } else { + $pos = 0; + } + if (substr($property, $pos) === $this->method) { + return $this->exclude ? false : true; + } + return $this->exclude ? true : false; + } +} diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 261c6b146..f67259c6f 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -16,6 +16,7 @@ use Zend\Stdlib\Hydrator\ArraySerializable; use Zend\Stdlib\Hydrator\Filter\FilterComposite; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCase; +use ZendTest\Stdlib\TestAsset\ClassMethodsFilterProviderInterface; use ZendTest\Stdlib\TestAsset\ClassMethodsUnderscore; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCaseMissing; use ZendTest\Stdlib\TestAsset\ClassMethodsInvalidParameter; @@ -385,4 +386,14 @@ public function testHydratorClassMethodsWithInvalidNumberOfParameters() $this->assertEquals('Bar', $datas['foo']); $this->assertFalse($datas['isBla']); } + + public function testObjectBasedFilters() + { + $hydrator = new ClassMethods(false); + $foo = new ClassMethodsFilterProviderInterface(); + $data = $hydrator->extract($foo); + $this->assertFalse(array_key_exists("filter", $data)); + $this->assertSame("bar", $data["foo"]); + $this->assertSame("foo", $data["bar"]); + } } diff --git a/test/TestAsset/ClassMethodsFilterProviderInterface.php b/test/TestAsset/ClassMethodsFilterProviderInterface.php new file mode 100644 index 000000000..b24b8210a --- /dev/null +++ b/test/TestAsset/ClassMethodsFilterProviderInterface.php @@ -0,0 +1,70 @@ +addFilter("get", new GetFilter()); + $excludes = new FilterComposite(); + $excludes->addFilter( + "servicemanager", + new MethodMatchFilter("getServiceManager"), + FilterComposite::CONDITION_AND + ); + $excludes->addFilter( + "eventmanager", + new MethodMatchFilter("getEventManager"), + FilterComposite::CONDITION_AND + ); + $filterComposite->addFilter("excludes", $excludes, FilterComposite::CONDITION_AND); + + return $filterComposite; + } +} From 86896f80c9ff95c87e7f56619734a9307f021eea Mon Sep 17 00:00:00 2001 From: ingo Date: Fri, 11 Jan 2013 02:02:27 +0100 Subject: [PATCH 065/127] Simplified code --- src/Hydrator/ClassMethods.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 0c6ffb142..2255b232c 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -105,15 +105,10 @@ public function extract($object) $filter = null; if ($object instanceof FilterProviderInterface) { - $filter = $object->getFilter(); - if ($filter instanceof FilterComposite) - { - $filter->addFilter( - "getfilter", - new MethodMatchFilter("getFilter"), - FilterComposite::CONDITION_AND - ); - } + $filter = new FilterComposite( + array($object->getFilter()), + array(new MethodMatchFilter("getFilter")) + ); } else { $filter = $this->filterComposite; } From a9ddfc98c20c9ab629bb61826aa404146ad1a141 Mon Sep 17 00:00:00 2001 From: ingo Date: Sat, 12 Jan 2013 20:25:15 +0100 Subject: [PATCH 066/127] Removed dump --- src/Hydrator/ArraySerializable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hydrator/ArraySerializable.php b/src/Hydrator/ArraySerializable.php index da16c4981..8332a983b 100644 --- a/src/Hydrator/ArraySerializable.php +++ b/src/Hydrator/ArraySerializable.php @@ -46,7 +46,7 @@ public function extract($object) $value = $self->extractValue($name, $value); } }); - #var_dump($data); + return $data; } From 32ec458d09cc21f0d25ce2f1f3f68390ebcbae26 Mon Sep 17 00:00:00 2001 From: ingo Date: Sun, 13 Jan 2013 21:51:46 +0100 Subject: [PATCH 067/127] CS fixes --- src/Hydrator/ClassMethods.php | 14 +++++---- src/Hydrator/Filter/FilterComposite.php | 30 ++++++++----------- .../Filter/NumberOfParameterFilter.php | 1 - 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 2255b232c..42681737d 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -48,7 +48,7 @@ public function __construct($underscoreSeparatedKeys = true) } /** - * @param array|\Traversable $options + * @param array|\Traversable $options * @return ClassMethods * @throws Exception\InvalidArgumentException */ @@ -69,12 +69,13 @@ public function setOptions($options) } /** - * @param boolean $underscoreSeparatedKeys + * @param boolean $underscoreSeparatedKeys * @return ClassMethods */ public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys) { $this->underscoreSeparatedKeys = $underscoreSeparatedKeys; + return $this; } @@ -91,7 +92,7 @@ public function getUnderscoreSeparatedKeys() * * Extracts the getter/setter of the given $object. * - * @param object $object + * @param object $object * @return array * @throws Exception\BadMethodCallException for a non-object $object */ @@ -115,6 +116,7 @@ public function extract($object) $transform = function ($letters) { $letter = array_shift($letters); + return '_' . strtolower($letter); }; $attributes = array(); @@ -149,8 +151,8 @@ public function extract($object) * * Hydrates an object by getter/setter methods of the object. * - * @param array $data - * @param object $object + * @param array $data + * @param object $object * @return object * @throws Exception\BadMethodCallException for a non-object $object */ @@ -164,6 +166,7 @@ public function hydrate(array $data, $object) $transform = function ($letters) { $letter = substr(array_shift($letters), 1, 1); + return ucfirst($letter); }; @@ -178,6 +181,7 @@ public function hydrate(array $data, $object) $object->$method($value); } } + return $object; } diff --git a/src/Hydrator/Filter/FilterComposite.php b/src/Hydrator/Filter/FilterComposite.php index cae986bc0..7531d5bd1 100644 --- a/src/Hydrator/Filter/FilterComposite.php +++ b/src/Hydrator/Filter/FilterComposite.php @@ -48,7 +48,7 @@ public function __construct($orFilter = array(), $andFilter = array()) { array_walk($orFilter, function($value, $key) { - if( + if ( !is_callable($value) && !$value instanceof FilterInterface ) { @@ -62,7 +62,7 @@ function($value, $key) { array_walk($andFilter, function($value, $key) { - if( + if ( !is_callable($value) && !$value instanceof FilterInterface ) { @@ -94,9 +94,9 @@ function($value, $key) { * ); * * - * @param string $name - * @param callable|FilterInterface $filter - * @param int $condition Can be either FilterComposite::CONDITION_OR or FilterComposite::CONDITION_AND + * @param string $name + * @param callable|FilterInterface $filter + * @param int $condition Can be either FilterComposite::CONDITION_OR or FilterComposite::CONDITION_AND * @throws InvalidArgumentException * @return FilterComposite */ @@ -126,11 +126,11 @@ public function addFilter($name, $filter, $condition = self::CONDITION_OR) */ public function removeFilter($name) { - if( isset($this->orFilter[$name])) { + if (isset($this->orFilter[$name])) { unset($this->orFilter[$name]); } - if( isset($this->andFilter[$name])) { + if (isset($this->andFilter[$name])) { unset($this->andFilter[$name]); } @@ -161,10 +161,7 @@ public function filter($property) $andCount = count($this->andFilter); $orCount = count($this->orFilter); // return true if no filters are registered - if ( - $orCount === 0 - && $andCount === 0 - ) { + if ($orCount === 0 && $andCount === 0) { return true; } elseif ($orCount === 0 && $andCount !== 0) { $returnValue = true; @@ -173,10 +170,9 @@ public function filter($property) } // Check if 1 from the or filters return true - foreach($this->orFilter as $filter) { + foreach ($this->orFilter as $filter) { if (is_callable($filter)) { - if( $filter($property) === true) - { + if ( $filter($property) === true) { $returnValue = true; break; } @@ -190,14 +186,14 @@ public function filter($property) } // Check if all of the and condition return true - foreach($this->andFilter as $filter) { + foreach ($this->andFilter as $filter) { if (is_callable($filter)) { - if( $filter($property) === false) { + if ($filter($property) === false) { return false; } continue; } else { - if( $filter->filter($property) === false) { + if ($filter->filter($property) === false) { return false; } } diff --git a/src/Hydrator/Filter/NumberOfParameterFilter.php b/src/Hydrator/Filter/NumberOfParameterFilter.php index 2a0479b5a..3c2e0b94a 100644 --- a/src/Hydrator/Filter/NumberOfParameterFilter.php +++ b/src/Hydrator/Filter/NumberOfParameterFilter.php @@ -57,4 +57,3 @@ public function filter($property) return true; } } - From a385e2a8dae6ab96ac8976cd9c3a02ecad233822 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 14 Jan 2013 10:41:22 -0600 Subject: [PATCH 068/127] [zendframework/zf2#3352] Import ReflectionMethod --- src/Hydrator/ClassMethods.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index b756d9e38..0f3dea2e2 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -10,6 +10,7 @@ namespace Zend\Stdlib\Hydrator; +use ReflectionMethod; use Zend\Stdlib\Exception; /** @@ -64,7 +65,7 @@ public function extract($object) continue; } - $reflectionMethod = new \ReflectionMethod(get_class($object) . '::' . $method); + $reflectionMethod = new ReflectionMethod(get_class($object) . '::' . $method); if ($reflectionMethod->getNumberOfParameters() > 0) { continue; } From 196c1dad9b74b13defbb97ab09cba6707db3b9db Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 18 Jan 2013 15:09:18 -0600 Subject: [PATCH 069/127] [zendframework/zf2#3230] CS fixes - Trailing whitespace --- src/Hydrator/Strategy/ClosureStrategy.php | 10 +++++----- test/HydratorClosureStrategyTest.php | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Hydrator/Strategy/ClosureStrategy.php b/src/Hydrator/Strategy/ClosureStrategy.php index 9c1a694a7..002ca9f70 100644 --- a/src/Hydrator/Strategy/ClosureStrategy.php +++ b/src/Hydrator/Strategy/ClosureStrategy.php @@ -25,7 +25,7 @@ class ClosureStrategy implements StrategyInterface * @var callable */ protected $extractFunc = null; - + /** * Function, used in hydrate method, default: * function($value) { @@ -34,7 +34,7 @@ class ClosureStrategy implements StrategyInterface * @var callable */ protected $hydrateFunc = null; - + /** * You can describe how your values will extract and hydrate, like this: * $hydrator->addStrategy('category', new ClosureStrategy( @@ -45,9 +45,9 @@ class ClosureStrategy implements StrategyInterface * return new Category((int)$value); * } * )); - * + * * @param callable $extractFunc - anonymous function, that extract values - * from object + * from object * @param callable $hydrateFunc - anonymous function, that hydrate values * into object */ @@ -77,7 +77,7 @@ public function __construct($extractFunc = null, $hydrateFunc = null) }; } } - + /** * Converts the given value so that it can be extracted by the hydrator. * diff --git a/test/HydratorClosureStrategyTest.php b/test/HydratorClosureStrategyTest.php index fd8601dae..ae4d227ef 100644 --- a/test/HydratorClosureStrategyTest.php +++ b/test/HydratorClosureStrategyTest.php @@ -21,7 +21,7 @@ */ class HydratorClosureStrategyTest extends \PHPUnit_Framework_TestCase { - + /** * The hydrator that is used during testing. * @@ -33,7 +33,7 @@ public function setUp() { $this->hydrator = new ObjectProperty(); } - + public function testAddingStrategy() { $this->assertAttributeCount(0, 'strategies', $this->hydrator); @@ -42,12 +42,12 @@ public function testAddingStrategy() $this->assertAttributeCount(1, 'strategies', $this->hydrator); } - + public function testCheckStrategyEmpty() { $this->assertFalse($this->hydrator->hasStrategy('myStrategy')); } - + public function testCheckStrategyNotEmpty() { $this->hydrator->addStrategy('myStrategy', new ClosureStrategy()); @@ -88,14 +88,14 @@ function($value) { }, null )); - + $entity = new TestAsset\HydratorClosureStrategyEntity(111, 'world'); $values = $this->hydrator->extract($entity); - + $this->assertEquals(111, $values['field1']); $this->assertEquals('hello, world!', $values['field2']); } - + public function testHydratingObjects() { $this->hydrator->addStrategy('field2', new ClosureStrategy( @@ -110,17 +110,17 @@ function($value) { return new TestAsset\HydratorClosureStrategyEntity($value, sprintf('111%s', $value)); } )); - + $entity = new TestAsset\HydratorClosureStrategyEntity(111, 'world'); - + $values = $this->hydrator->extract($entity); $values['field3'] = 333; $this->assertCount(2, (array)$entity); $this->hydrator->hydrate($values, $entity); $this->assertCount(3, (array)$entity); - + $this->assertInstanceOf('ZendTest\Stdlib\TestAsset\HydratorClosureStrategyEntity', $entity->field3); } - + } From 04b932a1fb216b3933a7d8eebcf63beec708893a Mon Sep 17 00:00:00 2001 From: radnan Date: Mon, 21 Jan 2013 17:44:00 -0600 Subject: [PATCH 070/127] string/int safe inArray implementation --- src/ArrayUtils.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/ArrayUtils.php b/src/ArrayUtils.php index b2870efe0..ff4bb67db 100644 --- a/src/ArrayUtils.php +++ b/src/ArrayUtils.php @@ -164,6 +164,36 @@ public static function isHashTable($value, $allowEmpty = false) return (array_values($value) !== $value); } + /** + * Checks if a value exists in an array. + * + * Due to "foo" == 0 === TRUE with in_array when strict = false, an option + * has been added to prevent this. When $strict = 0/false, the most secure + * non-strict check is implemented. if $strict = -1, the default in_array + * non-strict behaviour is used. + * + * @param mixed $needle + * @param array $haystack + * @param int|bool $strict + * @return bool + */ + public static function inArray($needle, array $haystack, $strict = false) + { + if (!$strict) { + if (is_int($needle) || is_float($needle)) { + $needle = (string) $needle; + } + if (is_string($needle)) { + foreach ($haystack as &$h) { + if (is_int($h) || is_float($h)) { + $h = (string) $h; + } + } + } + } + return in_array($needle, $haystack, $strict); + } + /** * Convert an iterator to an array. * From aa7c6a8d7d6370c552c8f521dd031c355885a6e2 Mon Sep 17 00:00:00 2001 From: Stefan Kleff Date: Mon, 28 Jan 2013 13:37:10 +0100 Subject: [PATCH 071/127] Added ability to use the context in hydrator strategies. This is very similar how validators are implemented. --- src/Hydrator/AbstractHydrator.php | 10 +++--- src/Hydrator/ClassMethods.php | 4 +-- src/Hydrator/ObjectProperty.php | 4 +-- src/Hydrator/Reflection.php | 4 +-- test/HydratorStrategyTest.php | 24 ++++++++++++++ .../HydratorStrategyContextAware.php | 31 +++++++++++++++++++ 6 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 test/TestAsset/HydratorStrategyContextAware.php diff --git a/src/Hydrator/AbstractHydrator.php b/src/Hydrator/AbstractHydrator.php index 5d62edc85..adccdad0d 100644 --- a/src/Hydrator/AbstractHydrator.php +++ b/src/Hydrator/AbstractHydrator.php @@ -104,13 +104,14 @@ public function removeStrategy($name) * * @param string $name The name of the strategy to use. * @param mixed $value The value that should be converted. + * @param array $data The object is optionally provided as context. * @return mixed */ - public function extractValue($name, $value) + public function extractValue($name, $value, $object = null) { if ($this->hasStrategy($name)) { $strategy = $this->getStrategy($name); - $value = $strategy->extract($value); + $value = $strategy->extract($value, $object); } return $value; } @@ -120,13 +121,14 @@ public function extractValue($name, $value) * * @param string $name The name of the strategy to use. * @param mixed $value The value that should be converted. + * @param array $data The whole data is optionally provided as context. * @return mixed */ - public function hydrateValue($name, $value) + public function hydrateValue($name, $value, $data = null) { if ($this->hasStrategy($name)) { $strategy = $this->getStrategy($name); - $value = $strategy->hydrate($value); + $value = $strategy->hydrate($value, $data); } return $value; } diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index d29185fe6..a3904013b 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -142,7 +142,7 @@ public function extract($object) if ($this->underscoreSeparatedKeys) { $attribute = preg_replace_callback('/([A-Z])/', $transform, $attribute); } - $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); + $attributes[$attribute] = $this->extractValue($attribute, $object->$method(), $object); } return $attributes; @@ -178,7 +178,7 @@ public function hydrate(array $data, $object) $method = preg_replace_callback('/(_[a-z])/', $transform, $method); } if (method_exists($object, $method)) { - $value = $this->hydrateValue($property, $value); + $value = $this->hydrateValue($property, $value, $data); $object->$method($value); } diff --git a/src/Hydrator/ObjectProperty.php b/src/Hydrator/ObjectProperty.php index e212dc79a..acff0359a 100644 --- a/src/Hydrator/ObjectProperty.php +++ b/src/Hydrator/ObjectProperty.php @@ -36,7 +36,7 @@ public function extract($object) if (!$self->getFilter()->filter($name)) { unset($data[$name]); } else { - $value = $self->extractValue($name, $value); + $value = $self->extractValue($name, $value, $object); } }); return $data; @@ -60,7 +60,7 @@ public function hydrate(array $data, $object) )); } foreach ($data as $property => $value) { - $object->$property = $this->hydrateValue($property, $value); + $object->$property = $this->hydrateValue($property, $value, $data); } return $object; } diff --git a/src/Hydrator/Reflection.php b/src/Hydrator/Reflection.php index 6fe230204..1c093c88b 100644 --- a/src/Hydrator/Reflection.php +++ b/src/Hydrator/Reflection.php @@ -36,7 +36,7 @@ public function extract($object) } $value = $property->getValue($object); - $result[$propertyName] = $this->extractValue($propertyName, $value); + $result[$propertyName] = $this->extractValue($propertyName, $value, $object); } return $result; @@ -54,7 +54,7 @@ public function hydrate(array $data, $object) $reflProperties = self::getReflProperties($object); foreach ($data as $key => $value) { if (isset($reflProperties[$key])) { - $reflProperties[$key]->setValue($object, $this->hydrateValue($key, $value)); + $reflProperties[$key]->setValue($object, $this->hydrateValue($key, $value, $data)); } } return $object; diff --git a/test/HydratorStrategyTest.php b/test/HydratorStrategyTest.php index 0d0d05fd4..926cfbf3f 100644 --- a/test/HydratorStrategyTest.php +++ b/test/HydratorStrategyTest.php @@ -144,4 +144,28 @@ public function underscoreHandlingDataProvider() array(false, 'fooBar'), ); } + + public function testContextAwarenessExtract() + { + $strategy = new TestAsset\HydratorStrategyContextAware(); + $this->hydrator->addStrategy('field2', $strategy); + + $entityB = new TestAsset\HydratorStrategyEntityB('X', 'Y'); + $attributes = $this->hydrator->extract($entityB); + + $this->assertEquals($entityB, $strategy->object); + } + + public function testContextAwarenessHydrate() + { + $strategy = new TestAsset\HydratorStrategyContextAware(); + $this->hydrator->addStrategy('field2', $strategy); + + $entityB = new TestAsset\HydratorStrategyEntityB('X', 'Y'); + $data = array('field1' => 'A', 'field2' => 'B'); + $attributes = $this->hydrator->hydrate($data, $entityB); + + $this->assertEquals($data, $strategy->data); + } + } diff --git a/test/TestAsset/HydratorStrategyContextAware.php b/test/TestAsset/HydratorStrategyContextAware.php new file mode 100644 index 000000000..d879aff73 --- /dev/null +++ b/test/TestAsset/HydratorStrategyContextAware.php @@ -0,0 +1,31 @@ +object = $object; + return $value; + } + + public function hydrate($value, $data = null) + { + $this->data = $data; + return $value; + } +} From 663db4de5b72fe594abd2dc473c625f8d5bbe1de Mon Sep 17 00:00:00 2001 From: Stefan Kleff Date: Fri, 1 Feb 2013 11:23:47 +0100 Subject: [PATCH 072/127] Remove package tag --- test/TestAsset/HydratorStrategyContextAware.php | 1 - 1 file changed, 1 deletion(-) diff --git a/test/TestAsset/HydratorStrategyContextAware.php b/test/TestAsset/HydratorStrategyContextAware.php index d879aff73..8400efd5a 100644 --- a/test/TestAsset/HydratorStrategyContextAware.php +++ b/test/TestAsset/HydratorStrategyContextAware.php @@ -5,7 +5,6 @@ * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License - * @package Zend_Stdlib */ namespace ZendTest\Stdlib\TestAsset; From 61ae84a9552456c71bb0ff606740446a356386b2 Mon Sep 17 00:00:00 2001 From: Mike Willbanks Date: Tue, 5 Feb 2013 07:37:00 -0800 Subject: [PATCH 073/127] 5.3.3 compatibility --- src/ArrayObject.php | 705 ++++++++++++++++++++------------------- test/ArrayObjectTest.php | 28 ++ 2 files changed, 385 insertions(+), 348 deletions(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index 381857c58..118da3ab5 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -9,410 +9,419 @@ namespace Zend\Stdlib; +use ArrayObject as PhpArrayObject; use IteratorAggregate; use ArrayAccess; use Serializable; use Countable; -/** - * ArrayObject - * This ArrayObject is a rewrite of the implementation to fix - * issues with php's implementation of ArrayObject where you - * are unable to unset multi-dimensional arrays because you - * need to fetch the properties / lists as references. - */ -class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable -{ - /** - * Properties of the object have their normal functionality - * when accessed as list (var_dump, foreach, etc.). - */ - const STD_PROP_LIST = 1; - - /** - * Entries can be accessed as properties (read and write). - */ - const ARRAY_AS_PROPS = 2; - - /** - * @var array - */ - protected $storage; - +// use our own version of arrayobject to handle references +if (version_compare(PHP_VERSION, '5.3.3') > 0) { /** - * @var int + * ArrayObject + * This ArrayObject is a rewrite of the implementation to fix + * issues with php's implementation of ArrayObject where you + * are unable to unset multi-dimensional arrays because you + * need to fetch the properties / lists as references. */ - protected $flag; - - /** - * @var string - */ - protected $iteratorClass; - - /** - * @var array - */ - protected $protectedProperties; - - /** - * Constructor - * - * @param array $input - * @param int $flags - * @param string $iteratorClass - * @return ArrayObject - */ - public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator') + class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable { - $this->setFlags($flags); - $this->storage = $input; - $this->setIteratorClass($iteratorClass); - $this->protectedProperties = array_keys(get_object_vars($this)); - } - - /** - * Returns whether the requested key exists - * - * @return boolean - */ - public function __isset($key) - { - if ($this->flag == self::ARRAY_AS_PROPS) { - return $this->offsetExists($key); - } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + /** + * Properties of the object have their normal functionality + * when accessed as list (var_dump, foreach, etc.). + */ + const STD_PROP_LIST = 1; + + /** + * Entries can be accessed as properties (read and write). + */ + const ARRAY_AS_PROPS = 2; + + /** + * @var array + */ + protected $storage; + + /** + * @var int + */ + protected $flag; + + /** + * @var string + */ + protected $iteratorClass; + + /** + * @var array + */ + protected $protectedProperties; + + /** + * Constructor + * + * @param array $input + * @param int $flags + * @param string $iteratorClass + * @return ArrayObject + */ + public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator') + { + $this->setFlags($flags); + $this->storage = $input; + $this->setIteratorClass($iteratorClass); + $this->protectedProperties = array_keys(get_object_vars($this)); } - return isset($this->$key); - } + /** + * Returns whether the requested key exists + * + * @return boolean + */ + public function __isset($key) + { + if ($this->flag == self::ARRAY_AS_PROPS) { + return $this->offsetExists($key); + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } - /** - * Sets the value at the specified key to value - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function __set($key, $value) - { - if ($this->flag == self::ARRAY_AS_PROPS) { - return $this->offsetSet($key, $value); - } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + return isset($this->$key); } - $this->$key = $value; - } - /** - * Unsets the value at the specified key - * - * @param mixed $key - * @return void - */ - public function __unset($key) - { - if ($this->flag == self::ARRAY_AS_PROPS) { - return $this->offsetUnset($key); + /** + * Sets the value at the specified key to value + * + * @param mixed $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + if ($this->flag == self::ARRAY_AS_PROPS) { + return $this->offsetSet($key, $value); + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } + $this->$key = $value; } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + + /** + * Unsets the value at the specified key + * + * @param mixed $key + * @return void + */ + public function __unset($key) + { + if ($this->flag == self::ARRAY_AS_PROPS) { + return $this->offsetUnset($key); + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } + unset($this->$key); } - unset($this->$key); - } - /** - * Returns the value at the specified key by reference - * - * @param mixed $key - * @return mixed - */ - public function &__get($key) - { - $ret = null; - if ($this->flag == self::ARRAY_AS_PROPS) { - $ret =& $this->offsetGet($key); + /** + * Returns the value at the specified key by reference + * + * @param mixed $key + * @return mixed + */ + public function &__get($key) + { + $ret = null; + if ($this->flag == self::ARRAY_AS_PROPS) { + $ret =& $this->offsetGet($key); + + return $ret; + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } - return $ret; + return $this->$key; } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + + /** + * Appends the value + * + * @param mixed $value + * @return void + */ + public function append($value) + { + $this->storage[] = $value; } - return $this->$key; - } + /** + * Sort the entries by value + * + * @return void + */ + public function asort() + { + asort($this->storage); + } - /** - * Appends the value - * - * @param mixed $value - * @return void - */ - public function append($value) - { - $this->storage[] = $value; - } + /** + * Get the number of public properties in the ArrayObject + * + * @return int + */ + public function count() + { + return count($this->storage); + } - /** - * Sort the entries by value - * - * @return void - */ - public function asort() - { - asort($this->storage); - } + /** + * Exchange the array for another one. + * + * @param array $data + * @return array + */ + public function exchangeArray(array $data) + { + $storage = $this->storage; - /** - * Get the number of public properties in the ArrayObject - * - * @return int - */ - public function count() - { - return count($this->storage); - } - - /** - * Exchange the array for another one. - * - * @param array $data - * @return array - */ - public function exchangeArray(array $data) - { - $storage = $this->storage; + $this->storage = $data; - $this->storage = $data; + return $storage; + } - return $storage; - } + /** + * Creates a copy of the ArrayObject. + * + * @return array + */ + public function getArrayCopy() + { + return $this->storage; + } - /** - * Creates a copy of the ArrayObject. - * - * @return array - */ - public function getArrayCopy() - { - return $this->storage; - } + /** + * Gets the behavior flags. + * + * @return int + */ + public function getFlags() + { + return $this->flag; + } - /** - * Gets the behavior flags. - * - * @return int - */ - public function getFlags() - { - return $this->flag; - } + /** + * Create a new iterator from an ArrayObject instance + * + * @return Iterator + */ + public function getIterator() + { + $class = $this->iteratorClass; - /** - * Create a new iterator from an ArrayObject instance - * - * @return Iterator - */ - public function getIterator() - { - $class = $this->iteratorClass; + return new $class($this->storage); + } - return new $class($this->storage); - } + /** + * Gets the iterator classname for the ArrayObject. + * + * @return string + */ + public function getIteratorClass() + { + return $this->iteratorClass; + } - /** - * Gets the iterator classname for the ArrayObject. - * - * @return string - */ - public function getIteratorClass() - { - return $this->iteratorClass; - } + /** + * Sort the entries by key + * + * @return void + */ + public function ksort() + { + ksort($this->storage); + } - /** - * Sort the entries by key - * - * @return void - */ - public function ksort() - { - ksort($this->storage); - } + /** + * Sort an array using a case insensitive "natural order" algorithm + * + * @return void + */ + public function natcasesort() + { + natcasesort($this->storage); + } - /** - * Sort an array using a case insensitive "natural order" algorithm - * - * @return void - */ - public function natcasesort() - { - natcasesort($this->storage); - } + /** + * Sort entries using a "natural order" algorithm + * + * @return void + */ + public function natsort() + { + natsort($this->storage); + } - /** - * Sort entries using a "natural order" algorithm - * - * @return void - */ - public function natsort() - { - natsort($this->storage); - } + /** + * Returns whether the requested key exists + * + * @return boolean + */ + public function offsetExists($key) + { + return isset($this->storage[$key]); + } - /** - * Returns whether the requested key exists - * - * @return boolean - */ - public function offsetExists($key) - { - return isset($this->storage[$key]); - } + /** + * Returns the value at the specified key + * + * @param mixed $key + * @return mixed + */ + public function &offsetGet($key) + { + $ret = null; + if (!$this->offsetExists($key)) { + return $ret; + } + $ret =& $this->storage[$key]; - /** - * Returns the value at the specified key - * - * @param mixed $key - * @return mixed - */ - public function &offsetGet($key) - { - $ret = null; - if (!$this->offsetExists($key)) { return $ret; } - $ret =& $this->storage[$key]; - - return $ret; - } - - /** - * Sets the value at the specified key to value - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function offsetSet($key, $value) - { - $this->storage[$key] = $value; - } - /** - * Unsets the value at the specified key - * - * @return void - */ - public function offsetUnset($key) - { - if ($this->offsetExists($key)) { - unset($this->storage[$key]); + /** + * Sets the value at the specified key to value + * + * @param mixed $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + $this->storage[$key] = $value; } - } - - /** - * Serialize an ArrayObject - * - * @return string - */ - public function serialize() - { - return serialize(get_object_vars($this)); - } - /** - * Sets the behavior flags - * - * @param int $flags - * @return void - */ - public function setFlags($flags) - { - $this->flag = $flags; - } + /** + * Unsets the value at the specified key + * + * @return void + */ + public function offsetUnset($key) + { + if ($this->offsetExists($key)) { + unset($this->storage[$key]); + } + } - /** - * Sets the iterator classname for the ArrayObject - * - * @param string $class - * @return void - */ - public function setIteratorClass($class) - { - if (class_exists($class)) { - $this->iteratorClass = $class; + /** + * Serialize an ArrayObject + * + * @return string + */ + public function serialize() + { + return serialize(get_object_vars($this)); + } - return ; + /** + * Sets the behavior flags + * + * @param int $flags + * @return void + */ + public function setFlags($flags) + { + $this->flag = $flags; } - if (strpos($class, '\\') === 0) { - $class = '\\' . $class; + /** + * Sets the iterator classname for the ArrayObject + * + * @param string $class + * @return void + */ + public function setIteratorClass($class) + { if (class_exists($class)) { $this->iteratorClass = $class; return ; } - } - throw new Exception\InvalidArgumentException('The iterator class does not exist'); - } + if (strpos($class, '\\') === 0) { + $class = '\\' . $class; + if (class_exists($class)) { + $this->iteratorClass = $class; - /** - * Sort the entries with a user-defined comparison function and maintain key association - * - * @param callable $function - * @return void - */ - public function uasort($function) - { - if (is_callable($function)) { - uasort($this->storage, $function); + return ; + } + } + + throw new Exception\InvalidArgumentException('The iterator class does not exist'); } - } - /** - * Sort the entries by keys using a user-defined comparison function - * - * @param callable $function - * @return void - */ - public function uksort($function) - { - if (is_callable($function)) { - uksort($this->storage, $function); + /** + * Sort the entries with a user-defined comparison function and maintain key association + * + * @param callable $function + * @return void + */ + public function uasort($function) + { + if (is_callable($function)) { + uasort($this->storage, $function); + } } - } - /** - * Unserialize an ArrayObject - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - $ar = unserialize($data); - $this->setFlags($ar['flag']); - $this->exchangeArray($ar['storage']); - $this->setIteratorClass($ar['iteratorClass']); - foreach ($ar as $k => $v) { - switch ($k) { - case 'flag': - $this->setFlags($v); - break; - case 'storage': - $this->exchangeArray($v); - break; - case 'iteratorClass': - $this->setIteratorClass($v); - break; - case 'protectedProperties': - continue; - default: - $this->__set($k, $v); + /** + * Sort the entries by keys using a user-defined comparison function + * + * @param callable $function + * @return void + */ + public function uksort($function) + { + if (is_callable($function)) { + uksort($this->storage, $function); + } + } + + /** + * Unserialize an ArrayObject + * + * @param string $data + * @return void + */ + public function unserialize($data) + { + $ar = unserialize($data); + $this->setFlags($ar['flag']); + $this->exchangeArray($ar['storage']); + $this->setIteratorClass($ar['iteratorClass']); + foreach ($ar as $k => $v) { + switch ($k) { + case 'flag': + $this->setFlags($v); + break; + case 'storage': + $this->exchangeArray($v); + break; + case 'iteratorClass': + $this->setIteratorClass($v); + break; + case 'protectedProperties': + continue; + default: + $this->__set($k, $v); + } } } } +} else { + class ArrayObject extends PhpArrayObject + { + + } } diff --git a/test/ArrayObjectTest.php b/test/ArrayObjectTest.php index 355133730..898a25054 100644 --- a/test/ArrayObjectTest.php +++ b/test/ArrayObjectTest.php @@ -53,6 +53,9 @@ public function testStdPropList() public function testStdPropListCannotAccessObjectVars() { + if (version_compare(PHP_VERSION, '5.3.3') <= 0) { + $this->markTestSkipped('Behavior is for overwritten ArrayObject in greater than 5.3.3'); + } $this->setExpectedException('InvalidArgumentException'); $ar = new ArrayObject(); $ar->flag; @@ -158,6 +161,9 @@ public function testIteratorClass() public function testInvalidIteratorClassThrowsInvalidArgumentException() { + if (version_compare(PHP_VERSION, '5.3.3') <= 0) { + $this->markTestSkipped('Behavior is for overwritten ArrayObject in greater than 5.3.3'); + } $this->setExpectedException('InvalidArgumentException'); $ar = new ArrayObject(array(), ArrayObject::STD_PROP_LIST, 'InvalidArrayIterator'); } @@ -203,6 +209,9 @@ public function testOffsetExists() public function testOffsetExistsThrowsExceptionOnProtectedProperty() { + if (version_compare(PHP_VERSION, '5.3.3') <= 0) { + $this->markTestSkipped('Behavior is for overwritten ArrayObject in greater than 5.3.3'); + } $this->setExpectedException('InvalidArgumentException'); $ar = new ArrayObject(); isset($ar->protectedProperties); @@ -222,6 +231,9 @@ public function testOffsetGetOffsetSet() public function testOffsetGetThrowsExceptionOnProtectedProperty() { + if (version_compare(PHP_VERSION, '5.3.3') <= 0) { + $this->markTestSkipped('Behavior is for overwritten ArrayObject in greater than 5.3.3'); + } $this->setExpectedException('InvalidArgumentException'); $ar = new ArrayObject(); $ar->protectedProperties; @@ -229,6 +241,9 @@ public function testOffsetGetThrowsExceptionOnProtectedProperty() public function testOffsetSetThrowsExceptionOnProtectedProperty() { + if (version_compare(PHP_VERSION, '5.3.3') <= 0) { + $this->markTestSkipped('Behavior is for overwritten ArrayObject in greater than 5.3.3'); + } $this->setExpectedException('InvalidArgumentException'); $ar = new ArrayObject(); $ar->protectedProperties = null; @@ -246,8 +261,21 @@ public function testOffsetUnset() $this->assertSame(array(), $ar->getArrayCopy()); } + public function testOffsetUnsetMultidimensional() + { + if (version_compare(PHP_VERSION, '5.3.3') <= 0) { + $this->markTestSkipped('Behavior is for overwritten ArrayObject in greater than 5.3.3'); + } + $ar = new ArrayObject(); + $ar['foo'] = array('bar' => array('baz' => 'boo')); + unset($ar['foo']['bar']['baz']); + } + public function testOffsetUnsetThrowsExceptionOnProtectedProperty() { + if (version_compare(PHP_VERSION, '5.3.3') <= 0) { + $this->markTestSkipped('Behavior is for overwritten ArrayObject in greater than 5.3.3'); + } $this->setExpectedException('InvalidArgumentException'); $ar = new ArrayObject(); unset($ar->protectedProperties); From a651809434aa5bb61f20cd368af8ce575d5eca33 Mon Sep 17 00:00:00 2001 From: Mike Willbanks Date: Tue, 5 Feb 2013 07:55:19 -0800 Subject: [PATCH 074/127] Resolved several unit test failures, more 5.3.3 compat, updated tests --- src/ArrayObject.php | 13 ++++++++++++- test/ArrayObjectTest.php | 10 +++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index 118da3ab5..987c97670 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -422,6 +422,17 @@ public function unserialize($data) } else { class ArrayObject extends PhpArrayObject { - + /** + * Constructor + * + * @param array $input + * @param int $flags + * @param string $iteratorClass + * @return ArrayObject + */ + public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator') + { + parent::__construct($input, $flags, $iteratorClass); + } } } diff --git a/test/ArrayObjectTest.php b/test/ArrayObjectTest.php index 898a25054..0a763ab6c 100644 --- a/test/ArrayObjectTest.php +++ b/test/ArrayObjectTest.php @@ -45,8 +45,8 @@ public function testStdPropList() $ar->bar = 'baz'; $this->assertSame('bar', $ar->foo); $this->assertSame('baz', $ar->bar); - $this->assertNull($ar['foo']); - $this->assertNull($ar['bar']); + $this->assertFalse(isset($ar['foo'])); + $this->assertFalse(isset($ar['bar'])); $this->assertEquals(0, $ar->count()); $this->assertSame(array(), $ar->getArrayCopy()); } @@ -225,8 +225,8 @@ public function testOffsetGetOffsetSet() $this->assertSame('bar', $ar['foo']); $this->assertSame('baz', $ar->bar); - $this->assertNull($ar->unknown); - $this->assertNull($ar['unknown']); + $this->assertFalse(isset($ar->unknown)); + $this->assertFalse(isset($ar['unknown'])); } public function testOffsetGetThrowsExceptionOnProtectedProperty() @@ -256,7 +256,7 @@ public function testOffsetUnset() $ar->bar = 'foo'; unset($ar['foo']); unset($ar->bar); - $this->assertNull($ar['foo']); + $this->assertFalse(isset($ar['foo'])); $this->assertNull($ar->bar); $this->assertSame(array(), $ar->getArrayCopy()); } From a75d062fbecc0322c1f2a8788e25cc6ce68290c4 Mon Sep 17 00:00:00 2001 From: Mike Willbanks Date: Tue, 5 Feb 2013 08:49:50 -0800 Subject: [PATCH 075/127] 5.3.3 compatibility for metadata, updated test from php arrayobject getiterator example --- test/ArrayObjectTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ArrayObjectTest.php b/test/ArrayObjectTest.php index 0a763ab6c..50fe2372a 100644 --- a/test/ArrayObjectTest.php +++ b/test/ArrayObjectTest.php @@ -142,7 +142,7 @@ public function testFlags() public function testIterator() { - $ar = new ArrayObject(array('one', 'two', 'three')); + $ar = new ArrayObject(array('1' => 'one', '2' => 'two', '3' => 'three')); $iterator = $ar->getIterator(); $this->assertEquals(new \ArrayIterator($ar->getArrayCopy()), $iterator); } @@ -257,7 +257,7 @@ public function testOffsetUnset() unset($ar['foo']); unset($ar->bar); $this->assertFalse(isset($ar['foo'])); - $this->assertNull($ar->bar); + $this->assertFalse(isset($ar->bar)); $this->assertSame(array(), $ar->getArrayCopy()); } From 8e522950fa7450d223a64bb1db64d067daf8ff67 Mon Sep 17 00:00:00 2001 From: Mike Willbanks Date: Tue, 5 Feb 2013 09:26:08 -0800 Subject: [PATCH 076/127] Resolved unit test failure --- src/ArrayObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index 987c97670..a1cfd8720 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -220,7 +220,7 @@ public function getFlags() public function getIterator() { $class = $this->iteratorClass; - + return new $class($this->storage); } From 493c0d8ced0a6fbcfa33b68ca1059c2315c31588 Mon Sep 17 00:00:00 2001 From: Mike Willbanks Date: Tue, 5 Feb 2013 09:43:32 -0800 Subject: [PATCH 077/127] Resolved last remaining unit test failure --- test/ArrayObjectTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/ArrayObjectTest.php b/test/ArrayObjectTest.php index 50fe2372a..41ebc4e8e 100644 --- a/test/ArrayObjectTest.php +++ b/test/ArrayObjectTest.php @@ -144,7 +144,8 @@ public function testIterator() { $ar = new ArrayObject(array('1' => 'one', '2' => 'two', '3' => 'three')); $iterator = $ar->getIterator(); - $this->assertEquals(new \ArrayIterator($ar->getArrayCopy()), $iterator); + $iterator2 = new \ArrayIterator($ar->getArrayCopy()); + $this->assertEquals($iterator2->getArrayCopy(), $iterator->getArrayCopy()); } public function testIteratorClass() From c42db0b064b48054a712f4b90aa980f36e156223 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Feb 2013 15:00:43 -0600 Subject: [PATCH 078/127] CS fixes - trailing whitespace --- src/ArrayObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index a1cfd8720..987c97670 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -220,7 +220,7 @@ public function getFlags() public function getIterator() { $class = $this->iteratorClass; - + return new $class($this->storage); } From e37f56ab3880ff6db69378bdbf53531c9c300bab Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 6 Feb 2013 11:32:34 -0600 Subject: [PATCH 079/127] [zendframework/zf2#3684] Fix indentation - Fixes docblock indentation in compat file --- src/compatibility/ArrayObject.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compatibility/ArrayObject.php b/src/compatibility/ArrayObject.php index 9a0018d5a..ec9316c55 100644 --- a/src/compatibility/ArrayObject.php +++ b/src/compatibility/ArrayObject.php @@ -22,13 +22,13 @@ class ArrayObject extends PhpArrayObject { /** - * Constructor - * - * @param array $input - * @param int $flags - * @param string $iteratorClass - * @return ArrayObject - */ + * Constructor + * + * @param array $input + * @param int $flags + * @param string $iteratorClass + * @return ArrayObject + */ public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator') { parent::__construct($input, $flags, $iteratorClass); From 6f6b6bc3d4a6e99042b96c5b938500a2b9d1c0a2 Mon Sep 17 00:00:00 2001 From: Gugu Mabuza Date: Sun, 17 Feb 2013 22:22:56 -0500 Subject: [PATCH 080/127] Update library/Zend/Stdlib/Hydrator/ClassMethods.php Formated according to formatting standars --- src/Hydrator/ClassMethods.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index bdbb053f1..6c30e231c 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -143,12 +143,12 @@ public function extract($object) } - if(property_exists($object, $attribute)) { - $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); - } else { - $attribute = lcfirst($attribute); - $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); - } + if(property_exists($object, $attribute)) { + $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); + } else { + $attribute = lcfirst($attribute); + $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); + } } return $attributes; From bdcb56bd2d7b62b960c705448613485e964b6576 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 19 Feb 2013 11:12:34 -0600 Subject: [PATCH 081/127] [zendframework/zf2#3580] Fix test failure - $object was not being passed to closure that used it --- src/Hydrator/ObjectProperty.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hydrator/ObjectProperty.php b/src/Hydrator/ObjectProperty.php index acff0359a..fe36d8828 100644 --- a/src/Hydrator/ObjectProperty.php +++ b/src/Hydrator/ObjectProperty.php @@ -32,7 +32,7 @@ public function extract($object) $self = $this; $data = get_object_vars($object); - array_walk($data, function (&$value, $name) use ($self, &$data) { + array_walk($data, function (&$value, $name) use ($self, &$data, $object) { if (!$self->getFilter()->filter($name)) { unset($data[$name]); } else { From 26edc746d56dd05b93b3b2056e31d1de83874991 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Mar 2013 11:19:58 -0600 Subject: [PATCH 082/127] Reworked polyfill support for Zend\Stdlib\ArrayObject - Instead of using an autoload file, instead created two separate classes, named after the type of support they provide. The file Zend\Stdlib\ArrayObject now simply has a conditional in it; based on the condition met, a class_alias() is created -- and from then on, that alias will be used for Zend\Stdlib\ArrayObject. - Removed autoload.files entries from composer.json files; no longer necessary. - One test failure currently in doing a comparison of merged array objects; will investigate in a later commit. --- src/ArrayObject.php | 434 +----------------- .../PhpLegacyCompatibility.php} | 4 +- src/ArrayObject/PhpReferenceCompatibility.php | 434 ++++++++++++++++++ src/compatibility/autoload.php | 6 - 4 files changed, 449 insertions(+), 429 deletions(-) rename src/{compatibility/ArrayObject.php => ArrayObject/PhpLegacyCompatibility.php} (91%) create mode 100644 src/ArrayObject/PhpReferenceCompatibility.php delete mode 100644 src/compatibility/autoload.php diff --git a/src/ArrayObject.php b/src/ArrayObject.php index ec3ef0723..3d5f21135 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -7,427 +7,19 @@ * @license http://framework.zend.com/license/new-bsd New BSD License */ -namespace Zend\Stdlib; - -use IteratorAggregate; -use ArrayAccess; -use Serializable; -use Countable; - /** - * ArrayObject - * - * This ArrayObject is a rewrite of the implementation to fix - * issues with php's implementation of ArrayObject where you - * are unable to unset multi-dimensional arrays because you - * need to fetch the properties / lists as references. + * If the version is less than 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpLegacyCompatibility + * which extend sthe native PHP ArrayObject implementation. For versions greater than or equal + * to 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpReferenceCompatibility, which corrects + * issues with how PHP handles references inside ArrayObject. + * + * class_alias is a global construct, so we can alias either one to Zend\Stdlib\ArrayObject, + * and from this point forward, that alias will be used. */ -class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable -{ - /** - * Properties of the object have their normal functionality - * when accessed as list (var_dump, foreach, etc.). - */ - const STD_PROP_LIST = 1; - - /** - * Entries can be accessed as properties (read and write). - */ - const ARRAY_AS_PROPS = 2; - - /** - * @var array - */ - protected $storage; - - /** - * @var int - */ - protected $flag; - - /** - * @var string - */ - protected $iteratorClass; - - /** - * @var array - */ - protected $protectedProperties; - - /** - * Constructor - * - * @param array $input - * @param int $flags - * @param string $iteratorClass - * @return ArrayObject - */ - public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator') - { - $this->setFlags($flags); - $this->storage = $input; - $this->setIteratorClass($iteratorClass); - $this->protectedProperties = array_keys(get_object_vars($this)); - } - - /** - * Returns whether the requested key exists - * - * @param mixed $key - * @return boolean - */ - public function __isset($key) - { - if ($this->flag == self::ARRAY_AS_PROPS) { - return $this->offsetExists($key); - } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); - } - - return isset($this->$key); - } - - /** - * Sets the value at the specified key to value - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function __set($key, $value) - { - if ($this->flag == self::ARRAY_AS_PROPS) { - return $this->offsetSet($key, $value); - } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); - } - $this->$key = $value; - } - - /** - * Unsets the value at the specified key - * - * @param mixed $key - * @return void - */ - public function __unset($key) - { - if ($this->flag == self::ARRAY_AS_PROPS) { - return $this->offsetUnset($key); - } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); - } - unset($this->$key); - } - - /** - * Returns the value at the specified key by reference - * - * @param mixed $key - * @return mixed - */ - public function &__get($key) - { - $ret = null; - if ($this->flag == self::ARRAY_AS_PROPS) { - $ret =& $this->offsetGet($key); - - return $ret; - } - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); - } - - return $this->$key; - } - - /** - * Appends the value - * - * @param mixed $value - * @return void - */ - public function append($value) - { - $this->storage[] = $value; - } - - /** - * Sort the entries by value - * - * @return void - */ - public function asort() - { - asort($this->storage); - } - - /** - * Get the number of public properties in the ArrayObject - * - * @return int - */ - public function count() - { - return count($this->storage); - } - - /** - * Exchange the array for another one. - * - * @param array|ArrayObject $data - * @return array - */ - public function exchangeArray($data) - { - if (!is_array($data) && !is_object($data)) { - throw new Exception\InvalidArgumentException('Passed variable is not an array or object, using empty array instead'); - } - - if (is_object($data) && ($data instanceof ArrayObject || $data instanceof \ArrayObject)) { - $data = $data->getArrayCopy(); - } - if (!is_array($data)) { - $data = (array) $data; - } - - $storage = $this->storage; - - $this->storage = $data; - - return $storage; - } - - /** - * Creates a copy of the ArrayObject. - * - * @return array - */ - public function getArrayCopy() - { - return $this->storage; - } - - /** - * Gets the behavior flags. - * - * @return int - */ - public function getFlags() - { - return $this->flag; - } - - /** - * Create a new iterator from an ArrayObject instance - * - * @return \Iterator - */ - public function getIterator() - { - $class = $this->iteratorClass; - - return new $class($this->storage); - } - - /** - * Gets the iterator classname for the ArrayObject. - * - * @return string - */ - public function getIteratorClass() - { - return $this->iteratorClass; - } - - /** - * Sort the entries by key - * - * @return void - */ - public function ksort() - { - ksort($this->storage); - } - - /** - * Sort an array using a case insensitive "natural order" algorithm - * - * @return void - */ - public function natcasesort() - { - natcasesort($this->storage); - } - - /** - * Sort entries using a "natural order" algorithm - * - * @return void - */ - public function natsort() - { - natsort($this->storage); - } - - /** - * Returns whether the requested key exists - * - * @param mixed $key - * @return boolean - */ - public function offsetExists($key) - { - return isset($this->storage[$key]); - } - - /** - * Returns the value at the specified key - * - * @param mixed $key - * @return mixed - */ - public function &offsetGet($key) - { - $ret = null; - if (!$this->offsetExists($key)) { - return $ret; - } - $ret =& $this->storage[$key]; - - return $ret; - } - - /** - * Sets the value at the specified key to value - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function offsetSet($key, $value) - { - $this->storage[$key] = $value; - } - - /** - * Unsets the value at the specified key - * - * @param mixed $key - * @return void - */ - public function offsetUnset($key) - { - if ($this->offsetExists($key)) { - unset($this->storage[$key]); - } - } - - /** - * Serialize an ArrayObject - * - * @return string - */ - public function serialize() - { - return serialize(get_object_vars($this)); - } - - /** - * Sets the behavior flags - * - * @param int $flags - * @return void - */ - public function setFlags($flags) - { - $this->flag = $flags; - } - - /** - * Sets the iterator classname for the ArrayObject - * - * @param string $class - * @return void - */ - public function setIteratorClass($class) - { - if (class_exists($class)) { - $this->iteratorClass = $class; - - return ; - } - - if (strpos($class, '\\') === 0) { - $class = '\\' . $class; - if (class_exists($class)) { - $this->iteratorClass = $class; - - return ; - } - } - - throw new Exception\InvalidArgumentException('The iterator class does not exist'); - } - - /** - * Sort the entries with a user-defined comparison function and maintain key association - * - * @param callable $function - * @return void - */ - public function uasort($function) - { - if (is_callable($function)) { - uasort($this->storage, $function); - } - } - - /** - * Sort the entries by keys using a user-defined comparison function - * - * @param callable $function - * @return void - */ - public function uksort($function) - { - if (is_callable($function)) { - uksort($this->storage, $function); - } - } - - /** - * Unserialize an ArrayObject - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - $ar = unserialize($data); - $this->setFlags($ar['flag']); - $this->exchangeArray($ar['storage']); - $this->setIteratorClass($ar['iteratorClass']); - foreach ($ar as $k => $v) { - switch ($k) { - case 'flag': - $this->setFlags($v); - break; - case 'storage': - $this->exchangeArray($v); - break; - case 'iteratorClass': - $this->setIteratorClass($v); - break; - case 'protectedProperties': - continue; - default: - $this->__set($k, $v); - } - } - } +if (version_compare(PHP_VERSION, '5.3.4', 'lt') + && !class_exists('Zend\Stdlib\ArrayObject', false) +) { + class_alias('Zend\Stdlib\ArrayObject\PhpLegacyCompatibility', 'Zend\Stdlib\ArrayObject'); +} else { + class_alias('Zend\Stdlib\ArrayObject\PhpReferenceCompatibility', 'Zend\Stdlib\ArrayObject'); } diff --git a/src/compatibility/ArrayObject.php b/src/ArrayObject/PhpLegacyCompatibility.php similarity index 91% rename from src/compatibility/ArrayObject.php rename to src/ArrayObject/PhpLegacyCompatibility.php index ec9316c55..70aa858ed 100644 --- a/src/compatibility/ArrayObject.php +++ b/src/ArrayObject/PhpLegacyCompatibility.php @@ -7,7 +7,7 @@ * @license http://framework.zend.com/license/new-bsd New BSD License */ -namespace Zend\Stdlib; +namespace Zend\Stdlib\ArrayObject; use ArrayObject as PhpArrayObject; @@ -19,7 +19,7 @@ * simply extends the PHP ArrayObject implementation, and provides default * behavior in the constructor. */ -class ArrayObject extends PhpArrayObject +class PhpLegacyCompatibility extends PhpArrayObject { /** * Constructor diff --git a/src/ArrayObject/PhpReferenceCompatibility.php b/src/ArrayObject/PhpReferenceCompatibility.php new file mode 100644 index 000000000..4aa5febc7 --- /dev/null +++ b/src/ArrayObject/PhpReferenceCompatibility.php @@ -0,0 +1,434 @@ +setFlags($flags); + $this->storage = $input; + $this->setIteratorClass($iteratorClass); + $this->protectedProperties = array_keys(get_object_vars($this)); + } + + /** + * Returns whether the requested key exists + * + * @param mixed $key + * @return boolean + */ + public function __isset($key) + { + if ($this->flag == self::ARRAY_AS_PROPS) { + return $this->offsetExists($key); + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } + + return isset($this->$key); + } + + /** + * Sets the value at the specified key to value + * + * @param mixed $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + if ($this->flag == self::ARRAY_AS_PROPS) { + return $this->offsetSet($key, $value); + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } + $this->$key = $value; + } + + /** + * Unsets the value at the specified key + * + * @param mixed $key + * @return void + */ + public function __unset($key) + { + if ($this->flag == self::ARRAY_AS_PROPS) { + return $this->offsetUnset($key); + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } + unset($this->$key); + } + + /** + * Returns the value at the specified key by reference + * + * @param mixed $key + * @return mixed + */ + public function &__get($key) + { + $ret = null; + if ($this->flag == self::ARRAY_AS_PROPS) { + $ret =& $this->offsetGet($key); + + return $ret; + } + if (in_array($key, $this->protectedProperties)) { + throw new Exception\InvalidArgumentException('$key is a protected property, use a different key'); + } + + return $this->$key; + } + + /** + * Appends the value + * + * @param mixed $value + * @return void + */ + public function append($value) + { + $this->storage[] = $value; + } + + /** + * Sort the entries by value + * + * @return void + */ + public function asort() + { + asort($this->storage); + } + + /** + * Get the number of public properties in the ArrayObject + * + * @return int + */ + public function count() + { + return count($this->storage); + } + + /** + * Exchange the array for another one. + * + * @param array|ArrayObject $data + * @return array + */ + public function exchangeArray($data) + { + if (!is_array($data) && !is_object($data)) { + throw new Exception\InvalidArgumentException('Passed variable is not an array or object, using empty array instead'); + } + + if (is_object($data) && ($data instanceof ArrayObject || $data instanceof \ArrayObject)) { + $data = $data->getArrayCopy(); + } + if (!is_array($data)) { + $data = (array) $data; + } + + $storage = $this->storage; + + $this->storage = $data; + + return $storage; + } + + /** + * Creates a copy of the ArrayObject. + * + * @return array + */ + public function getArrayCopy() + { + return $this->storage; + } + + /** + * Gets the behavior flags. + * + * @return int + */ + public function getFlags() + { + return $this->flag; + } + + /** + * Create a new iterator from an ArrayObject instance + * + * @return \Iterator + */ + public function getIterator() + { + $class = $this->iteratorClass; + + return new $class($this->storage); + } + + /** + * Gets the iterator classname for the ArrayObject. + * + * @return string + */ + public function getIteratorClass() + { + return $this->iteratorClass; + } + + /** + * Sort the entries by key + * + * @return void + */ + public function ksort() + { + ksort($this->storage); + } + + /** + * Sort an array using a case insensitive "natural order" algorithm + * + * @return void + */ + public function natcasesort() + { + natcasesort($this->storage); + } + + /** + * Sort entries using a "natural order" algorithm + * + * @return void + */ + public function natsort() + { + natsort($this->storage); + } + + /** + * Returns whether the requested key exists + * + * @param mixed $key + * @return boolean + */ + public function offsetExists($key) + { + return isset($this->storage[$key]); + } + + /** + * Returns the value at the specified key + * + * @param mixed $key + * @return mixed + */ + public function &offsetGet($key) + { + $ret = null; + if (!$this->offsetExists($key)) { + return $ret; + } + $ret =& $this->storage[$key]; + + return $ret; + } + + /** + * Sets the value at the specified key to value + * + * @param mixed $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + $this->storage[$key] = $value; + } + + /** + * Unsets the value at the specified key + * + * @param mixed $key + * @return void + */ + public function offsetUnset($key) + { + if ($this->offsetExists($key)) { + unset($this->storage[$key]); + } + } + + /** + * Serialize an ArrayObject + * + * @return string + */ + public function serialize() + { + return serialize(get_object_vars($this)); + } + + /** + * Sets the behavior flags + * + * @param int $flags + * @return void + */ + public function setFlags($flags) + { + $this->flag = $flags; + } + + /** + * Sets the iterator classname for the ArrayObject + * + * @param string $class + * @return void + */ + public function setIteratorClass($class) + { + if (class_exists($class)) { + $this->iteratorClass = $class; + + return ; + } + + if (strpos($class, '\\') === 0) { + $class = '\\' . $class; + if (class_exists($class)) { + $this->iteratorClass = $class; + + return ; + } + } + + throw new Exception\InvalidArgumentException('The iterator class does not exist'); + } + + /** + * Sort the entries with a user-defined comparison function and maintain key association + * + * @param callable $function + * @return void + */ + public function uasort($function) + { + if (is_callable($function)) { + uasort($this->storage, $function); + } + } + + /** + * Sort the entries by keys using a user-defined comparison function + * + * @param callable $function + * @return void + */ + public function uksort($function) + { + if (is_callable($function)) { + uksort($this->storage, $function); + } + } + + /** + * Unserialize an ArrayObject + * + * @param string $data + * @return void + */ + public function unserialize($data) + { + $ar = unserialize($data); + $this->setFlags($ar['flag']); + $this->exchangeArray($ar['storage']); + $this->setIteratorClass($ar['iteratorClass']); + foreach ($ar as $k => $v) { + switch ($k) { + case 'flag': + $this->setFlags($v); + break; + case 'storage': + $this->exchangeArray($v); + break; + case 'iteratorClass': + $this->setIteratorClass($v); + break; + case 'protectedProperties': + continue; + default: + $this->__set($k, $v); + } + } + } +} diff --git a/src/compatibility/autoload.php b/src/compatibility/autoload.php deleted file mode 100644 index fc6c3974a..000000000 --- a/src/compatibility/autoload.php +++ /dev/null @@ -1,6 +0,0 @@ - Date: Tue, 5 Mar 2013 11:43:25 -0600 Subject: [PATCH 083/127] Solved failing test in ArrayObject tests - changed a typehint from "ArrayObject" to "self" --- src/ArrayObject/PhpReferenceCompatibility.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArrayObject/PhpReferenceCompatibility.php b/src/ArrayObject/PhpReferenceCompatibility.php index 4aa5febc7..b5fa3422f 100644 --- a/src/ArrayObject/PhpReferenceCompatibility.php +++ b/src/ArrayObject/PhpReferenceCompatibility.php @@ -189,7 +189,7 @@ public function exchangeArray($data) throw new Exception\InvalidArgumentException('Passed variable is not an array or object, using empty array instead'); } - if (is_object($data) && ($data instanceof ArrayObject || $data instanceof \ArrayObject)) { + if (is_object($data) && ($data instanceof self || $data instanceof \ArrayObject)) { $data = $data->getArrayCopy(); } if (!is_array($data)) { From a6da63949d1e2df15b9c65029460231bea732630 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Mar 2013 11:59:24 -0600 Subject: [PATCH 084/127] Re-added autoload.php files - BC measure, so that code referencing these files doesn't break --- src/autoload.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/autoload.php diff --git a/src/autoload.php b/src/autoload.php new file mode 100644 index 000000000..2c4e31e83 --- /dev/null +++ b/src/autoload.php @@ -0,0 +1,12 @@ + Date: Tue, 5 Mar 2013 12:05:03 -0600 Subject: [PATCH 085/127] Fix typo - per @DASPRiD --- src/ArrayObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index 3d5f21135..a1d6961a7 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -9,7 +9,7 @@ /** * If the version is less than 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpLegacyCompatibility - * which extend sthe native PHP ArrayObject implementation. For versions greater than or equal + * which extends the native PHP ArrayObject implementation. For versions greater than or equal * to 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpReferenceCompatibility, which corrects * issues with how PHP handles references inside ArrayObject. * From e9352f52fe1e372c1742f0e487d64fb59f039381 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Mar 2013 15:04:43 -0600 Subject: [PATCH 086/127] Renamed compat autoload files and marked as deprecated - moved autoload.php files into compatibility subdirs where they belong - marked each with @deprecated annotation --- src/{ => compatibility}/autoload.php | 1 + 1 file changed, 1 insertion(+) rename src/{ => compatibility}/autoload.php (96%) diff --git a/src/autoload.php b/src/compatibility/autoload.php similarity index 96% rename from src/autoload.php rename to src/compatibility/autoload.php index 2c4e31e83..a52e30f48 100644 --- a/src/autoload.php +++ b/src/compatibility/autoload.php @@ -5,6 +5,7 @@ * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License + * @deprecated */ /** From 669123ae9b9a678fb854a7aa2d218377a2addfc7 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Mar 2013 15:08:46 -0600 Subject: [PATCH 087/127] Remove class_exists check - bad cut-and-paste --- src/ArrayObject.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index a1d6961a7..afa632b5b 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -16,9 +16,7 @@ * class_alias is a global construct, so we can alias either one to Zend\Stdlib\ArrayObject, * and from this point forward, that alias will be used. */ -if (version_compare(PHP_VERSION, '5.3.4', 'lt') - && !class_exists('Zend\Stdlib\ArrayObject', false) -) { +if (version_compare(PHP_VERSION, '5.3.4', 'lt')) { class_alias('Zend\Stdlib\ArrayObject\PhpLegacyCompatibility', 'Zend\Stdlib\ArrayObject'); } else { class_alias('Zend\Stdlib\ArrayObject\PhpReferenceCompatibility', 'Zend\Stdlib\ArrayObject'); From 4eea76f704c89f63694646a3a27f251874e44635 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Mar 2013 15:37:14 -0600 Subject: [PATCH 088/127] Fake scanners out - Use __halt_compiler(), and then define stub class, in order to trick classmap compilers into thinking a class exists. --- src/ArrayObject.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index afa632b5b..ee5c8e223 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -7,12 +7,14 @@ * @license http://framework.zend.com/license/new-bsd New BSD License */ +namespace Zend\Stdlib; + /** * If the version is less than 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpLegacyCompatibility * which extends the native PHP ArrayObject implementation. For versions greater than or equal * to 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpReferenceCompatibility, which corrects * issues with how PHP handles references inside ArrayObject. - * + * * class_alias is a global construct, so we can alias either one to Zend\Stdlib\ArrayObject, * and from this point forward, that alias will be used. */ @@ -21,3 +23,9 @@ class_alias('Zend\Stdlib\ArrayObject\PhpLegacyCompatibility', 'Zend\Stdlib\Array } else { class_alias('Zend\Stdlib\ArrayObject\PhpReferenceCompatibility', 'Zend\Stdlib\ArrayObject'); } + +__halt_compiler(); + +class ArrayObject extends \ArrayObject +{ +} From 967adce305ac8650fe7a9c049ecc57c0b147a504 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Mar 2013 15:56:45 -0600 Subject: [PATCH 089/127] Class stubs to force classmap generation --- src/ArrayObject.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index ee5c8e223..21fa5bdd9 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -26,6 +26,9 @@ class_alias('Zend\Stdlib\ArrayObject\PhpReferenceCompatibility', 'Zend\Stdlib\Ar __halt_compiler(); +/** + * Class stub to force classmap generation + */ class ArrayObject extends \ArrayObject { } From bb6593dba4539dbe4afa14cd50f00c23dc6513bd Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 5 Mar 2013 17:18:34 -0600 Subject: [PATCH 090/127] Trigger E_USER_DEPRECATED in deprecated polyfill autoload files --- src/compatibility/autoload.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compatibility/autoload.php b/src/compatibility/autoload.php index a52e30f48..cfc569626 100644 --- a/src/compatibility/autoload.php +++ b/src/compatibility/autoload.php @@ -11,3 +11,4 @@ /** * Legacy purposes only, to prevent code that references it from breaking. */ +trigger_error('Polyfill autoload support (file library/Zend/Stdlib/compatibility/autoload.php) is no longer necessary; please remove your require statement referencing this file', E_USER_DEPRECATED); From ad5bea179ca5cb620c1f5b87cd9a05421637bcc8 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 6 Mar 2013 06:23:17 -0600 Subject: [PATCH 091/127] Simpler polyfill support - Have a base class that extends a polyfill class - makes classmap generation simpler - makes typehinting and mock objects simpler --- src/ArrayObject.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ArrayObject.php b/src/ArrayObject.php index 21fa5bdd9..806c128fc 100644 --- a/src/ArrayObject.php +++ b/src/ArrayObject.php @@ -19,16 +19,16 @@ * and from this point forward, that alias will be used. */ if (version_compare(PHP_VERSION, '5.3.4', 'lt')) { - class_alias('Zend\Stdlib\ArrayObject\PhpLegacyCompatibility', 'Zend\Stdlib\ArrayObject'); + class_alias('Zend\Stdlib\ArrayObject\PhpLegacyCompatibility', 'Zend\Stdlib\AbstractArrayObject'); } else { - class_alias('Zend\Stdlib\ArrayObject\PhpReferenceCompatibility', 'Zend\Stdlib\ArrayObject'); + class_alias('Zend\Stdlib\ArrayObject\PhpReferenceCompatibility', 'Zend\Stdlib\AbstractArrayObject'); } -__halt_compiler(); - /** - * Class stub to force classmap generation + * Custom framework ArrayObject implementation + * + * Extends version-specific "abstract" implementation. */ -class ArrayObject extends \ArrayObject +class ArrayObject extends AbstractArrayObject { } From a5811ab08709f213be4c3bcdcd3e1157b961ad61 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 6 Mar 2013 06:34:18 -0600 Subject: [PATCH 092/127] Mark all polyfill bases as abstract - they are not intended to be instantiated directly; they are intended as bases for the typehinted class that uses the polyfills. --- src/ArrayObject/PhpLegacyCompatibility.php | 2 +- src/ArrayObject/PhpReferenceCompatibility.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ArrayObject/PhpLegacyCompatibility.php b/src/ArrayObject/PhpLegacyCompatibility.php index 70aa858ed..4d0f44d47 100644 --- a/src/ArrayObject/PhpLegacyCompatibility.php +++ b/src/ArrayObject/PhpLegacyCompatibility.php @@ -19,7 +19,7 @@ * simply extends the PHP ArrayObject implementation, and provides default * behavior in the constructor. */ -class PhpLegacyCompatibility extends PhpArrayObject +abstract class PhpLegacyCompatibility extends PhpArrayObject { /** * Constructor diff --git a/src/ArrayObject/PhpReferenceCompatibility.php b/src/ArrayObject/PhpReferenceCompatibility.php index b5fa3422f..9e680abbf 100644 --- a/src/ArrayObject/PhpReferenceCompatibility.php +++ b/src/ArrayObject/PhpReferenceCompatibility.php @@ -23,7 +23,7 @@ * are unable to unset multi-dimensional arrays because you * need to fetch the properties / lists as references. */ -class PhpReferenceCompatibility implements IteratorAggregate, ArrayAccess, Serializable, Countable +abstract class PhpReferenceCompatibility implements IteratorAggregate, ArrayAccess, Serializable, Countable { /** * Properties of the object have their normal functionality From eaa1e5aa083f1a9c64ef735ec9ae2178bda14087 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 7 Mar 2013 09:36:02 -0600 Subject: [PATCH 093/127] [zendframework/zf2#3984] Import ArrayObject as PhpArrayObject - and update class declaration to extend PhpArrayObject --- src/ArrayStack.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ArrayStack.php b/src/ArrayStack.php index 29d64ce9c..559d65e3f 100644 --- a/src/ArrayStack.php +++ b/src/ArrayStack.php @@ -10,12 +10,12 @@ namespace Zend\Stdlib; use ArrayIterator; -use Zend\Stdlib\ArrayObject; +use ArrayObject as PhpArrayObject; /** * ArrayObject that acts as a stack with regards to iteration */ -class ArrayStack extends ArrayObject +class ArrayStack extends PhpArrayObject { /** * Retrieve iterator From 3efb86f985dda79c4910facd513089dc92ac1b2e Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 12 Mar 2013 11:01:10 -0500 Subject: [PATCH 094/127] [zendframework/zf2#3951] Add error handler for deprecation warning - Added an error handler to catch the deprecation warning now emitted by Zend\Stdlib\DateTime --- test/DateTimeTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/DateTimeTest.php b/test/DateTimeTest.php index f6c2e0553..7f4cfa00b 100644 --- a/test/DateTimeTest.php +++ b/test/DateTimeTest.php @@ -22,6 +22,16 @@ class DateTimeTest extends \PHPUnit_Framework_TestCase { public $dateTime; + public function setUp() + { + set_error_handler(function ($errno, $errstr) { + if (!stristr($errstr, 'datetime extension deprecated')) { + return false; + } + return true; + }, E_USER_DEPRECATED); + } + public function testCreatesIS08601WithoutFractionalSeconds() { $time = '2009-03-07T08:03:50Z'; From 41e2d7b437a6cddecfa6350eda4d8b347364fb9f Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 10 Apr 2013 07:20:50 +0200 Subject: [PATCH 095/127] fixed typo --- src/AbstractOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AbstractOptions.php b/src/AbstractOptions.php index 8bea3fb9b..47235f2c9 100644 --- a/src/AbstractOptions.php +++ b/src/AbstractOptions.php @@ -81,7 +81,7 @@ public function toArray() } /** - * Set a configuration properties + * Set a configuration property * * @see ParameterObject::__set() * @param string $key From a93ba3995cb85b787214f679b21fe38f0ef4b1e3 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 12 Apr 2013 14:25:33 -0500 Subject: [PATCH 096/127] [zendframework/zf2#4203] CS fixes - per php-cs-fixer --- src/AbstractOptions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AbstractOptions.php b/src/AbstractOptions.php index 47235f2c9..0e68c29e1 100644 --- a/src/AbstractOptions.php +++ b/src/AbstractOptions.php @@ -159,4 +159,3 @@ public function __unset($key) } } } - From f1fabb0ffd9aafcec4ef1565bcbc5f40c48212bd Mon Sep 17 00:00:00 2001 From: brian978 Date: Sat, 13 Apr 2013 00:02:10 +0300 Subject: [PATCH 097/127] Added unit tests for the ClassMethods::hydrator() method to test the change from method_exists() to is_callable() --- test/HydratorTest.php | 22 ++++++++++++ .../ClassMethodsMagicMethodSetter.php | 28 +++++++++++++++ .../TestAsset/ClassMethodsProtectedSetter.php | 36 +++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 test/TestAsset/ClassMethodsMagicMethodSetter.php create mode 100644 test/TestAsset/ClassMethodsProtectedSetter.php diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 69cd24784..2baca1e47 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -17,6 +17,8 @@ use Zend\Stdlib\Hydrator\Filter\FilterComposite; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCase; use ZendTest\Stdlib\TestAsset\ClassMethodsFilterProviderInterface; +use ZendTest\Stdlib\TestAsset\ClassMethodsMagicMethodSetter; +use ZendTest\Stdlib\TestAsset\ClassMethodsProtectedSetter; use ZendTest\Stdlib\TestAsset\ClassMethodsUnderscore; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCaseMissing; use ZendTest\Stdlib\TestAsset\ClassMethodsInvalidParameter; @@ -397,4 +399,24 @@ public function testObjectBasedFilters() $this->assertSame("bar", $data["foo"]); $this->assertSame("foo", $data["bar"]); } + + public function testHydratorClassMethodsWithProtectedSetter() + { + $hydrator = new ClassMethods(false); + $object = new ClassMethodsProtectedSetter(); + $hydrator->hydrate(array('foo' => 'bar', 'bar' => 'BAR'), $object); + $data = $hydrator->extract($object); + + $this->assertEquals($data['bar'], 'BAR'); + } + + public function testHydratorClassMethodsWithMagicMethodSetter() + { + $hydrator = new ClassMethods(false); + $object = new ClassMethodsMagicMethodSetter(); + $hydrator->hydrate(array('foo' => 'bar'), $object); + $data = $hydrator->extract($object); + + $this->assertEquals($data['foo'], 'bar'); + } } diff --git a/test/TestAsset/ClassMethodsMagicMethodSetter.php b/test/TestAsset/ClassMethodsMagicMethodSetter.php new file mode 100644 index 000000000..b1f936b38 --- /dev/null +++ b/test/TestAsset/ClassMethodsMagicMethodSetter.php @@ -0,0 +1,28 @@ + 3 && strtolower(substr($method, 3)) == 'foo') + { + $this->foo = $args[0]; + } + } + + public function getFoo() + { + return $this->foo; + } +} \ No newline at end of file diff --git a/test/TestAsset/ClassMethodsProtectedSetter.php b/test/TestAsset/ClassMethodsProtectedSetter.php new file mode 100644 index 000000000..97bcfa85e --- /dev/null +++ b/test/TestAsset/ClassMethodsProtectedSetter.php @@ -0,0 +1,36 @@ +foo = $foo; + } + + public function setBar($bar) + { + $this->bar = $bar; + } + + public function getFoo() + { + return $this->foo; + } + + public function getBar() + { + return $this->bar; + } +} \ No newline at end of file From fd4de0787707198da4a4bcc5c9d10a4e759b3d1e Mon Sep 17 00:00:00 2001 From: brian978 Date: Sat, 13 Apr 2013 00:07:01 +0300 Subject: [PATCH 098/127] Removed method from the ClassMethodsProtectedSetter TestAsset because it's not required in the tests --- test/TestAsset/ClassMethodsProtectedSetter.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/TestAsset/ClassMethodsProtectedSetter.php b/test/TestAsset/ClassMethodsProtectedSetter.php index 97bcfa85e..09176369f 100644 --- a/test/TestAsset/ClassMethodsProtectedSetter.php +++ b/test/TestAsset/ClassMethodsProtectedSetter.php @@ -24,11 +24,6 @@ public function setBar($bar) $this->bar = $bar; } - public function getFoo() - { - return $this->foo; - } - public function getBar() { return $this->bar; From dbd8eaf5aa5191e5f092346b73fcd686d578ae62 Mon Sep 17 00:00:00 2001 From: "Mabuza, Gugu" Date: Sat, 13 Apr 2013 21:38:53 -0400 Subject: [PATCH 099/127] Fixing classMethods Hydrator to work for TitleCase properties --- src/Hydrator/ClassMethods.php | 16 ++++------- test/HydratorTest.php | 54 ++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 6c30e231c..942133d14 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -136,19 +136,15 @@ public function extract($object) $attribute = $method; if (preg_match('/^get/', $method)) { $attribute = substr($method, 3); + if(!property_exists($object, $attribute)) { + $attribute = lcfirst($attribute); + } } if ($this->underscoreSeparatedKeys) { $attribute = preg_replace_callback('/([A-Z])/', $transform, $attribute); - } - - - if(property_exists($object, $attribute)) { - $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); - } else { - $attribute = lcfirst($attribute); - $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); - } + } + $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); } return $attributes; @@ -193,4 +189,4 @@ public function hydrate(array $data, $object) return $object; } -} +} \ No newline at end of file diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 1c6938185..19e3b97c8 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -16,6 +16,7 @@ use Zend\Stdlib\Hydrator\ArraySerializable; use Zend\Stdlib\Hydrator\Filter\FilterComposite; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCase; +use ZendTest\Stdlib\TestAsset\ClassMethodsTitleCase; use ZendTest\Stdlib\TestAsset\ClassMethodsFilterProviderInterface; use ZendTest\Stdlib\TestAsset\ClassMethodsUnderscore; use ZendTest\Stdlib\TestAsset\ClassMethodsCamelCaseMissing; @@ -41,6 +42,11 @@ class HydratorTest extends \PHPUnit_Framework_TestCase * @var ClassMethodsCamelCase */ protected $classMethodsCamelCase; + + /** + * @var ClassMethodsTitleCase + */ + protected $classMethodsTitleCase; /** * @var ClassMethodsCamelCaseMissing @@ -65,6 +71,7 @@ class HydratorTest extends \PHPUnit_Framework_TestCase public function setUp() { $this->classMethodsCamelCase = new ClassMethodsCamelCase(); + $this->classMethodsTitleCase = new ClassMethodsTitleCase(); $this->classMethodsCamelCaseMissing = new ClassMethodsCamelCaseMissing(); $this->classMethodsUnderscore = new ClassMethodsUnderscore(); $this->classMethodsInvalidParameter = new ClassMethodsInvalidParameter(); @@ -79,7 +86,13 @@ public function testInitiateValues() $this->assertEquals($this->classMethodsCamelCase->getIsFoo(), true); $this->assertEquals($this->classMethodsCamelCase->isBar(), true); $this->assertEquals($this->classMethodsCamelCase->getHasFoo(), true); - $this->assertEquals($this->classMethodsCamelCase->hasBar(), true); + $this->assertEquals($this->classMethodsCamelCase->hasBar(), true); + $this->assertEquals($this->classMethodsTitleCase->getFooBar(), '1'); + $this->assertEquals($this->classMethodsTitleCase->getFooBarBaz(), '2'); + $this->assertEquals($this->classMethodsTitleCase->getIsFoo(), true); + $this->assertEquals($this->classMethodsTitleCase->getIsBar(), true); + $this->assertEquals($this->classMethodsTitleCase->getHasFoo(), true); + $this->assertEquals($this->classMethodsTitleCase->getHasBar(), true); $this->assertEquals($this->classMethodsUnderscore->getFooBar(), '1'); $this->assertEquals($this->classMethodsUnderscore->getFooBarBaz(), '2'); $this->assertEquals($this->classMethodsUnderscore->getIsFoo(), true); @@ -140,6 +153,45 @@ public function testHydratorClassMethodsCamelCase() $this->assertEquals($test->getHasFoo(), false); $this->assertEquals($test->hasBar(), false); } + + + + public function testHydratorClassMethodsTitleCase() + { + $hydrator = new ClassMethods(false); + $datas = $hydrator->extract($this->classMethodsTitleCase); + $this->assertTrue(isset($datas['FooBar'])); + $this->assertEquals($datas['FooBar'], '1'); + $this->assertTrue(isset($datas['FooBarBaz'])); + $this->assertFalse(isset($datas['foo_bar'])); + $this->assertTrue(isset($datas['IsFoo'])); + $this->assertEquals($datas['IsFoo'], true); + $this->assertTrue(isset($datas['IsBar'])); + $this->assertEquals($datas['IsBar'], true); + $this->assertTrue(isset($datas['HasFoo'])); + $this->assertEquals($datas['HasFoo'], true); + $this->assertTrue(isset($datas['HasBar'])); + $this->assertEquals($datas['HasBar'], true); + $test = $hydrator->hydrate( + array( + 'FooBar' => 'foo', + 'FooBarBaz' => 'bar', + 'IsFoo' => false, + 'IsBar' => false, + 'HasFoo' => false, + 'HasBar' => false, + ), + $this->classMethodsTitleCase + ); + $this->assertSame($this->classMethodsTitleCase, $test); + $this->assertEquals($test->getFooBar(), 'foo'); + $this->assertEquals($test->getFooBarBaz(), 'bar'); + $this->assertEquals($test->getIsFoo(), false); + $this->assertEquals($test->getIsBar(), false); + $this->assertEquals($test->getHasFoo(), false); + $this->assertEquals($test->getHasBar(), false); + } + public function testHydratorClassMethodsUnderscore() { From cbd155f880cabf240796718cd3df0e2d74c47ad7 Mon Sep 17 00:00:00 2001 From: "Mabuza, Gugu" Date: Sat, 13 Apr 2013 21:45:16 -0400 Subject: [PATCH 100/127] Added TestAssest for ClassMethods Hydrator --- test/TestAsset/ClassMethodsTitleCase.php | 100 +++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 test/TestAsset/ClassMethodsTitleCase.php diff --git a/test/TestAsset/ClassMethodsTitleCase.php b/test/TestAsset/ClassMethodsTitleCase.php new file mode 100644 index 000000000..8be4dedb7 --- /dev/null +++ b/test/TestAsset/ClassMethodsTitleCase.php @@ -0,0 +1,100 @@ +FooBar; + } + + public function setFooBar($value) + { + $this->FooBar = $value; + return $this; + } + + public function getFooBarBaz() + { + return $this->FooBarBaz; + } + + + public function setFooBarBaz($value) + { + $this->FooBarBaz = $value; + return $this; + } + + public function getIsFoo() + { + return $this->IsFoo; + } + + public function setIsFoo($IsFoo) + { + $this->IsFoo = $IsFoo; + return $this; + } + + + public function getIsBar() + { + return $this->IsBar; + } + + public function setIsBar($IsBar) + { + $this->IsBar = $IsBar; + return $this; + } + + + public function getHasFoo() + { + return $this->HasFoo; + } + + + public function getHasBar() + { + return $this->HasBar; + } + + + public function setHasFoo($HasFoo) + { + $this->HasFoo = $HasFoo; + return $this; + } + + + public function setHasBar($HasBar) + { + $this->HasBar = $HasBar; + } + + + +} From 0a561f5455cae4dbda3bb3ae5ebb8daff3d26147 Mon Sep 17 00:00:00 2001 From: wryck7 Date: Mon, 15 Apr 2013 07:12:31 -0400 Subject: [PATCH 101/127] Trimmed trailing whitespaces --- src/Hydrator/ClassMethods.php | 2 +- test/HydratorTest.php | 12 ++++---- test/TestAsset/ClassMethodsTitleCase.php | 38 ++++++++++++------------ 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 942133d14..4c5cceb7d 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -143,7 +143,7 @@ public function extract($object) if ($this->underscoreSeparatedKeys) { $attribute = preg_replace_callback('/([A-Z])/', $transform, $attribute); - } + } $attributes[$attribute] = $this->extractValue($attribute, $object->$method()); } diff --git a/test/HydratorTest.php b/test/HydratorTest.php index f27a0f774..7bde44768 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -42,7 +42,7 @@ class HydratorTest extends \PHPUnit_Framework_TestCase * @var ClassMethodsCamelCase */ protected $classMethodsCamelCase; - + /** * @var ClassMethodsTitleCase */ @@ -86,7 +86,7 @@ public function testInitiateValues() $this->assertEquals($this->classMethodsCamelCase->getIsFoo(), true); $this->assertEquals($this->classMethodsCamelCase->isBar(), true); $this->assertEquals($this->classMethodsCamelCase->getHasFoo(), true); - $this->assertEquals($this->classMethodsCamelCase->hasBar(), true); + $this->assertEquals($this->classMethodsCamelCase->hasBar(), true); $this->assertEquals($this->classMethodsTitleCase->getFooBar(), '1'); $this->assertEquals($this->classMethodsTitleCase->getFooBarBaz(), '2'); $this->assertEquals($this->classMethodsTitleCase->getIsFoo(), true); @@ -153,9 +153,9 @@ public function testHydratorClassMethodsCamelCase() $this->assertEquals($test->getHasFoo(), false); $this->assertEquals($test->hasBar(), false); } - - - + + + public function testHydratorClassMethodsTitleCase() { $hydrator = new ClassMethods(false); @@ -191,7 +191,7 @@ public function testHydratorClassMethodsTitleCase() $this->assertEquals($test->getHasFoo(), false); $this->assertEquals($test->getHasBar(), false); } - + public function testHydratorClassMethodsUnderscore() { diff --git a/test/TestAsset/ClassMethodsTitleCase.php b/test/TestAsset/ClassMethodsTitleCase.php index 8be4dedb7..3ca4191a1 100644 --- a/test/TestAsset/ClassMethodsTitleCase.php +++ b/test/TestAsset/ClassMethodsTitleCase.php @@ -23,8 +23,8 @@ class ClassMethodsTitleCase protected $HasFoo = true; protected $HasBar = true; - - public function getFooBar() + + public function getFooBar() { return $this->FooBar; } @@ -34,67 +34,67 @@ public function setFooBar($value) $this->FooBar = $value; return $this; } - + public function getFooBarBaz() { return $this->FooBarBaz; } - - + + public function setFooBarBaz($value) { $this->FooBarBaz = $value; return $this; } - public function getIsFoo() + public function getIsFoo() { return $this->IsFoo; } - + public function setIsFoo($IsFoo) { $this->IsFoo = $IsFoo; return $this; } - - public function getIsBar() + + public function getIsBar() { return $this->IsBar; } - + public function setIsBar($IsBar) { $this->IsBar = $IsBar; return $this; } - - public function getHasFoo() + + public function getHasFoo() { return $this->HasFoo; } - - public function getHasBar() + + public function getHasBar() { return $this->HasBar; } - - public function setHasFoo($HasFoo) + + public function setHasFoo($HasFoo) { $this->HasFoo = $HasFoo; return $this; } - - public function setHasBar($HasBar) + + public function setHasBar($HasBar) { $this->HasBar = $HasBar; } - + } From 8b7718948ac0243dfd5609a2fca12aa62168ca5c Mon Sep 17 00:00:00 2001 From: wryck7 Date: Mon, 15 Apr 2013 07:14:06 -0400 Subject: [PATCH 102/127] Converted identation from tabs to spaces --- src/Hydrator/ClassMethods.php | 2 +- test/HydratorTest.php | 64 +++++++------- test/TestAsset/ClassMethodsTitleCase.php | 106 +++++++++++------------ 3 files changed, 86 insertions(+), 86 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index 4c5cceb7d..d188e7f92 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -137,7 +137,7 @@ public function extract($object) if (preg_match('/^get/', $method)) { $attribute = substr($method, 3); if(!property_exists($object, $attribute)) { - $attribute = lcfirst($attribute); + $attribute = lcfirst($attribute); } } diff --git a/test/HydratorTest.php b/test/HydratorTest.php index 7bde44768..fe83f4833 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -158,38 +158,38 @@ public function testHydratorClassMethodsCamelCase() public function testHydratorClassMethodsTitleCase() { - $hydrator = new ClassMethods(false); - $datas = $hydrator->extract($this->classMethodsTitleCase); - $this->assertTrue(isset($datas['FooBar'])); - $this->assertEquals($datas['FooBar'], '1'); - $this->assertTrue(isset($datas['FooBarBaz'])); - $this->assertFalse(isset($datas['foo_bar'])); - $this->assertTrue(isset($datas['IsFoo'])); - $this->assertEquals($datas['IsFoo'], true); - $this->assertTrue(isset($datas['IsBar'])); - $this->assertEquals($datas['IsBar'], true); - $this->assertTrue(isset($datas['HasFoo'])); - $this->assertEquals($datas['HasFoo'], true); - $this->assertTrue(isset($datas['HasBar'])); - $this->assertEquals($datas['HasBar'], true); - $test = $hydrator->hydrate( - array( - 'FooBar' => 'foo', - 'FooBarBaz' => 'bar', - 'IsFoo' => false, - 'IsBar' => false, - 'HasFoo' => false, - 'HasBar' => false, - ), - $this->classMethodsTitleCase - ); - $this->assertSame($this->classMethodsTitleCase, $test); - $this->assertEquals($test->getFooBar(), 'foo'); - $this->assertEquals($test->getFooBarBaz(), 'bar'); - $this->assertEquals($test->getIsFoo(), false); - $this->assertEquals($test->getIsBar(), false); - $this->assertEquals($test->getHasFoo(), false); - $this->assertEquals($test->getHasBar(), false); + $hydrator = new ClassMethods(false); + $datas = $hydrator->extract($this->classMethodsTitleCase); + $this->assertTrue(isset($datas['FooBar'])); + $this->assertEquals($datas['FooBar'], '1'); + $this->assertTrue(isset($datas['FooBarBaz'])); + $this->assertFalse(isset($datas['foo_bar'])); + $this->assertTrue(isset($datas['IsFoo'])); + $this->assertEquals($datas['IsFoo'], true); + $this->assertTrue(isset($datas['IsBar'])); + $this->assertEquals($datas['IsBar'], true); + $this->assertTrue(isset($datas['HasFoo'])); + $this->assertEquals($datas['HasFoo'], true); + $this->assertTrue(isset($datas['HasBar'])); + $this->assertEquals($datas['HasBar'], true); + $test = $hydrator->hydrate( + array( + 'FooBar' => 'foo', + 'FooBarBaz' => 'bar', + 'IsFoo' => false, + 'IsBar' => false, + 'HasFoo' => false, + 'HasBar' => false, + ), + $this->classMethodsTitleCase + ); + $this->assertSame($this->classMethodsTitleCase, $test); + $this->assertEquals($test->getFooBar(), 'foo'); + $this->assertEquals($test->getFooBarBaz(), 'bar'); + $this->assertEquals($test->getIsFoo(), false); + $this->assertEquals($test->getIsBar(), false); + $this->assertEquals($test->getHasFoo(), false); + $this->assertEquals($test->getHasBar(), false); } diff --git a/test/TestAsset/ClassMethodsTitleCase.php b/test/TestAsset/ClassMethodsTitleCase.php index 3ca4191a1..d1326b95d 100644 --- a/test/TestAsset/ClassMethodsTitleCase.php +++ b/test/TestAsset/ClassMethodsTitleCase.php @@ -24,76 +24,76 @@ class ClassMethodsTitleCase protected $HasBar = true; - public function getFooBar() - { - return $this->FooBar; - } + public function getFooBar() + { + return $this->FooBar; + } - public function setFooBar($value) - { - $this->FooBar = $value; - return $this; - } + public function setFooBar($value) + { + $this->FooBar = $value; + return $this; + } - public function getFooBarBaz() - { - return $this->FooBarBaz; - } + public function getFooBarBaz() + { + return $this->FooBarBaz; + } - public function setFooBarBaz($value) - { - $this->FooBarBaz = $value; - return $this; - } + public function setFooBarBaz($value) + { + $this->FooBarBaz = $value; + return $this; + } - public function getIsFoo() - { - return $this->IsFoo; - } + public function getIsFoo() + { + return $this->IsFoo; + } - public function setIsFoo($IsFoo) - { - $this->IsFoo = $IsFoo; - return $this; - } + public function setIsFoo($IsFoo) + { + $this->IsFoo = $IsFoo; + return $this; + } - public function getIsBar() - { - return $this->IsBar; - } + public function getIsBar() + { + return $this->IsBar; + } - public function setIsBar($IsBar) - { - $this->IsBar = $IsBar; - return $this; - } + public function setIsBar($IsBar) + { + $this->IsBar = $IsBar; + return $this; + } - public function getHasFoo() - { - return $this->HasFoo; - } + public function getHasFoo() + { + return $this->HasFoo; + } - public function getHasBar() - { - return $this->HasBar; - } + public function getHasBar() + { + return $this->HasBar; + } - public function setHasFoo($HasFoo) - { - $this->HasFoo = $HasFoo; - return $this; - } + public function setHasFoo($HasFoo) + { + $this->HasFoo = $HasFoo; + return $this; + } - public function setHasBar($HasBar) - { - $this->HasBar = $HasBar; - } + public function setHasBar($HasBar) + { + $this->HasBar = $HasBar; + } From a242a20874f6e220f209d3fec8ca983413e99c1d Mon Sep 17 00:00:00 2001 From: wryck7 Date: Mon, 15 Apr 2013 07:20:39 -0400 Subject: [PATCH 103/127] Fixed CS issues --- src/Hydrator/ClassMethods.php | 3 +-- test/HydratorTest.php | 18 +++++++++--------- test/TestAsset/ClassMethodsTitleCase.php | 9 --------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index d188e7f92..de018a3c9 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -188,5 +188,4 @@ public function hydrate(array $data, $object) return $object; } - -} \ No newline at end of file +} diff --git a/test/HydratorTest.php b/test/HydratorTest.php index fe83f4833..c43cb7d9c 100644 --- a/test/HydratorTest.php +++ b/test/HydratorTest.php @@ -173,15 +173,15 @@ public function testHydratorClassMethodsTitleCase() $this->assertTrue(isset($datas['HasBar'])); $this->assertEquals($datas['HasBar'], true); $test = $hydrator->hydrate( - array( - 'FooBar' => 'foo', - 'FooBarBaz' => 'bar', - 'IsFoo' => false, - 'IsBar' => false, - 'HasFoo' => false, - 'HasBar' => false, - ), - $this->classMethodsTitleCase + array( + 'FooBar' => 'foo', + 'FooBarBaz' => 'bar', + 'IsFoo' => false, + 'IsBar' => false, + 'HasFoo' => false, + 'HasBar' => false, + ), + $this->classMethodsTitleCase ); $this->assertSame($this->classMethodsTitleCase, $test); $this->assertEquals($test->getFooBar(), 'foo'); diff --git a/test/TestAsset/ClassMethodsTitleCase.php b/test/TestAsset/ClassMethodsTitleCase.php index d1326b95d..8375e18a9 100644 --- a/test/TestAsset/ClassMethodsTitleCase.php +++ b/test/TestAsset/ClassMethodsTitleCase.php @@ -40,7 +40,6 @@ public function getFooBarBaz() return $this->FooBarBaz; } - public function setFooBarBaz($value) { $this->FooBarBaz = $value; @@ -58,7 +57,6 @@ public function setIsFoo($IsFoo) return $this; } - public function getIsBar() { return $this->IsBar; @@ -70,31 +68,24 @@ public function setIsBar($IsBar) return $this; } - public function getHasFoo() { return $this->HasFoo; } - public function getHasBar() { return $this->HasBar; } - public function setHasFoo($HasFoo) { $this->HasFoo = $HasFoo; return $this; } - public function setHasBar($HasBar) { $this->HasBar = $HasBar; } - - - } From efeef19e7ed20bbc33a4bef4c8cc078dbf010491 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 15 Apr 2013 06:44:23 -0500 Subject: [PATCH 104/127] [zendframework/zf2#4191] CS fixes - per php-cs-fixer --- test/TestAsset/ClassMethodsMagicMethodSetter.php | 5 ++--- test/TestAsset/ClassMethodsProtectedSetter.php | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/test/TestAsset/ClassMethodsMagicMethodSetter.php b/test/TestAsset/ClassMethodsMagicMethodSetter.php index b1f936b38..8cf00a150 100644 --- a/test/TestAsset/ClassMethodsMagicMethodSetter.php +++ b/test/TestAsset/ClassMethodsMagicMethodSetter.php @@ -15,8 +15,7 @@ class ClassMethodsMagicMethodSetter public function __call($method, $args) { - if(strlen($method) > 3 && strtolower(substr($method, 3)) == 'foo') - { + if(strlen($method) > 3 && strtolower(substr($method, 3)) == 'foo') { $this->foo = $args[0]; } } @@ -25,4 +24,4 @@ public function getFoo() { return $this->foo; } -} \ No newline at end of file +} diff --git a/test/TestAsset/ClassMethodsProtectedSetter.php b/test/TestAsset/ClassMethodsProtectedSetter.php index 09176369f..9f9085257 100644 --- a/test/TestAsset/ClassMethodsProtectedSetter.php +++ b/test/TestAsset/ClassMethodsProtectedSetter.php @@ -28,4 +28,4 @@ public function getBar() { return $this->bar; } -} \ No newline at end of file +} From c6d18e4d2a38e020b38db110832bf301e7ab045c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Thu, 25 Apr 2013 18:51:09 +0200 Subject: [PATCH 105/127] Add untracked files --- src/Hydrator/HydratorPluginManager.php | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/Hydrator/HydratorPluginManager.php diff --git a/src/Hydrator/HydratorPluginManager.php b/src/Hydrator/HydratorPluginManager.php new file mode 100644 index 000000000..efb7ff647 --- /dev/null +++ b/src/Hydrator/HydratorPluginManager.php @@ -0,0 +1,49 @@ + 'Zend\Stdlib\Hydrator\ArraySerializable', + 'classmethods' => 'Zend\Stdlib\Hydrator\ClassMethods', + 'objectproperty' => 'Zend\Stdlib\Hydrator\ObjectProperty', + 'reflection' => 'Zend\Stdlib\Hydrator\Reflection' + ); + + /** + * {@inheritDoc} + */ + public function validatePlugin($plugin) + { + if ($plugin instanceof HydratorInterface) { + // we're okay + return; + } + + throw new Exception\RuntimeException(sprintf( + 'Plugin of type %s is invalid; must implement Zend\Stdlib\Hydrator\HydratorInterface', + (is_object($plugin) ? get_class($plugin) : gettype($plugin)) + )); + } +} From 59d42c588bec72529119ddc1fe8204a4f75b8552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Thu, 25 Apr 2013 22:26:11 +0200 Subject: [PATCH 106/127] Inject validator chain in input filter factory --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 10bc34828..f736431b5 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "suggest": { "zendframework/zend-eventmanager": "To support aggregate hydrator usage", "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage", + "zendframework/zend-servicemanager": "For using the hydrator plugin manager", "zendframework/zend-filter": "To support naming strategy hydrator usage", "pecl-weakref": "Implementation of weak references for Stdlib\\CallbackHandler" }, From a31b12dac7375fb38ec45d19dbafbddc7ea4e275 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Apr 2013 15:36:52 -0500 Subject: [PATCH 107/127] Less expensive operation - array_keys() essentially creates a new array, using more memory. It's also like iterating the array twice. - If we're going to iterate once, might as well only do it once. --- src/Hydrator/ObjectProperty.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Hydrator/ObjectProperty.php b/src/Hydrator/ObjectProperty.php index ea704eb42..52178a1b3 100644 --- a/src/Hydrator/ObjectProperty.php +++ b/src/Hydrator/ObjectProperty.php @@ -33,17 +33,16 @@ public function extract($object) $data = get_object_vars($object); $filter = $this->getFilter(); - foreach (array_keys($data) as $name) { + foreach ($data as $name => $value) { + // Filter keys, removing any we don't want if (!$filter->filter($name)) { unset($data[$name]); + continue; } + // Extract data + $data[$name] = $this->extractValue($name, $value); } - $self = $this; - array_walk($data, function (&$value, $name) use ($self) { - $value = $self->extractValue($name, $value); - }); - return $data; } From 50fa97b380d5af2f3228f4715268d1ff601fa9b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Fri, 26 Apr 2013 12:09:39 +0200 Subject: [PATCH 108/127] Fix CS --- composer.json | 2 +- test/Hydrator/HydratorManagerTest.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/composer.json b/composer.json index f736431b5..10bc34828 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "suggest": { "zendframework/zend-eventmanager": "To support aggregate hydrator usage", "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "For using the hydrator plugin manager", + "zendframework/zend-servicemanager": "To support hydrator plugin manager usage", "zendframework/zend-filter": "To support naming strategy hydrator usage", "pecl-weakref": "Implementation of weak references for Stdlib\\CallbackHandler" }, diff --git a/test/Hydrator/HydratorManagerTest.php b/test/Hydrator/HydratorManagerTest.php index 370d13cee..f5f74cb7d 100644 --- a/test/Hydrator/HydratorManagerTest.php +++ b/test/Hydrator/HydratorManagerTest.php @@ -15,8 +15,6 @@ /** * @category Zend - * @package Zend_Stdlib - * @subpackage UnitTests * @group Zend_Stdlib */ class HydratorManagerTest extends \PHPUnit_Framework_TestCase From 2fc1ee11cce9bfb7cfc854bfc26cfa6636b4ec13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Fri, 26 Apr 2013 22:27:58 +0200 Subject: [PATCH 109/127] Feedbacks --- test/Hydrator/HydratorManagerTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/Hydrator/HydratorManagerTest.php b/test/Hydrator/HydratorManagerTest.php index f5f74cb7d..a2272ed3f 100644 --- a/test/Hydrator/HydratorManagerTest.php +++ b/test/Hydrator/HydratorManagerTest.php @@ -5,7 +5,6 @@ * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License - * @package Zend_Form */ namespace ZendTest\Stdlib\Hydrator; @@ -14,8 +13,7 @@ use Zend\Stdlib\Hydrator\HydratorPluginManager; /** - * @category Zend - * @group Zend_Stdlib + * @group Zend_Stdlib */ class HydratorManagerTest extends \PHPUnit_Framework_TestCase { From f1ccaa9121340b6227c9407483c559dc55b2fbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Fri, 26 Apr 2013 22:45:06 +0200 Subject: [PATCH 110/127] Set hydrators not shared by default --- src/Hydrator/HydratorPluginManager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Hydrator/HydratorPluginManager.php b/src/Hydrator/HydratorPluginManager.php index efb7ff647..0e9892a25 100644 --- a/src/Hydrator/HydratorPluginManager.php +++ b/src/Hydrator/HydratorPluginManager.php @@ -19,6 +19,13 @@ */ class HydratorPluginManager extends AbstractPluginManager { + /** + * Whether or not to share by default + * + * @var bool + */ + protected $shareByDefault = false; + /** * Default set of adapters * From 1ddc7e07a5c8d291f466055807f64ce1b120f9ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sun, 28 Apr 2013 12:49:12 +0200 Subject: [PATCH 111/127] Docblock doesn't match --- src/ArrayObject/PhpLegacyCompatibility.php | 7 +++---- src/ArrayObject/PhpReferenceCompatibility.php | 7 +++---- src/Hydrator/AbstractHydrator.php | 6 +++--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/ArrayObject/PhpLegacyCompatibility.php b/src/ArrayObject/PhpLegacyCompatibility.php index 4d0f44d47..9a71605e7 100644 --- a/src/ArrayObject/PhpLegacyCompatibility.php +++ b/src/ArrayObject/PhpLegacyCompatibility.php @@ -24,10 +24,9 @@ abstract class PhpLegacyCompatibility extends PhpArrayObject /** * Constructor * - * @param array $input - * @param int $flags - * @param string $iteratorClass - * @return ArrayObject + * @param array $input + * @param int $flags + * @param string $iteratorClass */ public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator') { diff --git a/src/ArrayObject/PhpReferenceCompatibility.php b/src/ArrayObject/PhpReferenceCompatibility.php index 117543995..e25257c76 100644 --- a/src/ArrayObject/PhpReferenceCompatibility.php +++ b/src/ArrayObject/PhpReferenceCompatibility.php @@ -59,10 +59,9 @@ abstract class PhpReferenceCompatibility implements IteratorAggregate, ArrayAcce /** * Constructor * - * @param array $input - * @param int $flags - * @param string $iteratorClass - * @return ArrayObject + * @param array $input + * @param int $flags + * @param string $iteratorClass */ public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator') { diff --git a/src/Hydrator/AbstractHydrator.php b/src/Hydrator/AbstractHydrator.php index 6e4e4d219..4cb9a4356 100644 --- a/src/Hydrator/AbstractHydrator.php +++ b/src/Hydrator/AbstractHydrator.php @@ -102,9 +102,9 @@ public function removeStrategy($name) /** * Converts a value for extraction. If no strategy exists the plain value is returned. * - * @param string $name The name of the strategy to use. - * @param mixed $value The value that should be converted. - * @param array $data The object is optionally provided as context. + * @param string $name The name of the strategy to use. + * @param mixed $value The value that should be converted. + * @param array $object The object is optionally provided as context. * @return mixed */ public function extractValue($name, $value, $object = null) From d20256c16e6ce73c5ba054ee08980024b9580501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sun, 28 Apr 2013 19:35:44 +0200 Subject: [PATCH 112/127] Alphabetically order use statements (related to zendframework/zf2#4338) --- src/Hydrator/ClassMethods.php | 2 +- src/Hydrator/Filter/NumberOfParameterFilter.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index c50d821d0..7f1952f70 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -15,10 +15,10 @@ use Zend\Stdlib\ArrayUtils; use Zend\Stdlib\Hydrator\Filter\FilterComposite; use Zend\Stdlib\Hydrator\Filter\FilterProviderInterface; -use Zend\Stdlib\Hydrator\Filter\MethodMatchFilter; use Zend\Stdlib\Hydrator\Filter\GetFilter; use Zend\Stdlib\Hydrator\Filter\HasFilter; use Zend\Stdlib\Hydrator\Filter\IsFilter; +use Zend\Stdlib\Hydrator\Filter\MethodMatchFilter; use Zend\Stdlib\Hydrator\Filter\NumberOfParameterFilter; class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface diff --git a/src/Hydrator/Filter/NumberOfParameterFilter.php b/src/Hydrator/Filter/NumberOfParameterFilter.php index c9e2dd5a3..e3b8c1c9f 100644 --- a/src/Hydrator/Filter/NumberOfParameterFilter.php +++ b/src/Hydrator/Filter/NumberOfParameterFilter.php @@ -9,8 +9,8 @@ namespace Zend\Stdlib\Hydrator\Filter; -use ReflectionMethod; use ReflectionException; +use ReflectionMethod; use Zend\Stdlib\Exception\InvalidArgumentException; use Zend\Stdlib\Hydrator\Filter\FilterInterface; From e144cd0bd6bf034103a9945de8a1588a89a4a2ed Mon Sep 17 00:00:00 2001 From: Nicolas Eeckeloo Date: Mon, 29 Apr 2013 08:41:10 +0200 Subject: [PATCH 113/127] Fix doc blocks consistency --- src/Glob.php | 12 ++++++------ src/StringWrapper/AbstractStringWrapper.php | 6 +++--- src/StringWrapper/StringWrapperInterface.php | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Glob.php b/src/Glob.php index b40f0d9a2..cc927d6d4 100644 --- a/src/Glob.php +++ b/src/Glob.php @@ -31,7 +31,7 @@ abstract class Glob * * @see http://docs.php.net/glob * @param string $pattern - * @param integer $flags + * @param int $flags * @param bool $forceFallback * @return array|false */ @@ -48,7 +48,7 @@ public static function glob($pattern, $flags, $forceFallback = false) * Use the glob function provided by the system. * * @param string $pattern - * @param integer $flags + * @param int $flags * @return array|false */ protected static function systemGlob($pattern, $flags) @@ -82,7 +82,7 @@ protected static function systemGlob($pattern, $flags) * Expand braces manually, then use the system glob. * * @param string $pattern - * @param integer $flags + * @param int $flags * @return array|false */ protected static function fallbackGlob($pattern, $flags) @@ -162,9 +162,9 @@ protected static function fallbackGlob($pattern, $flags) * Find the end of the sub-pattern in a brace expression. * * @param string $pattern - * @param integer $begin - * @param integer $flags - * @return integer|null + * @param int $begin + * @param int $flags + * @return int|null */ protected static function nextBraceSub($pattern, $begin, $flags) { diff --git a/src/StringWrapper/AbstractStringWrapper.php b/src/StringWrapper/AbstractStringWrapper.php index 38a4d540d..e22649e7f 100644 --- a/src/StringWrapper/AbstractStringWrapper.php +++ b/src/StringWrapper/AbstractStringWrapper.php @@ -140,7 +140,7 @@ public function convert($str, $reverse = false) * Wraps a string to a given number of characters * * @param string $string - * @param integer $width + * @param int $width * @param string $break * @param bool $cut * @return string|false @@ -221,9 +221,9 @@ public function wordWrap($string, $width = 75, $break = "\n", $cut = false) * Pad a string to a certain length with another string * * @param string $input - * @param integer $padLength + * @param int $padLength * @param string $padString - * @param integer $padType + * @param int $padType * @return string */ public function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT) diff --git a/src/StringWrapper/StringWrapperInterface.php b/src/StringWrapper/StringWrapperInterface.php index a6a79bfef..974b0be48 100644 --- a/src/StringWrapper/StringWrapperInterface.php +++ b/src/StringWrapper/StringWrapperInterface.php @@ -91,7 +91,7 @@ public function convert($str, $reverse = false); * Wraps a string to a given number of characters * * @param string $str - * @param integer $width + * @param int $width * @param string $break * @param bool $cut * @return string @@ -102,9 +102,9 @@ public function wordWrap($str, $width = 75, $break = "\n", $cut = false); * Pad a string to a certain length with another string * * @param string $input - * @param integer $padLength + * @param int $padLength * @param string $padString - * @param integer $padType + * @param int $padType * @return string */ public function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT); From 2bf51249053c0edbbdc005c18172e4652c94ed7d Mon Sep 17 00:00:00 2001 From: Nicolas Eeckeloo Date: Mon, 29 Apr 2013 09:38:13 +0200 Subject: [PATCH 114/127] Fix coding standards PSR-2 --- src/ArrayUtils.php | 4 ++-- src/ErrorHandler.php | 2 +- src/Hydrator/ClassMethods.php | 2 +- src/Hydrator/Filter/FilterComposite.php | 6 +++--- src/Hydrator/Filter/NumberOfParameterFilter.php | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ArrayUtils.php b/src/ArrayUtils.php index b073f3b45..4261d2e65 100644 --- a/src/ArrayUtils.php +++ b/src/ArrayUtils.php @@ -93,11 +93,11 @@ public static function hasNumericKeys($value, $allowEmpty = false) * * For example: * - * $list = array( 'a','b','c','d' ); + * $list = array('a', 'b', 'c', 'd'); * $list = array( * 0 => 'foo', * 1 => 'bar', - * 2 => array( 'foo' => 'baz' ), + * 2 => array('foo' => 'baz'), * ); * * diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php index 97b4e95d6..5096f53d9 100644 --- a/src/ErrorHandler.php +++ b/src/ErrorHandler.php @@ -109,7 +109,7 @@ public static function clean() */ public static function addError($errno, $errstr = '', $errfile = '', $errline = 0) { - $stack = & static::$stack[ count(static::$stack) - 1 ]; + $stack = & static::$stack[count(static::$stack) - 1]; $stack = new ErrorException($errstr, 0, $errno, $errfile, $errline, $stack); } } diff --git a/src/Hydrator/ClassMethods.php b/src/Hydrator/ClassMethods.php index c50d821d0..6cbb92557 100644 --- a/src/Hydrator/ClassMethods.php +++ b/src/Hydrator/ClassMethods.php @@ -136,7 +136,7 @@ public function extract($object) $attribute = $method; if (preg_match('/^get/', $method)) { $attribute = substr($method, 3); - if(!property_exists($object, $attribute)) { + if (!property_exists($object, $attribute)) { $attribute = lcfirst($attribute); } } diff --git a/src/Hydrator/Filter/FilterComposite.php b/src/Hydrator/Filter/FilterComposite.php index 179e209c3..f5ce7e9c8 100644 --- a/src/Hydrator/Filter/FilterComposite.php +++ b/src/Hydrator/Filter/FilterComposite.php @@ -96,7 +96,7 @@ function($value, $key) { */ public function addFilter($name, $filter, $condition = self::CONDITION_OR) { - if ( !is_callable($filter) && !($filter instanceof FilterInterface) ) { + if (!is_callable($filter) && !($filter instanceof FilterInterface)) { throw new InvalidArgumentException( 'The value of ' . $name . ' should be either a callable or ' . 'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface' @@ -166,13 +166,13 @@ public function filter($property) // Check if 1 from the or filters return true foreach ($this->orFilter as $filter) { if (is_callable($filter)) { - if ( $filter($property) === true) { + if ($filter($property) === true) { $returnValue = true; break; } continue; } else { - if ( $filter->filter($property) === true) { + if ($filter->filter($property) === true) { $returnValue = true; break; } diff --git a/src/Hydrator/Filter/NumberOfParameterFilter.php b/src/Hydrator/Filter/NumberOfParameterFilter.php index c9e2dd5a3..428d57dad 100644 --- a/src/Hydrator/Filter/NumberOfParameterFilter.php +++ b/src/Hydrator/Filter/NumberOfParameterFilter.php @@ -39,7 +39,7 @@ public function filter($property) { try { $reflectionMethod = new ReflectionMethod($property); - } catch( ReflectionException $exception) { + } catch (ReflectionException $exception) { throw new InvalidArgumentException( "Method $property doesn't exist" ); From 11415da3c939d560e3f6f229b2e14ebf733d7d30 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Mon, 29 Apr 2013 13:32:02 +0200 Subject: [PATCH 115/127] Glob::glob() should throw an exception on error --- src/Glob.php | 22 +++++++++++++++++----- test/GlobTest.php | 9 +++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Glob.php b/src/Glob.php index b40f0d9a2..714265f70 100644 --- a/src/Glob.php +++ b/src/Glob.php @@ -9,6 +9,9 @@ namespace Zend\Stdlib; +use Zend\Stdlib\Exception; +use Zend\Stdlib\ErrorHandler; + /** * Wrapper for glob with fallback if GLOB_BRACE is not available. */ @@ -33,9 +36,10 @@ abstract class Glob * @param string $pattern * @param integer $flags * @param bool $forceFallback - * @return array|false + * @return array + * @throws Exception\RuntimeException */ - public static function glob($pattern, $flags, $forceFallback = false) + public static function glob($pattern, $flags = 0, $forceFallback = false) { if (!defined('GLOB_BRACE') || $forceFallback) { return static::fallbackGlob($pattern, $flags); @@ -49,7 +53,8 @@ public static function glob($pattern, $flags, $forceFallback = false) * * @param string $pattern * @param integer $flags - * @return array|false + * @return array + * @throws Exception\RuntimeException */ protected static function systemGlob($pattern, $flags) { @@ -75,7 +80,13 @@ protected static function systemGlob($pattern, $flags) $globFlags = 0; } - return glob($pattern, $globFlags); + ErrorHandler::start(); + $res = glob($pattern, $globFlags); + $err = ErrorHandler::stop(); + if ($res === false) { + throw new Exception\RuntimeException("glob('{$pattern}', {$globFlags}) failed", 0, $err); + } + return $res; } /** @@ -83,7 +94,8 @@ protected static function systemGlob($pattern, $flags) * * @param string $pattern * @param integer $flags - * @return array|false + * @return array + * @throws Exception\RuntimeException */ protected static function fallbackGlob($pattern, $flags) { diff --git a/test/GlobTest.php b/test/GlobTest.php index de269d86e..996c80e2e 100644 --- a/test/GlobTest.php +++ b/test/GlobTest.php @@ -32,4 +32,13 @@ public function testNonMatchingGlobReturnsArray() $result = Glob::glob('/some/path/{,*.}{this,orthis}.php', Glob::GLOB_BRACE); $this->assertInternalType('array', $result); } + + public function testThrowExceptionOnError() + { + $this->setExpectedException('Zend\Stdlib\Exception\RuntimeException'); + + // run into a max path lengh error + $path = '/' . str_repeat('a', 10000); + Glob::glob($path); + } } From 9887ed17724ad2220e2376070285cccec5ff225d Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 1 May 2013 16:42:36 -0500 Subject: [PATCH 116/127] [2.2.0rc1] Release preparation - Updated all component composer.json files to reflect new branch aliases - Updated changelog - Updated readme --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 10bc34828..c32720426 100644 --- a/composer.json +++ b/composer.json @@ -33,8 +33,8 @@ }, "extra": { "branch-alias": { - "dev-master": "2.1-dev", - "dev-develop": "2.2-dev" + "dev-master": "2.2-dev", + "dev-develop": "2.3-dev" } }, "autoload-dev": { From f31174361eed6b80350e601b72e9ae6582c276fb Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Wed, 8 May 2013 21:02:01 +0200 Subject: [PATCH 117/127] Reusing hydration events in the aggregate hydrator --- src/Hydrator/Aggregate/AggregateHydrator.php | 33 +++++--------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/src/Hydrator/Aggregate/AggregateHydrator.php b/src/Hydrator/Aggregate/AggregateHydrator.php index 6198e25d2..07b79ca9a 100644 --- a/src/Hydrator/Aggregate/AggregateHydrator.php +++ b/src/Hydrator/Aggregate/AggregateHydrator.php @@ -41,22 +41,11 @@ public function add(HydratorInterface $hydrator, $priority = self::DEFAULT_PRIOR */ public function extract($object) { - $results = $this->eventManager->trigger(static::EVENT_EXTRACT, $this, array(static::PARAM_OBJECT => $object)); - $data = array(); + $event = new ExtractEvent($this, $object); - foreach ($results as $result) { - if ($result instanceof Traversable) { - $result = ArrayUtils::iteratorToArray($result); - } + $this->eventManager->trigger($event); - if (!is_array($result)) { - continue; - } - - $data = ArrayUtils::merge($data, $result); - } - - return $data; + return $event->getExtractedData(); } /** @@ -64,19 +53,11 @@ public function extract($object) */ public function hydrate(array $data, $object) { - $result = $this - ->eventManager - ->trigger( - static::EVENT_EXTRACT, - $this, - array( - static::PARAM_OBJECT => $object, - static::PARAM_DATA => $data, - ) - ) - ->last(); + $event = new HydrateEvent($this, $object, $data); + + $this->eventManager->trigger($event); - return is_object($result) ? $result : $object; + return $event->getHydratedObject(); } /** From e264274b4c4e0c241553f51d6675052826d13f1d Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Wed, 8 May 2013 21:05:22 +0200 Subject: [PATCH 118/127] Removing unused constants/imports --- src/Hydrator/Aggregate/AggregateHydrator.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Hydrator/Aggregate/AggregateHydrator.php b/src/Hydrator/Aggregate/AggregateHydrator.php index 07b79ca9a..1aae2745a 100644 --- a/src/Hydrator/Aggregate/AggregateHydrator.php +++ b/src/Hydrator/Aggregate/AggregateHydrator.php @@ -9,11 +9,9 @@ namespace Zend\Stdlib\Hydrator\Aggregate; -use Traversable; use Zend\EventManager\EventManager; use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerInterface; -use Zend\Stdlib\ArrayUtils; use Zend\Stdlib\Exception; use Zend\Stdlib\Hydrator\Filter\FilterComposite; use Zend\Stdlib\Hydrator\HydratorInterface; @@ -21,10 +19,6 @@ class AggregateHydrator implements HydratorInterface, EventManagerAwareInterface { const DEFAULT_PRIORITY = 1; - const EVENT_HYDRATE = 'hydrate'; - const EVENT_EXTRACT = 'extract'; - const PARAM_OBJECT = 'object'; - const PARAM_DATA = 'data'; /** * @var \Zend\EventManager\EventManagerInterface|null From 9c19b0aabe0eb3029e20b46954a0ac43dc7538e0 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 16:51:07 +0200 Subject: [PATCH 119/127] Unit tests for the aggregate hydrator --- .../AggregateHydratorFunctionalTest.php | 50 +++++++++ .../Aggregate/AggregateHydratorTest.php | 102 ++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php create mode 100644 test/Hydrator/Aggregate/AggregateHydratorTest.php diff --git a/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php b/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php new file mode 100644 index 000000000..f766582aa --- /dev/null +++ b/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php @@ -0,0 +1,50 @@ +hydrator = new AggregateHydrator(); + } + + public function testEmptyAggregate() + { + $this->markTestIncomplete(); + } + + public function testSingleHydrator() + { + $this->markTestIncomplete(); + } + + public function testMultipleHydrators() + { + $this->markTestIncomplete(); + } + + public function testStoppedPropagation() + { + $this->markTestIncomplete(); + } +} \ No newline at end of file diff --git a/test/Hydrator/Aggregate/AggregateHydratorTest.php b/test/Hydrator/Aggregate/AggregateHydratorTest.php new file mode 100644 index 000000000..539450e96 --- /dev/null +++ b/test/Hydrator/Aggregate/AggregateHydratorTest.php @@ -0,0 +1,102 @@ +eventManager = $this->getMock('Zend\EventManager\EventManagerInterface'); + $this->hydrator = new AggregateHydrator(); + + $this->hydrator->setEventManager($this->eventManager); + } + + /** + * @covers \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator::add + */ + public function testAdd() + { + $attached = $this->getMock('Zend\Stdlib\Hydrator\HydratorInterface'); + + $this + ->eventManager + ->expects($this->once()) + ->method('attachAggregate') + ->with($this->isInstanceOf('Zend\Stdlib\Hydrator\Aggregate\HydratorListener'), 123); + + $this->hydrator->add($attached, 123); + } + + /** + * @covers \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator::hydrate + */ + public function testHydrate() + { + $object = new stdClass(); + + $this + ->eventManager + ->expects($this->once()) + ->method('trigger') + ->with($this->isInstanceOf('Zend\Stdlib\Hydrator\Aggregate\HydrateEvent')); + + $this->assertSame($object, $this->hydrator->hydrate(array('foo' => 'bar'), $object)); + } + + /** + * @covers \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator::extract + */ + public function testExtract() + { + $object = new stdClass(); + + $this + ->eventManager + ->expects($this->once()) + ->method('trigger') + ->with($this->isInstanceOf('Zend\Stdlib\Hydrator\Aggregate\ExtractEvent')); + + $this->assertSame(array(), $this->hydrator->extract($object)); + } + + /** + * @covers \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator::getEventManager + * @covers \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator::setEventManager + */ + public function testGetSetManager() + { + $hydrator = new AggregateHydrator(); + $eventManager = $this->getMock('Zend\EventManager\EventManagerInterface'); + + $this->assertInstanceOf('Zend\EventManager\EventManagerInterface', $hydrator->getEventManager()); + + $hydrator->setEventManager($eventManager); + + $this->assertSame($eventManager, $hydrator->getEventManager()); + } +} From 3b8a81923e0603c350e34cf1bb432f50aeb81c5f Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 16:57:43 +0200 Subject: [PATCH 120/127] Unit tests for the hydrate event --- test/Hydrator/Aggregate/HydrateEventTest.php | 47 ++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 test/Hydrator/Aggregate/HydrateEventTest.php diff --git a/test/Hydrator/Aggregate/HydrateEventTest.php b/test/Hydrator/Aggregate/HydrateEventTest.php new file mode 100644 index 000000000..0cef834c2 --- /dev/null +++ b/test/Hydrator/Aggregate/HydrateEventTest.php @@ -0,0 +1,47 @@ + 'Zaphod'); + $event = new HydrateEvent($target, $hydrated1, $data1); + $data2 = array('maintainer' => 'Marvin'); + $hydrated2 = new \stdClass(); + + $this->assertSame($target, $event->getTarget()); + $this->assertSame($hydrated1, $event->getHydratedObject()); + $this->assertSame($data1, $event->getHydrationData()); + + $event->setHydrationData($data2); + + $this->assertSame($data2, $event->getHydrationData()); + + + $event->setHydratedObject($hydrated2); + + $this->assertSame($hydrated2, $event->getHydratedObject()); + } +} \ No newline at end of file From e6e318affb14b77ea9b84a650ca81775eec74764 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 17:12:43 +0200 Subject: [PATCH 121/127] Extract event unit tests --- test/Hydrator/Aggregate/ExtractEventTest.php | 56 ++++++++++++++++++++ test/Hydrator/Aggregate/HydrateEventTest.php | 7 +-- 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 test/Hydrator/Aggregate/ExtractEventTest.php diff --git a/test/Hydrator/Aggregate/ExtractEventTest.php b/test/Hydrator/Aggregate/ExtractEventTest.php new file mode 100644 index 000000000..7834b8662 --- /dev/null +++ b/test/Hydrator/Aggregate/ExtractEventTest.php @@ -0,0 +1,56 @@ + 'Marvin'); + $object2 = new stdClass(); + + $this->assertSame(ExtractEvent::EVENT_EXTRACT, $event->getName()); + $this->assertSame($target, $event->getTarget()); + $this->assertSame($object1, $event->getExtractionObject()); + $this->assertSame(array(), $event->getExtractedData()); + + $event->setExtractedData($data2); + + $this->assertSame($data2, $event->getExtractedData()); + + + $event->setExtractionObject($object2); + + $this->assertSame($object2, $event->getExtractionObject()); + + $event->mergeExtractedData(array('president' => 'Zaphod')); + + $extracted = $event->getExtractedData(); + + $this->assertCount(2, $extracted); + $this->assertSame('Marvin', $extracted['maintainer']); + $this->assertSame('Zaphod', $extracted['president']); + } +} \ No newline at end of file diff --git a/test/Hydrator/Aggregate/HydrateEventTest.php b/test/Hydrator/Aggregate/HydrateEventTest.php index 0cef834c2..dc4010594 100644 --- a/test/Hydrator/Aggregate/HydrateEventTest.php +++ b/test/Hydrator/Aggregate/HydrateEventTest.php @@ -24,13 +24,14 @@ class HydrateEventTest extends PHPUnit_Framework_TestCase */ public function testEvent() { - $target = new \stdClass(); - $hydrated1 = new \stdClass(); + $target = new stdClass(); + $hydrated1 = new stdClass(); $data1 = array('president' => 'Zaphod'); $event = new HydrateEvent($target, $hydrated1, $data1); $data2 = array('maintainer' => 'Marvin'); - $hydrated2 = new \stdClass(); + $hydrated2 = new stdClass(); + $this->assertSame(HydrateEvent::EVENT_HYDRATE, $event->getName()); $this->assertSame($target, $event->getTarget()); $this->assertSame($hydrated1, $event->getHydratedObject()); $this->assertSame($data1, $event->getHydrationData()); From dd4538f888b439c745070cde81888294ebe41ed4 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 17:29:50 +0200 Subject: [PATCH 122/127] Adding tests for the hydration listener --- .../Aggregate/HydratorListenerTest.php | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 test/Hydrator/Aggregate/HydratorListenerTest.php diff --git a/test/Hydrator/Aggregate/HydratorListenerTest.php b/test/Hydrator/Aggregate/HydratorListenerTest.php new file mode 100644 index 000000000..f09976c22 --- /dev/null +++ b/test/Hydrator/Aggregate/HydratorListenerTest.php @@ -0,0 +1,118 @@ +hydrator = $this->getMock('Zend\Stdlib\Hydrator\HydratorInterface'); + $this->listener = new HydratorListener($this->hydrator); + } + + /** + * @covers \Zend\Stdlib\Hydrator\Aggregate\HydratorListener::attach + */ + public function testAttach() + { + $eventManager = $this->getMock('Zend\EventManager\EventManagerInterface'); + + $eventManager + ->expects($this->exactly(2)) + ->method('attach') + ->with( + $this->logicalOr(HydrateEvent::EVENT_HYDRATE, ExtractEvent::EVENT_EXTRACT), + $this->logicalAnd( + $this->callback('is_callable'), + $this->logicalOr(array($this->listener, 'onHydrate'), array($this->listener, 'onExtract')) + ) + ); + + $this->listener->attach($eventManager); + } + + /** + * @covers \Zend\Stdlib\Hydrator\Aggregate\HydratorListener::onHydrate + */ + public function testOnHydrate() + { + $object = new stdClass(); + $hydrated = new stdClass(); + $data = array('foo' => 'bar'); + $event = $this + ->getMockBuilder('Zend\Stdlib\Hydrator\Aggregate\HydrateEvent') + ->disableOriginalConstructor() + ->getMock(); + + $event->expects($this->any())->method('getHydratedObject')->will($this->returnValue($object)); + $event->expects($this->any())->method('getHydrationData')->will($this->returnValue($data)); + + $this + ->hydrator + ->expects($this->once()) + ->method('hydrate') + ->with($data, $object) + ->will($this->returnValue($hydrated)); + $event->expects($this->once())->method('setHydratedObject')->with($hydrated); + + $this->assertSame($hydrated, $this->listener->onHydrate($event)); + } + + /** + * @covers \Zend\Stdlib\Hydrator\Aggregate\HydratorListener::onExtract + */ + public function testOnExtract() + { + $object = new stdClass(); + $data = array('foo' => 'bar'); + $event = $this + ->getMockBuilder('Zend\Stdlib\Hydrator\Aggregate\ExtractEvent') + ->disableOriginalConstructor() + ->getMock(); + + + $event->expects($this->any())->method('getExtractionObject')->will($this->returnValue($object)); + + $this + ->hydrator + ->expects($this->once()) + ->method('extract') + ->with($object) + ->will($this->returnValue($data)); + $event->expects($this->once())->method('mergeExtractedData')->with($data); + + $this->assertSame($data, $this->listener->onExtract($event)); + } +} \ No newline at end of file From 8fe431948f8372e59e3349d346542ec6b96d8f85 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 18:23:19 +0200 Subject: [PATCH 123/127] Adding integration tests for the aggregate hydrator --- src/Hydrator/Aggregate/AggregateHydrator.php | 4 +- .../AggregateHydratorFunctionalTest.php | 152 ++++++++++++++++-- test/TestAsset/AggregateObject.php | 60 +++++++ 3 files changed, 202 insertions(+), 14 deletions(-) create mode 100644 test/TestAsset/AggregateObject.php diff --git a/src/Hydrator/Aggregate/AggregateHydrator.php b/src/Hydrator/Aggregate/AggregateHydrator.php index 1aae2745a..1ad66e1d0 100644 --- a/src/Hydrator/Aggregate/AggregateHydrator.php +++ b/src/Hydrator/Aggregate/AggregateHydrator.php @@ -37,7 +37,7 @@ public function extract($object) { $event = new ExtractEvent($this, $object); - $this->eventManager->trigger($event); + $this->getEventManager()->trigger($event); return $event->getExtractedData(); } @@ -49,7 +49,7 @@ public function hydrate(array $data, $object) { $event = new HydrateEvent($this, $object, $data); - $this->eventManager->trigger($event); + $this->getEventManager()->trigger($event); return $event->getHydratedObject(); } diff --git a/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php b/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php index f766582aa..1eeb72931 100644 --- a/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php +++ b/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php @@ -1,18 +1,29 @@ hydrator = new AggregateHydrator(); } + /** + * Verifies that no interaction happens when the aggregate hydrator is empty + */ public function testEmptyAggregate() { - $this->markTestIncomplete(); + $object = new ArrayObject(array('zaphod' => 'beeblebrox')); + + $this->assertSame(array(), $this->hydrator->extract($object)); + $this->assertSame($object, $this->hydrator->hydrate(array('arthur' => 'dent'), $object)); + + $this->assertSame(array('zaphod' => 'beeblebrox'), $object->getArrayCopy()); + } + + /** + * @dataProvider getHydratorSet + * + * Verifies that using a single hydrator will have the aggregate hydrator behave like that single hydrator + */ + public function testSingleHydratorExtraction(HydratorInterface $comparisonHydrator, $object) + { + $blueprint = clone $object; + + $this->hydrator->add($comparisonHydrator); + + $this->assertSame($comparisonHydrator->extract($blueprint), $this->hydrator->extract($object)); + } + + /** + * @dataProvider getHydratorSet + * + * Verifies that using a single hydrator will have the aggregate hydrator behave like that single hydrator + */ + public function testSingleHydratorHydration(HydratorInterface $comparisonHydrator, $object, $data) + { + $blueprint = clone $object; + + $this->hydrator->add($comparisonHydrator); + + $hydratedBlueprint = $comparisonHydrator->hydrate($data, $blueprint); + $hydrated = $this->hydrator->hydrate($data, $object); + + $this->assertEquals($hydratedBlueprint, $hydrated); + + if ($hydratedBlueprint === $blueprint) { + $this->assertSame($hydrated, $object); + } + } + + /** + * Verifies that multiple hydrators in an aggregate merge the extracted data + */ + public function testExtractWithMultipleHydrators() + { + $this->hydrator->add(new ClassMethods()); + $this->hydrator->add(new ArraySerializable()); + + $object = new AggregateObject(); + + $extracted = $this->hydrator->extract($object); + + $this->assertArrayHasKey('maintainer', $extracted); + $this->assertArrayHasKey('president', $extracted); + $this->assertSame('Marvin', $extracted['maintainer']); + $this->assertSame('Zaphod', $extracted['president']); + } + + /** + * Verifies that multiple hydrators in an aggregate merge the extracted data + */ + public function testHydrateWithMultipleHydrators() + { + $this->hydrator->add(new ClassMethods()); + $this->hydrator->add(new ArraySerializable()); + + $object = new AggregateObject(); + + $this->assertSame( + $object, + $this->hydrator->hydrate(array('maintainer' => 'Trillian', 'president' => '???'), $object) + ); + + $this->assertArrayHasKey('maintainer', $object->arrayData); + $this->assertArrayHasKey('president', $object->arrayData); + $this->assertSame('Trillian', $object->arrayData['maintainer']); + $this->assertSame('???', $object->arrayData['president']); + $this->assertSame('Trillian', $object->maintainer); } - public function testSingleHydrator() + /** + * Verifies that stopping propagation within a listener in the hydrator allows modifying how the + * hydrator behaves + */ + public function testStoppedPropagationInExtraction() { - $this->markTestIncomplete(); + $object = new ArrayObject(array('president' => 'Zaphod')); + $callback = function (ExtractEvent $event) { + $event->setExtractedData(array('Ravenous Bugblatter Beast of Traal')); + $event->stopPropagation(); + }; + + $this->hydrator->add(new ArraySerializable()); + $this->hydrator->getEventManager()->attach(ExtractEvent::EVENT_EXTRACT, $callback, 1000); + + $this->assertSame(array('Ravenous Bugblatter Beast of Traal'), $this->hydrator->extract($object)); } - public function testMultipleHydrators() + /** + * Verifies that stopping propagation within a listener in the hydrator allows modifying how the + * hydrator behaves + */ + public function testStoppedPropagationInHydration() { - $this->markTestIncomplete(); + $object = new ArrayObject(); + $swappedObject = new stdClass(); + $callback = function (HydrateEvent $event) use ($swappedObject) { + $event->setHydratedObject($swappedObject); + $event->stopPropagation(); + }; + + $this->hydrator->add(new ArraySerializable()); + $this->hydrator->getEventManager()->attach(HydrateEvent::EVENT_HYDRATE, $callback, 1000); + + $this->assertSame($swappedObject, $this->hydrator->hydrate(array('president' => 'Zaphod'), $object)); } - public function testStoppedPropagation() + /** + * Data provider method + * + * @return array + */ + public function getHydratorSet() { - $this->markTestIncomplete(); + return array( + array(new ArraySerializable(), new ArrayObject(array('zaphod' => 'beeblebrox')), array('arthur' => 'dent')), + ); } } \ No newline at end of file diff --git a/test/TestAsset/AggregateObject.php b/test/TestAsset/AggregateObject.php new file mode 100644 index 000000000..5ef1611f4 --- /dev/null +++ b/test/TestAsset/AggregateObject.php @@ -0,0 +1,60 @@ + 'Zaphod'); + + /** + * @var string + */ + public $maintainer = 'Marvin'; + + /** + * @return string + */ + public function getMaintainer() + { + return $this->maintainer; + } + + /** + * @param string $maintainer + */ + public function setMaintainer($maintainer) + { + $this->maintainer = $maintainer; + } + + /** + * @return array + */ + public function getArrayCopy() + { + return $this->arrayData; + } + + /** + * @param array $data + */ + public function exchangeArray(array $data) + { + $this->arrayData = $data; + } +} \ No newline at end of file From b918182ea8bc764b628cbd432e1e423d4a6ea412 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 18:24:11 +0200 Subject: [PATCH 124/127] Using `array_merge` instead of --- src/Hydrator/Aggregate/ExtractEvent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hydrator/Aggregate/ExtractEvent.php b/src/Hydrator/Aggregate/ExtractEvent.php index 87fa68d31..83db9393b 100644 --- a/src/Hydrator/Aggregate/ExtractEvent.php +++ b/src/Hydrator/Aggregate/ExtractEvent.php @@ -60,6 +60,6 @@ public function setExtractedData(array $extractedData) public function mergeExtractedData(array $additionalData) { - $this->extractedData = ArrayUtils::merge($this->extractedData, $additionalData); + $this->extractedData = array_merge($this->extractedData, $additionalData); } } \ No newline at end of file From 15516a96a9bddeaa8049d54a3569b9874e1ab5cd Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 18:30:10 +0200 Subject: [PATCH 125/127] Adding event identifiers for the aggregate hydrator --- src/Hydrator/Aggregate/AggregateHydrator.php | 4 +++- test/Hydrator/Aggregate/AggregateHydratorTest.php | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Hydrator/Aggregate/AggregateHydrator.php b/src/Hydrator/Aggregate/AggregateHydrator.php index 1ad66e1d0..7f0680a89 100644 --- a/src/Hydrator/Aggregate/AggregateHydrator.php +++ b/src/Hydrator/Aggregate/AggregateHydrator.php @@ -59,6 +59,8 @@ public function hydrate(array $data, $object) */ public function setEventManager(EventManagerInterface $eventManager) { + $eventManager->setIdentifiers(array(__CLASS__, get_class($this))); + $this->eventManager = $eventManager; } @@ -68,7 +70,7 @@ public function setEventManager(EventManagerInterface $eventManager) public function getEventManager() { if (null === $this->eventManager) { - $this->eventManager = new EventManager(); + $this->setEventManager(new EventManager()); } return $this->eventManager; diff --git a/test/Hydrator/Aggregate/AggregateHydratorTest.php b/test/Hydrator/Aggregate/AggregateHydratorTest.php index 539450e96..f057c8c64 100644 --- a/test/Hydrator/Aggregate/AggregateHydratorTest.php +++ b/test/Hydrator/Aggregate/AggregateHydratorTest.php @@ -95,6 +95,16 @@ public function testGetSetManager() $this->assertInstanceOf('Zend\EventManager\EventManagerInterface', $hydrator->getEventManager()); + $eventManager + ->expects($this->once()) + ->method('setIdentifiers') + ->with( + array( + 'Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator', + 'Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator', + ) + ); + $hydrator->setEventManager($eventManager); $this->assertSame($eventManager, $hydrator->getEventManager()); From 1092c8e3348463c0e04fe4e9ef26c705aba38ce5 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 18:47:24 +0200 Subject: [PATCH 126/127] CS fixes and docblocks for the aggregate hydrator namespace --- src/Hydrator/Aggregate/AggregateHydrator.php | 9 +++++ src/Hydrator/Aggregate/ExtractEvent.php | 38 ++++++++++++++++++- src/Hydrator/Aggregate/HydrateEvent.php | 27 ++++++++++++- src/Hydrator/Aggregate/HydratorListener.php | 17 +++++++++ .../AggregateHydratorFunctionalTest.php | 2 +- .../Aggregate/AggregateHydratorTest.php | 3 ++ test/Hydrator/Aggregate/ExtractEventTest.php | 2 +- test/Hydrator/Aggregate/HydrateEventTest.php | 2 +- .../Aggregate/HydratorListenerTest.php | 2 +- 9 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/Hydrator/Aggregate/AggregateHydrator.php b/src/Hydrator/Aggregate/AggregateHydrator.php index 7f0680a89..bdcf1eb0a 100644 --- a/src/Hydrator/Aggregate/AggregateHydrator.php +++ b/src/Hydrator/Aggregate/AggregateHydrator.php @@ -16,6 +16,9 @@ use Zend\Stdlib\Hydrator\Filter\FilterComposite; use Zend\Stdlib\Hydrator\HydratorInterface; +/** + * Aggregate hydrator that composes multiple hydrators via events + */ class AggregateHydrator implements HydratorInterface, EventManagerAwareInterface { const DEFAULT_PRIORITY = 1; @@ -25,6 +28,12 @@ class AggregateHydrator implements HydratorInterface, EventManagerAwareInterface */ protected $eventManager; + /** + * Attaches the provided hydrator to the list of hydrators to be used while hydrating/extracting data + * + * @param \Zend\Stdlib\Hydrator\HydratorInterface $hydrator + * @param int $priority + */ public function add(HydratorInterface $hydrator, $priority = self::DEFAULT_PRIORITY) { $this->getEventManager()->attachAggregate(new HydratorListener($hydrator), $priority); diff --git a/src/Hydrator/Aggregate/ExtractEvent.php b/src/Hydrator/Aggregate/ExtractEvent.php index 83db9393b..dfdfbcfb6 100644 --- a/src/Hydrator/Aggregate/ExtractEvent.php +++ b/src/Hydrator/Aggregate/ExtractEvent.php @@ -11,8 +11,11 @@ use Zend\EventManager\Event; -use Zend\Stdlib\ArrayUtils; +/** + * Event triggered when the {@see \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator} extracts + * data from an object + */ class ExtractEvent extends Event { const EVENT_EXTRACT = 'extract'; @@ -32,34 +35,65 @@ class ExtractEvent extends Event */ protected $extractedData = array(); + /** + * @param object $target + * @param object $extractionObject + */ public function __construct($target, $extractionObject) { $this->target = $target; $this->extractionObject = $extractionObject; } + /** + * Retrieves the object from which data is extracted + * + * @return object + */ public function getExtractionObject() { return $this->extractionObject; } + /** + * @param object $extractionObject + * + * @return void + */ public function setExtractionObject($extractionObject) { $this->extractionObject = $extractionObject; } + /** + * Retrieves the data that has been extracted + * + * @return array + */ public function getExtractedData() { return $this->extractedData; } + /** + * @param array $extractedData + * + * @return void + */ public function setExtractedData(array $extractedData) { $this->extractedData = $extractedData; } + /** + * Merge provided data with the extracted data + * + * @param array $additionalData + * + * @return void + */ public function mergeExtractedData(array $additionalData) { $this->extractedData = array_merge($this->extractedData, $additionalData); } -} \ No newline at end of file +} diff --git a/src/Hydrator/Aggregate/HydrateEvent.php b/src/Hydrator/Aggregate/HydrateEvent.php index 2afbb90ba..11bab0237 100644 --- a/src/Hydrator/Aggregate/HydrateEvent.php +++ b/src/Hydrator/Aggregate/HydrateEvent.php @@ -12,6 +12,10 @@ use Zend\EventManager\Event; +/** + * Event triggered when the {@see \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator} hydrates + * data into an object + */ class HydrateEvent extends Event { const EVENT_HYDRATE = 'hydrate'; @@ -31,6 +35,11 @@ class HydrateEvent extends Event */ protected $hydrationData; + /** + * @param object $target + * @param object $hydratedObject + * @param array $hydrationData + */ public function __construct($target, $hydratedObject, array $hydrationData) { $this->target = $target; @@ -38,23 +47,39 @@ public function __construct($target, $hydratedObject, array $hydrationData) $this->hydrationData = $hydrationData; } + /** + * Retrieves the object that is being hydrated + * + * @return object + */ public function getHydratedObject() { return $this->hydratedObject; } + /** + * @param object $hydratedObject + */ public function setHydratedObject($hydratedObject) { $this->hydratedObject = $hydratedObject; } + /** + * Retrieves the data that is being used for hydration + * + * @return array + */ public function getHydrationData() { return $this->hydrationData; } + /** + * @param array $hydrationData + */ public function setHydrationData(array $hydrationData) { $this->hydrationData = $hydrationData; } -} \ No newline at end of file +} diff --git a/src/Hydrator/Aggregate/HydratorListener.php b/src/Hydrator/Aggregate/HydratorListener.php index 71698a289..68cc67274 100644 --- a/src/Hydrator/Aggregate/HydratorListener.php +++ b/src/Hydrator/Aggregate/HydratorListener.php @@ -14,6 +14,11 @@ use Zend\EventManager\EventManagerInterface; use Zend\Stdlib\Hydrator\HydratorInterface; +/** + * Aggregate listener wrapping around a hydrator. Listens + * to {@see \Zend\Stdlib\Hydrator\Aggregate::EVENT_HYDRATE} and + * {@see \Zend\Stdlib\Hydrator\Aggregate::EVENT_EXTRACT} + */ class HydratorListener extends AbstractListenerAggregate { /** @@ -39,6 +44,12 @@ public function attach(EventManagerInterface $events) } /** + * Callback to be used when {@see \Zend\Stdlib\Hydrator\Aggregate\HydrateEvent::EVENT_HYDRATE} is triggered + * + * @param \Zend\Stdlib\Hydrator\Aggregate\HydrateEvent $event + * + * @return object + * * @internal */ public function onHydrate(HydrateEvent $event) @@ -51,6 +62,12 @@ public function onHydrate(HydrateEvent $event) } /** + * Callback to be used when {@see \Zend\Stdlib\Hydrator\Aggregate\ExtractEvent::EVENT_EXTRACT} is triggered + * + * @param \Zend\Stdlib\Hydrator\Aggregate\ExtractEvent $event + * + * @return array + * * @internal */ public function onExtract(ExtractEvent $event) diff --git a/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php b/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php index 1eeb72931..58c2c2d7a 100644 --- a/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php +++ b/test/Hydrator/Aggregate/AggregateHydratorFunctionalTest.php @@ -175,4 +175,4 @@ public function getHydratorSet() array(new ArraySerializable(), new ArrayObject(array('zaphod' => 'beeblebrox')), array('arthur' => 'dent')), ); } -} \ No newline at end of file +} diff --git a/test/Hydrator/Aggregate/AggregateHydratorTest.php b/test/Hydrator/Aggregate/AggregateHydratorTest.php index f057c8c64..1d1dbc62f 100644 --- a/test/Hydrator/Aggregate/AggregateHydratorTest.php +++ b/test/Hydrator/Aggregate/AggregateHydratorTest.php @@ -13,6 +13,9 @@ use Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator; use stdClass; +/** + * Unit tests for {@see \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator} + */ class AggregateHydratorTest extends PHPUnit_Framework_TestCase { /** diff --git a/test/Hydrator/Aggregate/ExtractEventTest.php b/test/Hydrator/Aggregate/ExtractEventTest.php index 7834b8662..4063a6d5e 100644 --- a/test/Hydrator/Aggregate/ExtractEventTest.php +++ b/test/Hydrator/Aggregate/ExtractEventTest.php @@ -53,4 +53,4 @@ public function testEvent() $this->assertSame('Marvin', $extracted['maintainer']); $this->assertSame('Zaphod', $extracted['president']); } -} \ No newline at end of file +} diff --git a/test/Hydrator/Aggregate/HydrateEventTest.php b/test/Hydrator/Aggregate/HydrateEventTest.php index dc4010594..a00ec1548 100644 --- a/test/Hydrator/Aggregate/HydrateEventTest.php +++ b/test/Hydrator/Aggregate/HydrateEventTest.php @@ -45,4 +45,4 @@ public function testEvent() $this->assertSame($hydrated2, $event->getHydratedObject()); } -} \ No newline at end of file +} diff --git a/test/Hydrator/Aggregate/HydratorListenerTest.php b/test/Hydrator/Aggregate/HydratorListenerTest.php index f09976c22..ce93a28ac 100644 --- a/test/Hydrator/Aggregate/HydratorListenerTest.php +++ b/test/Hydrator/Aggregate/HydratorListenerTest.php @@ -115,4 +115,4 @@ public function testOnExtract() $this->assertSame($data, $this->listener->onExtract($event)); } -} \ No newline at end of file +} From d5774e8df41e5e4482d92ceef0ce444bd18b8783 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 18:57:59 +0200 Subject: [PATCH 127/127] CS fix (EOF EOL) --- test/TestAsset/AggregateObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestAsset/AggregateObject.php b/test/TestAsset/AggregateObject.php index 5ef1611f4..41745a6af 100644 --- a/test/TestAsset/AggregateObject.php +++ b/test/TestAsset/AggregateObject.php @@ -57,4 +57,4 @@ public function exchangeArray(array $data) { $this->arrayData = $data; } -} \ No newline at end of file +}