From 0fbca000a2f41c09ba3a13f3e0cebfd96480285c Mon Sep 17 00:00:00 2001 From: Maxime Veber Date: Tue, 1 Aug 2017 14:41:28 +0200 Subject: [PATCH 1/3] Move sources to src folder --- composer.json | 2 +- EqualableInterface.php => src/EqualableInterface.php | 0 StringTools.php => src/StringTools.php | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename EqualableInterface.php => src/EqualableInterface.php (100%) rename StringTools.php => src/StringTools.php (100%) diff --git a/composer.json b/composer.json index 026d9cf..1c1bdd8 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "licence": "MIT", "description": "Just some tools to work better with PHP", "autoload": { - "psr-4": { "Nekland\\Tools\\": "" } + "psr-4": { "Nekland\\Tools\\": "src/" } }, "require-dev": { "phpspec/phpspec": "^2.5" diff --git a/EqualableInterface.php b/src/EqualableInterface.php similarity index 100% rename from EqualableInterface.php rename to src/EqualableInterface.php diff --git a/StringTools.php b/src/StringTools.php similarity index 100% rename from StringTools.php rename to src/StringTools.php From 9bea6ad09053afb23f9836adc69c7792cd29ac79 Mon Sep 17 00:00:00 2001 From: Maxime Veber Date: Tue, 1 Aug 2017 15:07:44 +0200 Subject: [PATCH 2/3] Fix unicode support for camelize --- README.md | 28 +++++++++++--- spec/Nekland/Tools/StringToolsSpec.php | 8 ++++ src/StringTools.php | 53 +++++++++++++++++++------- 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 0f7add0..37ac20e 100644 --- a/README.md +++ b/README.md @@ -24,14 +24,17 @@ Reference #### ::camelize ```php -StringTools::camelize($str, $from) : string +StringTools::camelize($str, $from, $encoding) : string ``` * `$str` string input -* `$from` (optional, default "\_") string entry format (can be "-" or "\_") +* `$from` (optional, default "\_") input string format (can be "-" or "\_") +* `$encoding` (optional, default "UTF-8") encoding of your input string #### ::startsWith +Say if the given string starts with needle or not. + ```php StringTools::startsWith($str, $start) : bool ``` @@ -41,8 +44,10 @@ StringTools::startsWith($str, $start) : bool #### ::endsWith +Say if the given string ends with needle or not. + ```php -StringTools::endsWith($str, $end, $encoding) : bool +StringTools::endsWith($str, $end) : bool ``` * `$str` string input @@ -50,8 +55,10 @@ StringTools::endsWith($str, $end, $encoding) : bool #### ::removeStart +Removes the start of the string if it matches with the given one. + ```php -StringTools::removeStart($str, $toRemove, $encoding) : string +StringTools::removeStart($str, $toRemove) : string ``` * `$str` string input @@ -60,12 +67,23 @@ StringTools::removeStart($str, $toRemove, $encoding) : string #### ::contains ```php -StringTools::contains($str, $needle, $encoding) : bool +StringTools::contains($str, $needle) : bool ``` * `$str` string input * `$needle` potentially contained string +#### ::mb_ucfirst + +Adds missing multi-byte PHP function for `ucfirst` standard function. + +``` +StringTools::mb_ucfirst($str, $encoding) : string +``` + +* `$str` string input +* `$encoding` (optional, default "UTF-8") encoding of your input string + ### EqualableInterface Helps you equals on objects on a similar way as [java](http://stackoverflow.com/questions/1643067/whats-the-difference-between-equals-and). diff --git a/spec/Nekland/Tools/StringToolsSpec.php b/spec/Nekland/Tools/StringToolsSpec.php index b4b5ca8..c7ee34f 100644 --- a/spec/Nekland/Tools/StringToolsSpec.php +++ b/spec/Nekland/Tools/StringToolsSpec.php @@ -75,4 +75,12 @@ function it_should_contain_str() $this::contains('Hello world ! 😀', '! 😀')->shouldReturn(true); $this::contains('Hello 👽 aliens !', 'aliens')->shouldReturn(true); } + + function it_should_uppercase_first_letter_with_ucfirst() + { + $this::mb_ucfirst('hello')->shouldReturn('Hello'); + $this::mb_ucfirst('helloWorlD')->shouldReturn('HelloWorlD'); + $this::mb_ucfirst('HelloWorld')->shouldReturn('HelloWorld'); + $this::mb_ucfirst('🍕isReallyGood')->shouldReturn('🍕isReallyGood'); + } } diff --git a/src/StringTools.php b/src/StringTools.php index c52d7c8..b72c054 100644 --- a/src/StringTools.php +++ b/src/StringTools.php @@ -7,15 +7,27 @@ class StringTools /** * @param string $str * @param string $from + * @param string $encoding * @return string */ - public static function camelize($str, $from = '_') + public static function camelize($str, $from = '_', $encoding = 'UTF-8') { if (!in_array($from, ['_', '-'])) { throw new \InvalidArgumentException('We can camelize only from snake case or kebab case.'); } - return implode('', array_map('ucfirst', array_map('strtolower', explode($from, $str)))); + return implode('', + array_map( + // Up the first letter for each sub string + function ($item) use ($encoding) { + return StringTools::mb_ucfirst($item, $encoding); + }, + // Lowercase the whole string (otherwise it's not camelize) + array_map(function ($item) use ($encoding) { + return mb_strtolower($item, $encoding); + }, explode($from, $str)) + ) + ); } /** @@ -33,48 +45,61 @@ public static function startsWith($str, $start) /** * @param string $str * @param string $end - * @param string $encoding * @return bool */ - public static function endsWith($str, $end, $encoding = 'UTF-8') + public static function endsWith($str, $end) { - $length = mb_strlen($end, $encoding); + $length = strlen($end); if ($length === 0) { return true; } - return mb_substr($str, -$length, $length, $encoding) === $end; + return substr($str, -$length, $length) === $end; } /** * @param string $str * @param string $toRemove - * @param string $encoding * @return string */ - public static function removeStart($str, $toRemove, $encoding = 'UTF-8') + public static function removeStart($str, $toRemove) { - if (!StringTools::startsWith($str, $toRemove, $encoding)) { + if (!StringTools::startsWith($str, $toRemove)) { return $str; } - $sizeToRemove = mb_strlen($toRemove, $encoding); + $sizeToRemove = strlen($toRemove); - return mb_substr($str, $sizeToRemove, mb_strlen($str, $encoding) - $sizeToRemove, $encoding); + return substr($str, $sizeToRemove, strlen($str) - $sizeToRemove); } /** * @param string $str The string that should contains the needle * @param string $needle What should be contained - * @param string $encoding * @return bool */ - public static function contains($str, $needle, $encoding = 'UTF-8') + public static function contains($str, $needle) { - $position = mb_strpos($str, $needle, 0, $encoding); + $position = mb_strpos($str, $needle, 0); if ($position === 0) { return true; } return (bool) $position; } + + /** + * This function is missing in PHP for now. + * + * @param string $str + * @param string $encoding + * @return string + */ + public static function mb_ucfirst($str, $encoding = 'UTF-8') + { + $length = mb_strlen($str, $encoding); + $firstChar = mb_substr($str, 0, 1, $encoding); + $then = mb_substr($str, 1, $length - 1, $encoding); + + return mb_strtoupper($firstChar, $encoding) . $then; + } } From 95a83337644212a432edb41f323473757745ff39 Mon Sep 17 00:00:00 2001 From: Maxime Veber Date: Tue, 1 Aug 2017 15:14:25 +0200 Subject: [PATCH 3/3] Keep a changelog --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a3bddfe --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- New method `mb_ucfirst`. + +### Changed +- Sources are now located inside `src` folder. +- [Minor BC Break] many parameters `encoding` are suppressed because processing is faster without and they are not + mandatory. _This change doesn't break your code but may in the future if we add new parameters._ + +### Fixed +- Unicode usage for `camelize` method. + +## [1.0.0] - 2016-11-3 + +### Added + +- StringTools class. +- EqualableInterface interface.