From 75404a033833ef2af7cffc5147a3ae84341d3114 Mon Sep 17 00:00:00 2001 From: gotterdemarung Date: Tue, 10 Dec 2013 22:15:28 +0200 Subject: [PATCH 1/6] Stringy must correctly handle non-string arguments and implicitly cast to string to avoid problems in __toString() method --- tests/Stringy/StringyTest.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/Stringy/StringyTest.php b/tests/Stringy/StringyTest.php index c1e57d2..51c7e65 100644 --- a/tests/Stringy/StringyTest.php +++ b/tests/Stringy/StringyTest.php @@ -15,6 +15,35 @@ class StringyTestCase extends CommonTest $this->assertEquals('UTF-8', $stringy->encoding); } + public function testToString() + { + // Correct work for primitives + $this->assertSame('', (string) new S(null)); + $this->assertSame('', (string) new S(false)); + $this->assertSame('1', (string) new S(true)); + $this->assertSame('-9', (string) new S(-9)); + $this->assertSame('1.18', (string) new S(1.18)); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testToStringArray() + { + (string) new S(array()); + $this->fail('Expecting exception on receiving array as constructor argument'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testToStringResource() + { + (string) new S(fopen('php://stdout', 'w')); + $this->fail('Expecting exception on receiving array as constructor argument'); + } + + public function testCreate() { $stringy = S::create('foo bar', 'UTF-8'); From 88d597370185880a9b9f2002cfb9cd17cf8244dc Mon Sep 17 00:00:00 2001 From: gotterdemarung Date: Tue, 10 Dec 2013 22:15:58 +0200 Subject: [PATCH 2/6] Implicit cast argument to string in constructor --- src/Stringy/Stringy.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Stringy/Stringy.php b/src/Stringy/Stringy.php index c152154..9c41ea5 100644 --- a/src/Stringy/Stringy.php +++ b/src/Stringy/Stringy.php @@ -15,10 +15,21 @@ class Stringy * * @param string $str String to modify * @param string $encoding The character encoding + * + * @throws \InvalidArgumentException if array or resource passed to constructor instead of string */ public function __construct($str, $encoding = null) { - $this->str = $str; + if (is_array($str)) { + throw new \InvalidArgumentException( + 'Expecting string, array given' + ); + } else if (is_resource($str)) { + throw new \InvalidArgumentException( + 'Expecting string, resource given' + ); + } + $this->str = (string) $str; $this->encoding = $encoding ?: mb_internal_encoding(); } From 6e5e5e055fe67dfa091f165ea13c26d31d6edcdd Mon Sep 17 00:00:00 2001 From: gotterdemarung Date: Tue, 10 Dec 2013 22:19:42 +0200 Subject: [PATCH 3/6] primitives check in constructor & toString --- tests/Stringy/StringyTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Stringy/StringyTest.php b/tests/Stringy/StringyTest.php index 51c7e65..6283f2e 100644 --- a/tests/Stringy/StringyTest.php +++ b/tests/Stringy/StringyTest.php @@ -23,6 +23,7 @@ class StringyTestCase extends CommonTest $this->assertSame('1', (string) new S(true)); $this->assertSame('-9', (string) new S(-9)); $this->assertSame('1.18', (string) new S(1.18)); + $this->assertSame(' string ', (string) new S(' string ')); } /** @@ -40,7 +41,7 @@ class StringyTestCase extends CommonTest public function testToStringResource() { (string) new S(fopen('php://stdout', 'w')); - $this->fail('Expecting exception on receiving array as constructor argument'); + $this->fail('Expecting exception on receiving resource as constructor argument'); } From 3458fd79fd0d568ae225b5cb841fde245528e38e Mon Sep 17 00:00:00 2001 From: gotterdemarung Date: Tue, 10 Dec 2013 22:34:19 +0200 Subject: [PATCH 4/6] Stringy->$str became private to ensure its sting content and guarantee zero-exception __toString() execution --- src/Stringy/StaticStringy.php | 100 ++++++++++++++++++---------------- src/Stringy/Stringy.php | 5 +- tests/Stringy/StringyTest.php | 4 +- 3 files changed, 58 insertions(+), 51 deletions(-) diff --git a/src/Stringy/StaticStringy.php b/src/Stringy/StaticStringy.php index e73fb08..10691d0 100644 --- a/src/Stringy/StaticStringy.php +++ b/src/Stringy/StaticStringy.php @@ -13,7 +13,7 @@ class StaticStringy */ public static function upperCaseFirst($str, $encoding = null) { - return Stringy::create($str, $encoding)->upperCaseFirst()->str; + return (string) Stringy::create($str, $encoding)->upperCaseFirst(); } /** @@ -25,7 +25,7 @@ class StaticStringy */ public static function lowerCaseFirst($str, $encoding = null) { - return Stringy::create($str, $encoding)->lowerCaseFirst()->str; + return (string) Stringy::create($str, $encoding)->lowerCaseFirst(); } /** @@ -39,7 +39,7 @@ class StaticStringy */ public static function camelize($str, $encoding = null) { - return Stringy::create($str, $encoding)->camelize()->str; + return (string) Stringy::create($str, $encoding)->camelize(); } /** @@ -53,7 +53,7 @@ class StaticStringy */ public static function upperCamelize($str, $encoding = null) { - return Stringy::create($str, $encoding)->upperCamelize()->str; + return (string) Stringy::create($str, $encoding)->upperCamelize(); } /** @@ -67,7 +67,7 @@ class StaticStringy */ public static function dasherize($str, $encoding = null) { - return Stringy::create($str, $encoding)->dasherize()->str; + return (string) Stringy::create($str, $encoding)->dasherize(); } /** @@ -82,7 +82,7 @@ class StaticStringy */ public static function underscored($str, $encoding = null) { - return $result = Stringy::create($str, $encoding)->underscored()->str; + return (string) Stringy::create($str, $encoding)->underscored(); } /** @@ -94,7 +94,7 @@ class StaticStringy */ public static function swapCase($str, $encoding = null) { - return $result = Stringy::create($str, $encoding)->swapCase()->str; + return (string) Stringy::create($str, $encoding)->swapCase(); } /** @@ -110,7 +110,7 @@ class StaticStringy */ public static function titleize($str, $ignore = null, $encoding = null) { - return $result = Stringy::create($str, $encoding)->titleize($ignore)->str; + return (string) Stringy::create($str, $encoding)->titleize($ignore); } /** @@ -123,7 +123,7 @@ class StaticStringy */ public static function humanize($str, $encoding = null) { - return $result = Stringy::create($str, $encoding)->humanize()->str; + return (string) Stringy::create($str, $encoding)->humanize(); } /** @@ -136,7 +136,7 @@ class StaticStringy */ public static function tidy($str) { - return $result = Stringy::create($str)->tidy()->str; + return (string) Stringy::create($str)->tidy(); } /** @@ -150,7 +150,7 @@ class StaticStringy */ public static function collapseWhitespace($str, $encoding = null) { - return $result = Stringy::create($str, $encoding)->collapseWhitespace()->str; + return (string) Stringy::create($str, $encoding)->collapseWhitespace(); } /** @@ -162,7 +162,7 @@ class StaticStringy */ public static function toAscii($str) { - return $result = Stringy::create($str)->toAscii()->str; + return (string) Stringy::create($str)->toAscii(); } /** @@ -178,14 +178,14 @@ class StaticStringy * @param string $padType One of 'left', 'right', 'both' * @param string $encoding The character encoding * @return string The padded string - * @throws InvalidArgumentException If $padType isn't one of 'right', + * @throws \InvalidArgumentException If $padType isn't one of 'right', * 'left' or 'both' */ public static function pad($str, $length, $padStr = ' ', $padType = 'right', $encoding = null) { - return $result = Stringy::create($str, $encoding) - ->pad($length, $padStr, $padType)->str; + return (string) Stringy::create($str, $encoding) + ->pad($length, $padStr, $padType); } /** @@ -200,7 +200,7 @@ class StaticStringy */ public static function padLeft($str, $length, $padStr = ' ', $encoding = null) { - return Stringy::create($str, $encoding)->padLeft($length, $padStr)->str; + return (string) Stringy::create($str, $encoding)->padLeft($length, $padStr); } /** @@ -215,7 +215,7 @@ class StaticStringy */ public static function padRight($str, $length, $padStr = ' ', $encoding = null) { - return Stringy::create($str, $encoding)->padRight($length, $padStr)->str; + return (string) Stringy::create($str, $encoding)->padRight($length, $padStr); } /** @@ -230,7 +230,7 @@ class StaticStringy */ public static function padBoth($str, $length, $padStr = ' ', $encoding = null) { - return Stringy::create($str, $encoding)->padBoth($length, $padStr)->str; + return (string) Stringy::create($str, $encoding)->padBoth($length, $padStr); } /** @@ -279,7 +279,7 @@ class StaticStringy */ public static function toSpaces($str, $tabLength = 4) { - return Stringy::create($str)->toSpaces($tabLength)->str; + return (string) Stringy::create($str)->toSpaces($tabLength); } /** @@ -293,7 +293,7 @@ class StaticStringy */ public static function toTabs($str, $tabLength = 4) { - return Stringy::create($str)->toTabs($tabLength)->str; + return (string) Stringy::create($str)->toTabs($tabLength); } /** @@ -306,7 +306,7 @@ class StaticStringy */ public static function toLowerCase($str, $encoding = null) { - return Stringy::create($str, $encoding)->toLowerCase()->str; + return (string) Stringy::create($str, $encoding)->toLowerCase(); } /** @@ -319,7 +319,7 @@ class StaticStringy */ public static function toUpperCase($str, $encoding = null) { - return Stringy::create($str, $encoding)->toUpperCase()->str; + return (string) Stringy::create($str, $encoding)->toUpperCase(); } /** @@ -335,7 +335,7 @@ class StaticStringy */ public static function slugify($str, $replacement = '-') { - return Stringy::create($str)->slugify($replacement)->str; + return (string) Stringy::create($str)->slugify($replacement); } /** @@ -364,7 +364,7 @@ class StaticStringy */ public static function surround($str, $substring) { - return Stringy::create($str)->surround($substring)->str; + return (string) Stringy::create($str)->surround($substring); } /** @@ -378,7 +378,7 @@ class StaticStringy */ public static function insert($str, $substring, $index, $encoding = null) { - return Stringy::create($str, $encoding)->insert($substring, $index)->str; + return (string) Stringy::create($str, $encoding)->insert($substring, $index); } /** @@ -395,8 +395,8 @@ class StaticStringy public static function truncate($str, $length, $substring = '', $encoding = null) { - return Stringy::create($str, $encoding) - ->truncate($length, $substring)->str; + return (string) Stringy::create($str, $encoding) + ->truncate($length, $substring); } /** @@ -414,8 +414,8 @@ class StaticStringy public static function safeTruncate($str, $length, $substring = '', $encoding = null) { - return Stringy::create($str, $encoding) - ->safeTruncate($length, $substring)->str; + return (string) Stringy::create($str, $encoding) + ->safeTruncate($length, $substring); } /** @@ -427,7 +427,7 @@ class StaticStringy */ public static function reverse($str, $encoding = null) { - return Stringy::create($str, $encoding)->reverse()->str; + return (string) Stringy::create($str, $encoding)->reverse(); } /** @@ -440,7 +440,7 @@ class StaticStringy */ public static function shuffle($str, $encoding = null) { - return Stringy::create($str, $encoding)->shuffle()->str; + return (string) Stringy::create($str, $encoding)->shuffle(); } /** @@ -464,8 +464,8 @@ class StaticStringy */ public static function longestCommonPrefix($str, $otherStr, $encoding = null) { - return Stringy::create($str, $encoding) - ->longestCommonPrefix($otherStr)->str; + return (string) Stringy::create($str, $encoding) + ->longestCommonPrefix($otherStr); } /** @@ -478,8 +478,8 @@ class StaticStringy */ public static function longestCommonSuffix($str, $otherStr, $encoding = null) { - return Stringy::create($str, $encoding) - ->longestCommonSuffix($otherStr)->str; + return (string) Stringy::create($str, $encoding) + ->longestCommonSuffix($otherStr); } /** @@ -494,8 +494,8 @@ class StaticStringy public static function longestCommonSubstring($str, $otherStr, $encoding = null) { - return Stringy::create($str, $encoding) - ->longestCommonSubstring($otherStr)->str; + return (string) Stringy::create($str, $encoding) + ->longestCommonSubstring($otherStr); } /** @@ -523,7 +523,7 @@ class StaticStringy */ public static function substr($str, $start, $length = null, $encoding = null) { - return Stringy::create($str, $encoding)->substr($start, $length)->str; + return (string) Stringy::create($str, $encoding)->substr($start, $length); } /** @@ -536,7 +536,7 @@ class StaticStringy */ public static function at($str, $index, $encoding = null) { - return Stringy::create($str, $encoding)->at($index)->str; + return (string) Stringy::create($str, $encoding)->at($index); } /** @@ -549,7 +549,7 @@ class StaticStringy */ public static function first($str, $n, $encoding = null) { - return Stringy::create($str, $encoding)->first($n)->str; + return (string) Stringy::create($str, $encoding)->first($n); } /** @@ -562,7 +562,7 @@ class StaticStringy */ public static function last($str, $n, $encoding = null) { - return Stringy::create($str, $encoding)->last($n)->str; + return (string) Stringy::create($str, $encoding)->last($n); } /** @@ -576,7 +576,7 @@ class StaticStringy */ public static function ensureLeft($str, $substring, $encoding = null) { - return Stringy::create($str, $encoding)->ensureLeft($substring)->str; + return (string) Stringy::create($str, $encoding)->ensureLeft($substring); } /** @@ -590,7 +590,7 @@ class StaticStringy */ public static function ensureRight($str, $substring, $encoding = null) { - return Stringy::create($str, $encoding)->ensureRight($substring)->str; + return (string) Stringy::create($str, $encoding)->ensureRight($substring); } /** @@ -603,7 +603,7 @@ class StaticStringy */ public static function removeLeft($str, $substring, $encoding = null) { - return Stringy::create($str, $encoding)->removeLeft($substring)->str; + return (string) Stringy::create($str, $encoding)->removeLeft($substring); } /** @@ -616,7 +616,7 @@ class StaticStringy */ public static function removeRight($str, $substring, $encoding = null) { - return Stringy::create($str, $encoding)->removeRight($substring)->str; + return (string) Stringy::create($str, $encoding)->removeRight($substring); } /** @@ -744,7 +744,7 @@ class StaticStringy */ public static function replace($str, $search, $replacement, $encoding = null) { - return Stringy::create($str, $encoding)->replace($search, $replacement)->str; + return (string) Stringy::create($str, $encoding)->replace($search, $replacement); } /** @@ -763,7 +763,11 @@ class StaticStringy public static function regexReplace($str, $pattern, $replacement, $options = 'msr', $encoding = null) { - return Stringy::create($str, $encoding)->regexReplace($pattern, - $replacement, $options, $encoding)->str; + return (string) Stringy::create($str, $encoding) + ->regexReplace( + $pattern, + $replacement, + $options, + $encoding); } } diff --git a/src/Stringy/Stringy.php b/src/Stringy/Stringy.php index 9c41ea5..888f721 100644 --- a/src/Stringy/Stringy.php +++ b/src/Stringy/Stringy.php @@ -4,7 +4,10 @@ namespace Stringy; class Stringy { - public $str; + /** + * @var string + */ + private $str; public $encoding; diff --git a/tests/Stringy/StringyTest.php b/tests/Stringy/StringyTest.php index 6283f2e..5db2ff8 100644 --- a/tests/Stringy/StringyTest.php +++ b/tests/Stringy/StringyTest.php @@ -11,7 +11,7 @@ class StringyTestCase extends CommonTest { $stringy = new S('foo bar', 'UTF-8'); $this->assertInstanceOf('Stringy\Stringy', $stringy); - $this->assertEquals('foo bar', $stringy->str); + $this->assertEquals('foo bar', (string) $stringy); $this->assertEquals('UTF-8', $stringy->encoding); } @@ -49,7 +49,7 @@ class StringyTestCase extends CommonTest { $stringy = S::create('foo bar', 'UTF-8'); $this->assertInstanceOf('Stringy\Stringy', $stringy); - $this->assertEquals('foo bar', $stringy->str); + $this->assertEquals('foo bar', (string) $stringy); $this->assertEquals('UTF-8', $stringy->encoding); } From 5e01d895dba36af7bc4923a4a40773ccdb510e57 Mon Sep 17 00:00:00 2001 From: gotterdemarung Date: Tue, 10 Dec 2013 22:59:10 +0200 Subject: [PATCH 5/6] titleize refactoring to avoid visibility problems in PHP 5.3 --- src/Stringy/Stringy.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Stringy/Stringy.php b/src/Stringy/Stringy.php index 888f721..3e0a408 100644 --- a/src/Stringy/Stringy.php +++ b/src/Stringy/Stringy.php @@ -217,21 +217,22 @@ class Stringy */ public function titleize($ignore = null) { - $stringy = self::create($this->str, $this->encoding)->trim(); - $encoding = $stringy->encoding; + $buffer = $this->trim(); + $encoding = $this->encoding; - $stringy->str = preg_replace_callback( + $buffer = preg_replace_callback( '/([\S]+)/u', - function ($match) use (&$encoding, &$ignore, &$stringy) { - if ($ignore && in_array($match[0], $ignore)) + function ($match) use (&$encoding, &$ignore) { + if ($ignore && in_array($match[0], $ignore)) { return $match[0]; - $stringy->str = $match[0]; - return $stringy->upperCaseFirst(); + } else { + return (string) (new Stringy($match[0], $encoding))->upperCaseFirst(); + } }, - $stringy->str + $buffer ); - return $stringy; + return new Stringy($buffer, $encoding); } /** From 7335ee5c882874b3b065b703ac37c4949bd3e147 Mon Sep 17 00:00:00 2001 From: gotterdemarung Date: Tue, 10 Dec 2013 23:10:44 +0200 Subject: [PATCH 6/6] fixed T_OBJECT_OPERATOR issue in PHP 5.3 --- src/Stringy/Stringy.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Stringy/Stringy.php b/src/Stringy/Stringy.php index 3e0a408..e90cba3 100644 --- a/src/Stringy/Stringy.php +++ b/src/Stringy/Stringy.php @@ -226,7 +226,8 @@ class Stringy if ($ignore && in_array($match[0], $ignore)) { return $match[0]; } else { - return (string) (new Stringy($match[0], $encoding))->upperCaseFirst(); + $stringy = new Stringy($match[0], $encoding); + return (string) $stringy->upperCaseFirst(); } }, $buffer