diff --git a/README.md b/README.md index 88b1493..413654a 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ s('string')->toTitleCase()->ensureRight('y') == 'Stringy' * [underscored](#underscored) * [upperCamelize](#uppercamelize) * [upperCaseFirst](#uppercasefirst) +* [StaticStringy](#staticstringy) * [Extensions](#extensions) * [Tests](#tests) * [License](#license) @@ -947,6 +948,19 @@ Converts the first character of the supplied string to upper case. s('σ foo')->upperCaseFirst(); // 'Σ foo' ``` +## StaticStringy + +A static wrapper exists for Stringy methods. All the methods list under +"Instance methods" are available. For StaticStringy method, the optional +encoding is expected to be the last argument. The result is not cast, so +the return value may be of type Stringy, integer, boolean, etc. + +```php +// Translates to Stringy::create('fòôbàř', 'UTF-8')->slice(0, 3); +StaticStringy::slice('fòôbàř', 0, 3, 'UTF-8'); +``` + + ## Extensions The following is a list of libraries that extend Stringy: diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 27cb585..8ed62f7 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,8 +5,8 @@ syntaxCheck="false"> - tests/CommonTest.php tests/StringyTest.php + tests/StaticStringyTest.php tests/CreateTest.php diff --git a/src/StaticStringy.php b/src/StaticStringy.php new file mode 100644 index 0000000..e676d14 --- /dev/null +++ b/src/StaticStringy.php @@ -0,0 +1,127 @@ + 3, + 'at' => 3, + 'between' => 5, + 'camelize' => 2, + 'chars' => 2, + 'collapseWhitespace' => 2, + 'contains' => 4, + 'containsAll' => 4, + 'containsAny' => 4, + 'count' => 2, + 'countSubstr' => 4, + 'dasherize' => 2, + 'delimit' => 3, + 'endsWith' => 4, + 'ensureLeft' => 3, + 'ensureRight' => 3, + 'first' => 3, + 'getEncoding' => 2, + 'hasLowerCase' => 2, + 'hasUpperCase' => 2, + 'htmlDecode' => 3, + 'htmlEncode' => 3, + 'humanize' => 2, + 'indexOf' => 4, + 'indexOfLast' => 4, + 'insert' => 4, + 'isAlpha' => 2, + 'isAlphanumeric' => 2, + 'isBlank' => 2, + 'isHexadecimal' => 2, + 'isJson' => 2, + 'isLowerCase' => 2, + 'isSerialized' => 2, + 'isUpperCase' => 2, + 'last' => 3, + 'length' => 2, + 'lines' => 2, + 'longestCommonPrefix' => 3, + 'longestCommonSuffix' => 3, + 'longestCommonSubstring' => 3, + 'lowerCaseFirst' => 2, + 'pad' => 5, + 'padBoth' => 4, + 'padLeft' => 4, + 'padRight' => 4, + 'prepend' => 3, + 'regexReplace' => 5, + 'removeLeft' => 3, + 'removeRight' => 3, + 'repeat' => 3, + 'replace' => 4, + 'reverse' => 2, + 'safeTruncate' => 4, + 'shuffle' => 2, + 'slugify' => 3, + 'startsWith' => 4, + 'slice' => 4, + 'split' => 4, + 'substr' => 4, + 'surround' => 3, + 'swapCase' => 2, + 'tidy' => 2, + 'titleize' => 3, + 'toAscii' => 3, + 'toBoolean' => 2, + 'toLowerCase' => 2, + 'toSpaces' => 3, + 'toTabs' => 3, + 'toTitleCase' => 2, + 'toUpperCase' => 2, + 'trim' => 3, + 'trimLeft' => 3, + 'trimRight' => 3, + 'truncate' => 4, + 'underscored' => 2, + 'upperCamelize' => 2, + 'upperCaseFirst' => 2 + ); + + /** + * Creates an instance of Stringy and invokes the given method with the + * rest of the passed arguments. The optional encoding is expected to be + * the last argument. For example, the following: + * StaticStringy::slice('fòôbàř', 0, 3, 'UTF-8'); translates to + * Stringy::create('fòôbàř', 'UTF-8')->slice(0, 3); + * The result is not cast, so the return value may be of type Stringy, + * integer, boolean, etc. + * + * @param string $name + * @param mixed[] $arguments + */ + public static function __callStatic($name, $arguments) + { + if (!isset(static::$methodArgs[$name])) { + throw new \BadMethodCallException($name . ' is not a valid method'); + } + + $numArgs = count($arguments); + $str = ($numArgs) ? $arguments[0] : ''; + + if ($numArgs === static::$methodArgs[$name]) { + $args = array_slice($arguments, 1, -1); + $encoding = $arguments[$numArgs - 1]; + } else { + $args = array_slice($arguments, 1); + $encoding = null; + } + + $stringy = Stringy::create($str, $encoding); + + return call_user_func_array(array($stringy, $name), $args); + } +} diff --git a/tests/StaticStringyTest.php b/tests/StaticStringyTest.php new file mode 100644 index 0000000..90312ee --- /dev/null +++ b/tests/StaticStringyTest.php @@ -0,0 +1,56 @@ +assertEquals('', (string) $result); + } + + public function testPartialArgsInvocation() + { + $result = S::slice('foobar', 0, 3); + $this->assertEquals('foo', (string) $result); + } + + public function testFullArgsInvocation() + { + $result = S::slice('fòôbàř', 0, 3, 'UTF-8'); + $this->assertEquals('fòô', (string) $result); + } + + /** + * Use reflection to ensure that all argument numbers are correct. Each + * static method should accept 2 more arguments than their Stringy + * equivalent. + */ + public function testArgumentNumbers() + { + $staticStringyClass = new ReflectionClass('Stringy\StaticStringy'); + $stringyClass = new ReflectionClass('Stringy\Stringy'); + + // getStaticPropertyValue can't access protected properties + $properties = $staticStringyClass->getStaticProperties(); + + foreach ($properties['methodArgs'] as $method => $expected) { + $num = $stringyClass->getMethod($method) + ->getNumberOfParameters() + 2; + + $this->assertEquals($expected, $num, + 'Invalid num args for ' . $method); + } + } +}