1
0
mirror of https://github.com/danielstjules/Stringy.git synced 2025-09-01 09:03:03 +02:00

60 Commits
2.0.0 ... 2.3.1

Author SHA1 Message Date
Daniel St. Jules
bd90918858 2.3.1 2016-03-21 13:26:21 -07:00
Daniel St. Jules
a2d1ec535a Fix #129: Always use root namespace for mbstring functions 2016-03-21 13:22:27 -07:00
Daniel St. Jules
b953a85d2c Add capture group test to regexReplaceProvider 2016-03-19 17:57:04 -07:00
Daniel St. Jules
e07a07a076 Add capture group example to readme 2016-03-19 17:53:09 -07:00
Daniel St. Jules
c4d785d29f Fix changelog date 2016-03-19 17:34:20 -07:00
Daniel St. Jules
5554477962 2.3.0 2016-03-19 17:33:13 -07:00
Daniel St. Jules
87c1a47355 Support older verisons of composer 2016-03-19 17:21:08 -07:00
Daniel St. Jules
6d558974ba Merge pull request #120 from lucasmichot/feature/master/useless-else
Remove some useless else.
2016-02-10 13:20:49 -08:00
Daniel St. Jules
5a9b987f9a Merge pull request #124 from lucasmichot/feature/master/integrates-polyfill
Add polyfill
2016-02-09 16:59:23 -08:00
Lucas Michot
e3d397fa74 Add polyfill 2016-02-10 01:56:06 +01:00
Daniel St. Jules
ffc3fa5ff9 Merge pull request #112 from lucasmichot/feature/master/polyfill
WIP - Allows Stringy to work without ext-mbstring
2016-02-09 16:43:13 -08:00
Lucas Michot
c3f25577ed Avoid duplicate jobs 2016-02-10 01:38:59 +01:00
Lucas Michot
5a4629662c Add tests matrix 2016-02-10 01:28:12 +01:00
Lucas Michot
823e50a340 Allows Stringy to work without ext-mbstring 2016-01-08 18:35:53 +01:00
Daniel St. Jules
9d77c49fca Merge pull request #117 from lucasmichot/feature/master/phpunit-autoload
Let phpunit load autoload.php
2016-01-08 09:32:17 -08:00
Daniel St. Jules
a074d2a2ac Merge pull request #118 from lucasmichot/feature/master/import
Avoid FQN in code
2016-01-08 09:30:30 -08:00
Daniel St. Jules
b7cfa84219 Merge pull request #119 from lucasmichot/feature/master/export-ignore-editorconfig
Do not export .editorconfig
2016-01-08 09:25:15 -08:00
Lucas Michot
e3be6a56ea Composer install for travisCI tests. 2016-01-08 18:22:09 +01:00
Lucas Michot
bdbd4d7541 Let phpunit load autoload.php 2016-01-08 18:01:20 +01:00
Lucas Michot
8419369f3b Add some imports 2016-01-08 18:01:13 +01:00
Lucas Michot
a3dde38a2f Do not export .editorconfig 2016-01-08 18:00:43 +01:00
Lucas Michot
59ce593086 Remove some useless else. 2016-01-08 18:00:23 +01:00
Daniel St. Jules
54cf92c89c Merge pull request #115 from behzadsh/master
Add Persian characters in Stringy::charsArray()
2015-12-27 11:17:23 -05:00
Behzad Shabani
d320bf8704 Add Persian characters in Stringy::charsArray() 2015-12-27 16:03:33 +03:30
Daniel St. Jules
2de4c4aee3 Add badges 2015-12-26 08:13:47 -08:00
Daniel St. Jules
fc39b70953 2.2 2015-12-20 16:49:59 -08:00
Daniel St. Jules
9b61dcc771 Remove y char 2015-12-20 16:45:53 -08:00
Daniel St. Jules
b85a84d0b9 Fix #108 Improve char coverage 2015-12-20 16:44:46 -08:00
Daniel St. Jules
e5c3043d75 Style fixes 2015-12-20 13:22:02 -08:00
Daniel St. Jules
49a7405a2a Remove package annotation from #105 2015-12-20 13:19:29 -08:00
Daniel St. Jules
63109ce85c Add @method lines to StaticStringy 2015-12-20 13:08:08 -08:00
Daniel St. Jules
b223a2c320 Small fixes from #105 2015-12-20 12:08:36 -08:00
Daniel St. Jules
264eed18dd Merge pull request #111 from lucasmichot/feature/master/gitattributes
Add a basic .gitattributes file and avoid some exports
2015-12-20 14:51:11 -05:00
Daniel St. Jules
d990a41a1a Update isBase64 to return true if an empty string 2015-12-20 11:46:33 -08:00
Marcel Pociot
318db789b1 Added isBase64 method 2015-12-20 11:44:18 -08:00
Daniel St. Jules
f086c67ac7 Merge pull request #114 from danielstjules/reflection
Reflection
2015-12-20 14:37:45 -05:00
Daniel St. Jules
ee59d586f2 PHP 5.3 support with reflection 2015-12-20 11:35:48 -08:00
samuelwilliams
3c7bc662a6 :: is dynamically generated. 2015-12-20 17:01:52 +11:00
Daniel St. Jules
2072e667e9 Merge pull request #109 from lucasmichot/feature/master/editorconfig
Add a .editorconfig file
2015-12-08 13:29:02 -05:00
Lucas Michot
b65da66ae8 Add a .gitattributes file and avoid some exports 2015-12-06 14:20:38 +01:00
Lucas Michot
604ddc0528 Add a .editorconfig file 2015-12-06 14:11:58 +01:00
Daniel St. Jules
abd5505e98 Merge pull request #103 from danielkesselberg/master
Update for German umlaut transformation
2015-10-19 22:54:55 -07:00
Daniel Kesselberg
ee4b89c2f8 Update for German umlaut transformation (Ä => AE, Ö => UE, Ü => UE, ä => ae, ö => oe, ü => ue) 2015-09-24 10:47:35 +02:00
Daniel St. Jules
ac04be8416 Add note on PHP 7 compatibility 2015-09-09 22:17:45 -07:00
Daniel St. Jules
41336996a1 Fix ensureRight doc comment 2015-09-09 22:06:27 -07:00
Daniel St. Jules
a8793ff711 Merge pull request #100 from joshdifabio/patch-1
Fix copy/paste mistake in README
2015-09-09 22:05:46 -07:00
Daniel St. Jules
183e529e15 Merge pull request #102 from Big-Shark/newTravisInfrastructure
Changed travis infrastructure
2015-09-09 21:59:17 -07:00
Daniel St. Jules
4673754054 Fix: isJSON now returns false for empty strings 2015-09-09 21:24:11 -07:00
Big_Shark
83671e721a Changed travis infrastructure 2015-09-10 11:19:33 +07:00
Daniel St. Jules
c5f370c46d Merge pull request #101 from Big-Shark/php7
Added php7 for travis
2015-09-09 21:18:47 -07:00
Big_Shark
436d269622 Added php7 for travis 2015-09-10 11:16:21 +07:00
Josh Di Fabio
c09de057a1 Fix copy/paste mistake in README 2015-09-08 13:37:21 +01:00
Daniel St. Jules
efb10020f6 2.1 2015-09-02 23:50:48 -07:00
Daniel St. Jules
ae74e66369 Update readme notes on StaticStringy 2015-09-02 23:47:07 -07:00
Daniel St. Jules
f6475e1288 Stringy::create str defaults to empty string 2015-09-02 23:46:48 -07:00
Daniel St. Jules
ff36c79892 Add test for StaticStringy invocation 2015-09-02 23:37:17 -07:00
Daniel St. Jules
8f40b3495d String is now optional in Stringy constructor 2015-09-02 23:35:32 -07:00
Daniel St. Jules
e237f30d94 Bring back StaticStringy as a __callStatic wrapper 2015-09-02 00:12:25 -07:00
Daniel St. Jules
ad6d32080f Update titleize description in readme 2015-07-29 02:09:00 -07:00
Daniel St. Jules
7377aabf61 Fix titleize example 2015-07-29 02:05:16 -07:00
12 changed files with 608 additions and 193 deletions

16
.editorconfig Normal file
View File

@@ -0,0 +1,16 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.yml]
indent_style = space
indent_size = 2

8
.gitattributes vendored Normal file
View File

@@ -0,0 +1,8 @@
* text=auto
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.travis.yml export-ignore
phpunit.xml.dist export-ignore
tests export-ignore

View File

@@ -1,7 +1,43 @@
language: php
php:
- 5.6
- 5.5
- 5.4
- 5.3
- hhvm
# This triggers builds to run on the new TravisCI infrastructure.
# See: http://docs.travis-ci.com/user/workers/container-based-infrastructure/
sudo: false
matrix:
fast_finish: true
include:
- php: 5.3
env: polyfill='true'
- php: 5.3
env: polyfill='false'
- php: 5.4
env: polyfill='true'
- php: 5.4
env: polyfill='false'
- php: 5.5
env: polyfill='true'
- php: 5.5
env: polyfill='false'
- php: 5.6
env: polyfill='true'
- php: 5.6
env: polyfill='false'
- php: 7.0
env: polyfill='true'
- php: 7.0
env: polyfill='false'
install: travis_retry composer install --no-interaction --prefer-source
before_script:
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-source
- if [[ $polyfill = 'false' ]]; then travis_retry composer remove symfony/polyfill-mbstring; fi
script:
- vendor/bin/phpunit

View File

@@ -1,3 +1,25 @@
### 2.3.1 (2016-03-21)
* Always use root namespace for mbstring functions
### 2.3.0 (2016-03-19)
* Add Persian characters in Stringy::charsArray()
* Use symfony/polyfill-mbstring to avoid dependency on ext-mbstring
### 2.2.0 (2015-12-20)
* isJSON now returns false for empty strings
* Update for German umlaut transformation
* Use reflection to generate method list for StaticStringy
* Added isBase64 method
* Improved toAscii char coverage
### 2.1.0 (2015-09-02)
* Added simplified StaticStringy class
* str in Stringy::create and constructor is now optional
### 2.0.0 (2015-07-29)
* Removed StaticStringy class

View File

@@ -1,7 +1,7 @@
![Stringy](http://danielstjules.com/github/stringy-logo.png)
A PHP string manipulation library with multibyte support. Compatible with PHP
5.3+ and HHVM. Refer to the [1.x branch](https://github.com/danielstjules/Stringy/tree/1.x)
5.3+, PHP 7, and HHVM. Refer to the [1.x branch](https://github.com/danielstjules/Stringy/tree/1.x)
for older documentation.
``` php
@@ -9,12 +9,15 @@ s('string')->toTitleCase()->ensureRight('y') == 'Stringy'
```
[![Build Status](https://api.travis-ci.org/danielstjules/Stringy.svg?branch=master)](https://travis-ci.org/danielstjules/Stringy)
[![Total Downloads](https://poser.pugx.org/danielstjules/stringy/downloads)](https://packagist.org/packages/danielstjules/stringy)
[![License](https://poser.pugx.org/danielstjules/stringy/license)](https://packagist.org/packages/danielstjules/stringy)
* [Why?](#why)
* [Installation](#installation)
* [OO and Chaining](#oo-and-chaining)
* [Implemented Interfaces](#implemented-interfaces)
* [PHP 5.6 Creation](#php-56-creation)
* [StaticStringy](#staticstringy)
* [Class methods](#class-methods)
* [create](#createmixed-str--encoding-)
* [Instance methods](#instance-methods)
@@ -45,6 +48,7 @@ s('string')->toTitleCase()->ensureRight('y') == 'Stringy'
* [insert](#insertint-index-string-substring)
* [isAlpha](#isalpha)
* [isAlphanumeric](#isalphanumeric)
* [isBase64](#isbase64)
* [isBlank](#isblank)
* [isHexadecimal](#ishexadecimal)
* [isJson](#isjson)
@@ -127,7 +131,7 @@ in your composer.json file:
```json
"require": {
"danielstjules/stringy": "~2.0"
"danielstjules/stringy": "~2.3"
}
```
@@ -150,11 +154,13 @@ And in either case, I'd suggest using an alias.
use Stringy\Stringy as S;
```
Please note that Stringy relies on the `mbstring` PHP module for its underlying
multibyte support. This is a non-default, but very common module. For example,
with debian and ubuntu, it's included in libapache2-mod-php5, php5-cli, and
php5-fpm. For OSX users, it's a default for any version of PHP installed with
homebrew. If compiling PHP from scratch, it can be included with the
Please note that Stringy relies on the `mbstring` module for its underlying
multibyte support. If the module is not found, Stringy will use
[symfony/polyfill-mbstring](https://github.com/symfony/polyfill-mbstring).
ex-mbstring is a non-default, but very common module. For example, with debian
and ubuntu, it's included in libapache2-mod-php5, php5-cli, and php5-fpm. For
OSX users, it's a default for any version of PHP installed with homebrew.
If compiling PHP from scratch, it can be included with the
`--enable-mbstring` flag.
## OO and Chaining
@@ -223,6 +229,21 @@ use function Stringy\create as s;
s('fòô bàř')->collapseWhitespace()->swapCase();
```
## StaticStringy
All methods listed under "Instance methods" are available as part of a static
wrapper. For StaticStringy methods, the optional encoding is expected to be the
last argument. The return value is not cast, and may thus be of type Stringy,
integer, boolean, etc.
```php
use Stringy\StaticStringy as S;
// Translates to Stringy::create('fòôbàř', 'UTF-8')->slice(0, 3);
// Returns a Stringy object with the string "fòô"
S::slice('fòôbàř', 0, 3, 'UTF-8');
```
## Class methods
##### create(mixed $str [, $encoding ])
@@ -380,7 +401,7 @@ s('foobar')->ensureLeft('http://'); // 'http://foobar'
##### ensureRight(string $substring)
Ensures that the string begins with $substring. If it doesn't, it's appended.
Ensures that the string ends with $substring. If it doesn't, it's appended.
```php
s('foobar')->ensureRight('.com'); // 'foobar.com'
@@ -493,6 +514,14 @@ otherwise.
s('دانيال1')->isAlphanumeric(); // true
```
##### isBase64()
Returns true if the string is base64 encoded, false otherwise.
```php
s('Zm9vYmFy')->isBase64(); // true
```
##### isBlank()
Returns true if the string contains only whitespace chars, false otherwise.
@@ -511,7 +540,9 @@ s('A102F')->isHexadecimal(); // true
##### isJson()
Returns true if the string is JSON, false otherwise.
Returns true if the string is JSON, false otherwise. Unlike json_decode
in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
in that an empty string is not considered valid JSON.
```php
s('{"foo":"bar"}')->isJson(); // true
@@ -655,7 +686,8 @@ to a lack of support in the bundled version of Oniguruma in PHP < 5.6,
and current versions of HHVM (3.8 and below).
```php
s('fòô ')->regexReplace('f[òô]+\s', 'bàř', 'msr'); // 'bàř'
s('fòô ')->regexReplace('f[òô]+\s', 'bàř'); // 'bàř'
s('fò')->regexReplace('(ò)', '\\1ô'); // 'fòô'
```
##### removeLeft(string $substring)
@@ -800,13 +832,13 @@ s('“I see…”')->tidy(); // '"I see..."'
##### titleize([, array $ignore])
Returns a trimmed string with the first letter of each word capitalized.
Ignores the case of other letters, preserving any acronyms. Also accepts
an array, $ignore, allowing you to list words not to be capitalized.
Also accepts an array, $ignore, allowing you to list words not to be
capitalized.
```php
$ignore = ['at', 'by', 'for', 'in', 'of', 'on', 'out', 'to', 'the'];
s('If you optimize everything, you will always be unhappy.')->titleize($ignore);
// 'I Like to Watch television'
s('i like to watch television')->titleize($ignore);
// 'I Like to Watch Television'
```
##### toAscii()

View File

@@ -16,7 +16,7 @@
],
"require": {
"php": ">=5.3.0",
"ext-mbstring": "*"
"symfony/polyfill-mbstring": "~1.1"
},
"require-dev": {
"phpunit/phpunit": "~4.0"

View File

@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit processIsolation="false"
<phpunit bootstrap="vendor/autoload.php"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<testsuites>
<testsuite name="Stringy">
<file>tests/CommonTest.php</file>
<file>tests/StringyTest.php</file>
<file>tests/StaticStringyTest.php</file>
<file phpVersion="5.6.0">tests/CreateTest.php</file>
</testsuite>
</testsuites>

148
src/StaticStringy.php Normal file
View File

@@ -0,0 +1,148 @@
<?php
namespace Stringy;
use BadMethodCallException;
use ReflectionClass;
use ReflectionMethod;
/**
* Class StaticStringy
*
* @method static string append(string $str, string $stringAppend, string $encoding = null)
* @method static string at(string $str, int $index, string $encoding = null)
* @method static string between(string $str, string $start, string $end, int $offset = 0, string $encoding = null)
* @method static string camelize(string $str, string $encoding = null)
* @method static string chars(string $str, string $encoding = null)
* @method static string collapseWhitespace(string $str, string $encoding = null)
* @method static bool contains(string $str, string $needle, bool $caseSensitive = true, string $encoding = null)
* @method static bool containsAll(string $str, string $needle, bool $caseSensitive = true, string $encoding = null)
* @method static bool containsAny(string $str, string $needle, bool $caseSensitive = true, string $encoding = null)
* @method static int count(string $str, string $encoding = null)
* @method static int countSubstr(string $str, string $substring, bool $caseSensitive = true, string $encoding = null)
* @method static string dasherize(string $str, string $encoding = null)
* @method static string delimit(string $str, string $delimiter, string $encoding = null)
* @method static bool endsWith(string $str, string $substring, bool $caseSensitive = true, string $encoding = null)
* @method static string ensureLeft(string $str, string $substring, string $encoding = null)
* @method static string ensureRight(string $str, string $substring, string $encoding = null)
* @method static string first(string $str, int $n, string $encoding = null)
* @method static bool hasLowerCase(string $str, string $encoding = null)
* @method static bool hasUpperCase(string $str, string $encoding = null)
* @method static string htmlDecode(string $str, int $flags = ENT_COMPAT, string $encoding = null)
* @method static string htmlEncode(string $str, int $flags = ENT_COMPAT, string $encoding = null)
* @method static string humanize(string $str, string $encoding = null)
* @method static int indexOf(string $str, string $needle, int $offset = 0, string $encoding = null)
* @method static int indexOfLast(string $str, string $needle, int $offset = 0, string $encoding = null)
* @method static string insert(string $str, string $substring, int $index = 0, string $encoding = null)
* @method static bool isAlpha(string $str, string $encoding = null)
* @method static bool isAlphanumeric(string $str, string $encoding = null)
* @method static bool isBase64(string $str, string $encoding = null)
* @method static bool isBlank(string $str, string $encoding = null)
* @method static bool isHexadecimal(string $str, string $encoding = null)
* @method static bool isJson(string $str, string $encoding = null)
* @method static bool isLowerCase(string $str, string $encoding = null)
* @method static bool isSerialized(string $str, string $encoding = null)
* @method static bool isUpperCase(string $str, string $encoding = null)
* @method static string last(string $str, string $encoding = null)
* @method static int length(string $str, string $encoding = null)
* @method static Stringy[] lines(string $str, string $encoding = null)
* @method static string longestCommonPrefix(string $str, string $otherStr, string $encoding = null)
* @method static string longestCommonSuffix(string $str, string $otherStr, string $encoding = null)
* @method static string longestCommonSubstring(string $str, string $otherStr, string $encoding = null)
* @method static string lowerCaseFirst(string $str, string $encoding = null)
* @method static string pad(string $str, int $length, string $padStr = ' ', string $padType = 'right', string $encoding = null)
* @method static string padBoth(string $str, int $length, string $padStr = ' ', string $encoding = null)
* @method static string padLeft(string $str, int $length, string $padStr = ' ', string $encoding = null)
* @method static string padRight(string $str, int $length, string $padStr = ' ', string $encoding = null)
* @method static string prepend(string $str, string $string, string $encoding = null)
* @method static string regexReplace(string $str, string $pattern, string $replacement, string $options = 'msr', string $encoding = null)
* @method static string removeLeft(string $str, string $substring, string $encoding = null)
* @method static string removeRight(string $str, string $substring, string $encoding = null)
* @method static string repeat(string $str, int $multiplier, string $encoding = null)
* @method static string replace(string $str, string $search, string $replacement, string $encoding = null)
* @method static string reverse(string $str, string $encoding = null)
* @method static string safeTruncate(string $str, int $length, string $substring = '', string $encoding = null)
* @method static string shuffle(string $str, string $encoding = null)
* @method static string slugify(string $str, string $replacement = '-', string $encoding = null)
* @method static bool startsWith(string $str, string $substring, bool $caseSensitive = true, string $encoding = null)
* @method static string slice(string $str, int $start, int $end = null, string $encoding = null)
* @method static string split(string $str, string $pattern, int $limit = null, string $encoding = null)
* @method static string substr(string $str, int $start, int $length = null, string $encoding = null)
* @method static string surround(string $str, string $substring, string $encoding = null)
* @method static string swapCase(string $str, string $encoding = null)
* @method static string tidy(string $str, string $encoding = null)
* @method static string titleize(string $str, string $encoding = null)
* @method static string toAscii(string $str, bool $removeUnsupported = true, string $encoding = null)
* @method static bool toBoolean(string $str, string $encoding = null)
* @method static string toLowerCase(string $str, string $encoding = null)
* @method static string toSpaces(string $str, int $tabLength = 4, string $encoding = null)
* @method static string toTabs(string $str, int $tabLength = 4, string $encoding = null)
* @method static string toTitleCase(string $str, string $encoding = null)
* @method static string toUpperCase(string $str, string $encoding = null)
* @method static string trim(string $str, string $chars = null, string $encoding = null)
* @method static string trimLeft(string $str, string $chars = null, string $encoding = null)
* @method static string trimRight(string $str, string $chars = null, string $encoding = null)
* @method static string truncate(string $str, int $length, string $substring = '', string $encoding = null)
* @method static string underscored(string $str, string $encoding = null)
* @method static string upperCamelize(string $str, string $encoding = null)
* @method static string upperCaseFirst(string $str, string $encoding = null)
*/
class StaticStringy
{
/**
* A mapping of method names to the numbers of arguments it accepts. Each
* should be two more than the equivalent Stringy method. Necessary as
* static methods place the optional $encoding as the last parameter.
*
* @var string[]
*/
protected static $methodArgs = null;
/**
* 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
*
* @return Stringy
*
* @throws \BadMethodCallException
*/
public static function __callStatic($name, $arguments)
{
if (!static::$methodArgs) {
$stringyClass = new ReflectionClass('Stringy\Stringy');
$methods = $stringyClass->getMethods(ReflectionMethod::IS_PUBLIC);
foreach ($methods as $method) {
$params = $method->getNumberOfParameters() + 2;
static::$methodArgs[$method->name] = $params;
}
}
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);
}
}

View File

@@ -2,7 +2,15 @@
namespace Stringy;
class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
use ArrayAccess;
use ArrayIterator;
use Countable;
use Exception;
use InvalidArgumentException;
use IteratorAggregate;
use OutOfBoundsException;
class Stringy implements Countable, IteratorAggregate, ArrayAccess
{
/**
* An instance's string.
@@ -31,20 +39,20 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
* @throws \InvalidArgumentException if an array or object without a
* __toString method is passed as the first argument
*/
public function __construct($str, $encoding = null)
public function __construct($str = '', $encoding = null)
{
if (is_array($str)) {
throw new \InvalidArgumentException(
throw new InvalidArgumentException(
'Passed value cannot be an array'
);
} elseif (is_object($str) && !method_exists($str, '__toString')) {
throw new \InvalidArgumentException(
throw new InvalidArgumentException(
'Passed object must have a __toString method'
);
}
$this->str = (string) $str;
$this->encoding = $encoding ?: mb_internal_encoding();
$this->encoding = $encoding ?: \mb_internal_encoding();
}
/**
@@ -60,7 +68,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
* @throws \InvalidArgumentException if an array or object without a
* __toString method is passed as the first argument
*/
public static function create($str, $encoding = null)
public static function create($str = '', $encoding = null)
{
return new static($str, $encoding);
}
@@ -104,7 +112,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*
* @param string $start Delimiter marking the start of the substring
* @param string $end Delimiter marketing the end of the substring
* @param string $offset Index from which to begin the search
* @param int $offset Index from which to begin the search
* @return Stringy Object whose $str has been converted to an URL slug
*/
public function between($start, $end, $offset = 0)
@@ -114,7 +122,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
return static::create('', $this->encoding);
}
$substrIndex = $startIndex + mb_strlen($start, $this->encoding);
$substrIndex = $startIndex + \mb_strlen($start, $this->encoding);
$endIndex = $this->indexOf($end, $substrIndex);
if ($endIndex === false) {
return static::create('', $this->encoding);
@@ -140,10 +148,10 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
'/[-_\s]+(.)?/u',
function ($match) use ($encoding) {
if (isset($match[1])) {
return mb_strtoupper($match[1], $encoding);
} else {
return '';
return \mb_strtoupper($match[1], $encoding);
}
return '';
},
$stringy->str
);
@@ -151,7 +159,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$stringy->str = preg_replace_callback(
'/[\d]+(.)?/u',
function ($match) use ($encoding) {
return mb_strtoupper($match[0], $encoding);
return \mb_strtoupper($match[0], $encoding);
},
$stringy->str
);
@@ -200,10 +208,10 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$encoding = $this->encoding;
if ($caseSensitive) {
return (mb_strpos($this->str, $needle, 0, $encoding) !== false);
} else {
return (mb_stripos($this->str, $needle, 0, $encoding) !== false);
return (\mb_strpos($this->str, $needle, 0, $encoding) !== false);
}
return (\mb_stripos($this->str, $needle, 0, $encoding) !== false);
}
/**
@@ -276,13 +284,13 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
public function countSubstr($substring, $caseSensitive = true)
{
if ($caseSensitive) {
return mb_substr_count($this->str, $substring, $this->encoding);
return \mb_substr_count($this->str, $substring, $this->encoding);
}
$str = mb_strtoupper($this->str, $this->encoding);
$substring = mb_strtoupper($substring, $this->encoding);
$str = \mb_strtoupper($this->str, $this->encoding);
$substring = \mb_strtoupper($substring, $this->encoding);
return mb_substr_count($str, $substring, $this->encoding);
return \mb_substr_count($str, $substring, $this->encoding);
}
/**
@@ -309,14 +317,14 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
public function delimit($delimiter)
{
// Save current regex encoding so we can reset it after
$regexEncoding = mb_regex_encoding();
mb_regex_encoding($this->encoding);
$regexEncoding = \mb_regex_encoding();
\mb_regex_encoding($this->encoding);
$str = mb_ereg_replace('\B([A-Z])', '-\1', $this->trim());
$str = mb_strtolower($str, $this->encoding);
$str = mb_ereg_replace('[-_\s]+', $delimiter, $str);
$str = \mb_ereg_replace('\B([A-Z])', '-\1', $this->trim());
$str = \mb_strtolower($str, $this->encoding);
$str = \mb_ereg_replace('[-_\s]+', $delimiter, $str);
mb_regex_encoding($regexEncoding);
\mb_regex_encoding($regexEncoding);
return static::create($str, $this->encoding);
}
@@ -332,15 +340,15 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function endsWith($substring, $caseSensitive = true)
{
$substringLength = mb_strlen($substring, $this->encoding);
$substringLength = \mb_strlen($substring, $this->encoding);
$strLength = $this->length();
$endOfStr = mb_substr($this->str, $strLength - $substringLength,
$endOfStr = \mb_substr($this->str, $strLength - $substringLength,
$substringLength, $this->encoding);
if (!$caseSensitive) {
$substring = mb_strtolower($substring, $this->encoding);
$endOfStr = mb_strtolower($endOfStr, $this->encoding);
$substring = \mb_strtolower($substring, $this->encoding);
$endOfStr = \mb_strtolower($endOfStr, $this->encoding);
}
return (string) $substring === $endOfStr;
@@ -365,7 +373,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
}
/**
* Ensures that the string begins with $substring. If it doesn't, it's
* Ensures that the string ends with $substring. If it doesn't, it's
* appended.
*
* @param string $substring The substring to add if not present
@@ -394,11 +402,10 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
if ($n < 0) {
$stringy->str = '';
} else {
return $stringy->substr(0, $n);
return $stringy;
}
return $stringy;
return $stringy->substr(0, $n);
}
/**
@@ -421,7 +428,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function getIterator()
{
return new \ArrayIterator($this->chars());
return new ArrayIterator($this->chars());
}
/**
@@ -501,7 +508,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function indexOf($needle, $offset = 0)
{
return mb_strpos($this->str, (string) $needle,
return \mb_strpos($this->str, (string) $needle,
(int) $offset, $this->encoding);
}
@@ -517,7 +524,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function indexOfLast($needle, $offset = 0)
{
return mb_strrpos($this->str, (string) $needle,
return \mb_strrpos($this->str, (string) $needle,
(int) $offset, $this->encoding);
}
@@ -535,8 +542,8 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
return $stringy;
}
$start = mb_substr($stringy->str, 0, $index, $stringy->encoding);
$end = mb_substr($stringy->str, $index, $stringy->length(),
$start = \mb_substr($stringy->str, 0, $index, $stringy->encoding);
$end = \mb_substr($stringy->str, $index, $stringy->length(),
$stringy->encoding);
$stringy->str = $start . $substring . $end;
@@ -589,12 +596,18 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
}
/**
* Returns true if the string is JSON, false otherwise.
* Returns true if the string is JSON, false otherwise. Unlike json_decode
* in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
* in that an empty string is not considered valid JSON.
*
* @return bool Whether or not $str is JSON
*/
public function isJson()
{
if (!$this->length()) {
return false;
}
json_decode($this->str);
return (json_last_error() === JSON_ERROR_NONE);
@@ -621,6 +634,17 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
return $this->str === 'b:0;' || @unserialize($this->str) !== false;
}
/**
* Returns true if the string is base64 encoded, false otherwise.
*
* @return bool Whether or not $str is base64 encoded
*/
public function isBase64()
{
return (base64_encode(base64_decode($this->str, true)) === $this->str);
}
/**
* Returns true if the string contains only lower case chars, false
* otherwise.
@@ -644,11 +668,10 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
if ($n <= 0) {
$stringy->str = '';
} else {
return $stringy->substr(-$n);
return $stringy;
}
return $stringy;
return $stringy->substr(-$n);
}
/**
@@ -658,7 +681,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function length()
{
return mb_strlen($this->str, $this->encoding);
return \mb_strlen($this->str, $this->encoding);
}
/**
@@ -669,7 +692,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function lines()
{
$array = mb_split('[\r\n]{1,2}', $this->str);
$array = \mb_split('[\r\n]{1,2}', $this->str);
for ($i = 0; $i < count($array); $i++) {
$array[$i] = static::create($array[$i], $this->encoding);
}
@@ -686,13 +709,13 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
public function longestCommonPrefix($otherStr)
{
$encoding = $this->encoding;
$maxLength = min($this->length(), mb_strlen($otherStr, $encoding));
$maxLength = min($this->length(), \mb_strlen($otherStr, $encoding));
$longestCommonPrefix = '';
for ($i = 0; $i < $maxLength; $i++) {
$char = mb_substr($this->str, $i, 1, $encoding);
$char = \mb_substr($this->str, $i, 1, $encoding);
if ($char == mb_substr($otherStr, $i, 1, $encoding)) {
if ($char == \mb_substr($otherStr, $i, 1, $encoding)) {
$longestCommonPrefix .= $char;
} else {
break;
@@ -711,13 +734,13 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
public function longestCommonSuffix($otherStr)
{
$encoding = $this->encoding;
$maxLength = min($this->length(), mb_strlen($otherStr, $encoding));
$maxLength = min($this->length(), \mb_strlen($otherStr, $encoding));
$longestCommonSuffix = '';
for ($i = 1; $i <= $maxLength; $i++) {
$char = mb_substr($this->str, -$i, 1, $encoding);
$char = \mb_substr($this->str, -$i, 1, $encoding);
if ($char == mb_substr($otherStr, -$i, 1, $encoding)) {
if ($char == \mb_substr($otherStr, -$i, 1, $encoding)) {
$longestCommonSuffix = $char . $longestCommonSuffix;
} else {
break;
@@ -741,7 +764,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$encoding = $this->encoding;
$stringy = static::create($this->str, $encoding);
$strLength = $stringy->length();
$otherLength = mb_strlen($otherStr, $encoding);
$otherLength = \mb_strlen($otherStr, $encoding);
// Return if either string is empty
if ($strLength == 0 || $otherLength == 0) {
@@ -756,8 +779,8 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
for ($i = 1; $i <= $strLength; $i++) {
for ($j = 1; $j <= $otherLength; $j++) {
$strChar = mb_substr($stringy->str, $i - 1, 1, $encoding);
$otherChar = mb_substr($otherStr, $j - 1, 1, $encoding);
$strChar = \mb_substr($stringy->str, $i - 1, 1, $encoding);
$otherChar = \mb_substr($otherStr, $j - 1, 1, $encoding);
if ($strChar == $otherChar) {
$table[$i][$j] = $table[$i - 1][$j - 1] + 1;
@@ -771,7 +794,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
}
}
$stringy->str = mb_substr($stringy->str, $end - $len, $len, $encoding);
$stringy->str = \mb_substr($stringy->str, $end - $len, $len, $encoding);
return $stringy;
}
@@ -783,11 +806,11 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function lowerCaseFirst()
{
$first = mb_substr($this->str, 0, 1, $this->encoding);
$rest = mb_substr($this->str, 1, $this->length() - 1,
$first = \mb_substr($this->str, 0, 1, $this->encoding);
$rest = \mb_substr($this->str, 1, $this->length() - 1,
$this->encoding);
$str = mb_strtolower($first, $this->encoding) . $rest;
$str = \mb_strtolower($first, $this->encoding) . $rest;
return static::create($str, $this->encoding);
}
@@ -829,10 +852,10 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$length = $this->length();
if (($offset >= 0 && $length <= $offset) || $length < abs($offset)) {
throw new \OutOfBoundsException('No character exists at the index');
throw new OutOfBoundsException('No character exists at the index');
}
return mb_substr($this->str, $offset, 1, $this->encoding);
return \mb_substr($this->str, $offset, 1, $this->encoding);
}
/**
@@ -846,7 +869,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
public function offsetSet($offset, $value)
{
// Stringy is immutable, cannot directly set char
throw new \Exception('Stringy object is immutable, cannot modify char');
throw new Exception('Stringy object is immutable, cannot modify char');
}
/**
@@ -859,7 +882,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
public function offsetUnset($offset)
{
// Don't allow directly modifying the string
throw new \Exception('Stringy object is immutable, cannot unset char');
throw new Exception('Stringy object is immutable, cannot unset char');
}
/**
@@ -873,13 +896,13 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
* @param string $padStr String used to pad, defaults to space
* @param string $padType One of 'left', 'right', 'both'
* @return Stringy Object with a padded $str
* @throws InvalidArgumentException If $padType isn't one of 'right',
* @throws /InvalidArgumentException If $padType isn't one of 'right',
* 'left' or 'both'
*/
public function pad($length, $padStr = ' ', $padType = 'right')
{
if (!in_array($padType, array('left', 'right', 'both'))) {
throw new \InvalidArgumentException('Pad expects $padType ' .
throw new InvalidArgumentException('Pad expects $padType ' .
"to be one of 'left', 'right' or 'both'");
}
@@ -960,11 +983,11 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function regexReplace($pattern, $replacement, $options = 'msr')
{
$regexEncoding = mb_regex_encoding();
mb_regex_encoding($this->encoding);
$regexEncoding = \mb_regex_encoding();
\mb_regex_encoding($this->encoding);
$str = mb_ereg_replace($pattern, $replacement, $this->str, $options);
mb_regex_encoding($regexEncoding);
$str = \mb_ereg_replace($pattern, $replacement, $this->str, $options);
\mb_regex_encoding($regexEncoding);
return static::create($str, $this->encoding);
}
@@ -980,7 +1003,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$stringy = static::create($this->str, $this->encoding);
if ($stringy->startsWith($substring)) {
$substringLength = mb_strlen($substring, $stringy->encoding);
$substringLength = \mb_strlen($substring, $stringy->encoding);
return $stringy->substr($substringLength);
}
@@ -998,7 +1021,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$stringy = static::create($this->str, $this->encoding);
if ($stringy->endsWith($substring)) {
$substringLength = mb_strlen($substring, $stringy->encoding);
$substringLength = \mb_strlen($substring, $stringy->encoding);
return $stringy->substr(0, $stringy->length() - $substringLength);
}
@@ -1042,7 +1065,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
// Loop from last index of string to first
for ($i = $strLength - 1; $i >= 0; $i--) {
$reversed .= mb_substr($this->str, $i, 1, $this->encoding);
$reversed .= \mb_substr($this->str, $i, 1, $this->encoding);
}
return static::create($reversed, $this->encoding);
@@ -1067,16 +1090,16 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
// Need to further trim the string so we can append the substring
$encoding = $stringy->encoding;
$substringLength = mb_strlen($substring, $encoding);
$substringLength = \mb_strlen($substring, $encoding);
$length = $length - $substringLength;
$truncated = mb_substr($stringy->str, 0, $length, $encoding);
$truncated = \mb_substr($stringy->str, 0, $length, $encoding);
// If the last word was truncated
if (mb_strpos($stringy->str, ' ', $length - 1, $encoding) != $length) {
// Find pos of the last occurrence of a space, get up to that
$lastPos = mb_strrpos($truncated, ' ', 0, $encoding);
$truncated = mb_substr($truncated, 0, $lastPos, $encoding);
$lastPos = \mb_strrpos($truncated, ' ', 0, $encoding);
$truncated = \mb_substr($truncated, 0, $lastPos, $encoding);
}
$stringy->str = $truncated . $substring;
@@ -1097,7 +1120,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$shuffledStr = '';
foreach ($indexes as $i) {
$shuffledStr .= mb_substr($this->str, $i, 1, $this->encoding);
$shuffledStr .= \mb_substr($this->str, $i, 1, $this->encoding);
}
return static::create($shuffledStr, $this->encoding);
@@ -1136,13 +1159,13 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function startsWith($substring, $caseSensitive = true)
{
$substringLength = mb_strlen($substring, $this->encoding);
$startOfStr = mb_substr($this->str, 0, $substringLength,
$substringLength = \mb_strlen($substring, $this->encoding);
$startOfStr = \mb_substr($this->str, 0, $substringLength,
$this->encoding);
if (!$caseSensitive) {
$substring = mb_strtolower($substring, $this->encoding);
$startOfStr = mb_strtolower($startOfStr, $this->encoding);
$substring = \mb_strtolower($substring, $this->encoding);
$startOfStr = \mb_strtolower($startOfStr, $this->encoding);
}
return (string) $substring === $startOfStr;
@@ -1170,7 +1193,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$length = $end - $start;
}
$str = mb_substr($this->str, $start, $length, $this->encoding);
$str = \mb_substr($this->str, $start, $length, $this->encoding);
return static::create($str, $this->encoding);
}
@@ -1196,14 +1219,14 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
return array(static::create($this->str, $this->encoding));
}
$regexEncoding = mb_regex_encoding();
mb_regex_encoding($this->encoding);
$regexEncoding = \mb_regex_encoding();
\mb_regex_encoding($this->encoding);
// mb_split returns the remaining unsplit string in the last index when
// supplying a limit
$limit = ($limit > 0) ? $limit += 1 : -1;
$array = mb_split($pattern, $this->str, $limit);
mb_regex_encoding($regexEncoding);
$array = \mb_split($pattern, $this->str, $limit);
\mb_regex_encoding($regexEncoding);
if ($limit > 0 && count($array) === $limit) {
array_pop($array);
@@ -1228,7 +1251,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
public function substr($start, $length = null)
{
$length = $length === null ? $this->length() : $length;
$str = mb_substr($this->str, $start, $length, $this->encoding);
$str = \mb_substr($this->str, $start, $length, $this->encoding);
return static::create($str, $this->encoding);
}
@@ -1260,11 +1283,11 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
$stringy->str = preg_replace_callback(
'/[\S]/u',
function ($match) use ($encoding) {
if ($match[0] == mb_strtoupper($match[0], $encoding)) {
return mb_strtolower($match[0], $encoding);
} else {
return mb_strtoupper($match[0], $encoding);
if ($match[0] == \mb_strtoupper($match[0], $encoding)) {
return \mb_strtolower($match[0], $encoding);
}
return \mb_strtoupper($match[0], $encoding);
},
$stringy->str
);
@@ -1314,10 +1337,11 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
function ($match) use ($encoding, $ignore) {
if ($ignore && in_array($match[0], $ignore)) {
return $match[0];
} else {
$stringy = new Stringy($match[0], $encoding);
return (string) $stringy->toLowerCase()->upperCaseFirst();
}
$stringy = new Stringy($match[0], $encoding);
return (string) $stringy->toLowerCase()->upperCaseFirst();
},
$stringy->str
);
@@ -1377,10 +1401,10 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
if (array_key_exists($key, $map)) {
return $map[$key];
} elseif (is_numeric($this->str)) {
return (intval($this->str) > 0);
} else {
return (bool) $this->regexReplace('[[:space:]]', '')->str;
return (intval($this->str) > 0);
}
return (bool) $this->regexReplace('[[:space:]]', '')->str;
}
/**
@@ -1391,7 +1415,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function toLowerCase()
{
$str = mb_strtolower($this->str, $this->encoding);
$str = \mb_strtolower($this->str, $this->encoding);
return static::create($str, $this->encoding);
}
@@ -1434,7 +1458,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function toTitleCase()
{
$str = mb_convert_case($this->str, MB_CASE_TITLE, $this->encoding);
$str = \mb_convert_case($this->str, \MB_CASE_TITLE, $this->encoding);
return static::create($str, $this->encoding);
}
@@ -1447,7 +1471,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function toUpperCase()
{
$str = mb_strtoupper($this->str, $this->encoding);
$str = \mb_strtoupper($this->str, $this->encoding);
return static::create($str, $this->encoding);
}
@@ -1514,10 +1538,10 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
}
// Need to further trim the string so we can append the substring
$substringLength = mb_strlen($substring, $stringy->encoding);
$substringLength = \mb_strlen($substring, $stringy->encoding);
$length = $length - $substringLength;
$truncated = mb_substr($stringy->str, 0, $length, $stringy->encoding);
$truncated = \mb_substr($stringy->str, 0, $length, $stringy->encoding);
$stringy->str = $truncated . $substring;
return $stringy;
@@ -1555,11 +1579,11 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
public function upperCaseFirst()
{
$first = mb_substr($this->str, 0, 1, $this->encoding);
$rest = mb_substr($this->str, 1, $this->length() - 1,
$first = \mb_substr($this->str, 0, 1, $this->encoding);
$rest = \mb_substr($this->str, 1, $this->length() - 1,
$this->encoding);
$str = mb_strtoupper($first, $this->encoding) . $rest;
$str = \mb_strtoupper($first, $this->encoding) . $rest;
return static::create($str, $this->encoding);
}
@@ -1575,74 +1599,100 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
if (isset($charsArray)) return $charsArray;
return $charsArray = array(
'a' => array(
'à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', '', '', '',
'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ä', 'ā', 'ą',
'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', '', '', '',
'', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', '', '', '', '',
'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', '', '', 'а', 'أ'),
'b' => array('б', 'β', 'Ъ', 'Ь', '),
'0' => array('°', '₀', '۰'),
'1' => array('¹', '', '۱'),
'2' => array('²', '', '۲'),
'3' => array('³', '', '۳'),
'4' => array('', '', '۴', '٤'),
'5' => array('', '', '۵', '٥'),
'6' => array('', '', '۶', '٦'),
'7' => array('⁷', '₇', '۷'),
'8' => array('⁸', '₈', '۸'),
'9' => array('⁹', '₉', '۹'),
'a' => array('à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ',
'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ā', 'ą', 'å',
'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', 'ἇ',
'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', 'ά',
'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', 'အ',
'ာ', 'ါ', 'ǻ', 'ǎ', 'ª', 'ა', 'अ', 'ا'),
'b' => array('б', 'β', 'Ъ', 'Ь', 'ب', 'ဗ', 'ბ'),
'c' => array('ç', 'ć', 'č', 'ĉ', 'ċ'),
'd' => array('ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ',
'д', 'δ', 'د', 'ض'),
'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ'),
'e' => array('é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ',
'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ',
'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э',
'є', 'ə'),
'f' => array('ф', 'φ', 'ف'),
'g' => array('ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ج'),
'h' => array('ĥ', 'ħ', 'η', 'ή', 'ح', 'ه'),
'є', 'ə', 'ဧ', 'ေ', 'ဲ', 'ე', 'ए', 'إ', 'ئ'),
'f' => array('ф', 'φ', 'ف', 'ƒ', 'ფ'),
'g' => array('ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', '),
'h' => array('ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ'),
'i' => array('í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į',
'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ',
'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ',
'ῗ', 'і', 'ї', 'и'),
'j' => array('ĵ', 'ј', 'Ј'),
'k' => array('ķ', 'ĸ', ', 'κ', 'Ķ', 'ق', 'ك'),
'l' => array('ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل'),
'm' => array('м', 'μ', 'م'),
'n' => array('ñ', 'ń', 'ň', 'ņ', ', 'ŋ', 'ν', 'н', 'ن'),
'ῗ', 'і', 'ї', 'и', 'ဣ', 'ိ', 'ီ', 'ည်', 'ǐ', 'ი',
'', 'ی'),
'j' => array('ĵ', 'ј', 'Ј', '', 'ج'),
'k' => array('ķ', 'ĸ', 'к', ', 'Ķ', 'ق', 'ك', 'က', '', '', 'ک'),
'l' => array('ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', ', '', ''),
'm' => array('м', 'μ', 'م', '', ''),
'n' => array('ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န',
'ნ'),
'o' => array('ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ',
'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő',
'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό',
'ö', 'о', 'و', 'θ'),
'p' => array('п', 'π'),
'r' => array('ŕ', 'ř', 'ŗ', 'р', 'ρ', '),
's' => array('ś', 'š', ', 'с', 'σ', 'ș', 'ς', 'س', 'ص'),
't' => array('ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط'),
'о', 'و', ', 'ို', 'ǒ', 'ǿ', 'º', 'ო', 'ओ'),
'p' => array('п', 'π', 'ပ', 'პ', 'پ'),
'q' => array(''),
'r' => array('ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', ''),
's' => array('ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ',
'ſ', 'ს'),
't' => array('ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ',
'თ', 'ტ'),
'u' => array('ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ',
'ự', 'ü', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у'),
'v' => array('),
'w' => array('ŵ', 'ω', 'ώ'),
'x' => array('χ'),
'ự', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', 'ဉ',
'', 'ူ', 'ǔ', 'ǖ', 'ǘ', 'ǚ', 'ǜ', 'უ', 'उ'),
'v' => array('в', '', 'ϐ'),
'w' => array('ŵ', 'ω', 'ώ', '', 'ွ'),
'x' => array('χ', 'ξ'),
'y' => array('ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ',
'ϋ', 'ύ', 'ΰ', 'ي'),
'z' => array('ź', 'ž', 'ż', 'з', 'ζ', 'ز'),
'aa' => array('ع'),
'ae' => array('æ'),
'ch' => array('ч'),
'ϋ', 'ύ', 'ΰ', 'ي', 'ယ'),
'z' => array('ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ'),
'aa' => array('ع', 'आ', 'آ'),
'ae' => array('ä', 'æ', '),
'ai' => array(''),
'at' => array('@'),
'ch' => array('ч', 'ჩ', 'ჭ', 'چ'),
'dj' => array('ђ', 'đ'),
'dz' => array('џ'),
'gh' => array('غ'),
'kh' => array('х', 'خ'),
'dz' => array('џ', 'ძ'),
'ei' => array(''),
'gh' => array('غ', ''),
'ii' => array('ई'),
'ij' => array('ij'),
'kh' => array('х', 'خ', 'ხ'),
'lj' => array('љ'),
'nj' => array('њ'),
'oe' => array('œ'),
'oe' => array('ö', 'œ', '),
'oi' => array('ऑ'),
'oii' => array('ऒ'),
'ps' => array('ψ'),
'sh' => array('ш'),
'sh' => array('ш', 'შ', 'ش'),
'shch' => array('щ'),
'ss' => array('ß'),
'th' => array('þ', 'ث', 'ذ', '),
'ts' => array('ц'),
'sx' => array('ŝ'),
'th' => array('þ', 'ϑ', 'ث', 'ذ', '),
'ts' => array('ц', 'ც', 'წ'),
'ue' => array('ü'),
'uu' => array('ऊ'),
'ya' => array('я'),
'yu' => array('ю'),
'zh' => array('ж'),
'zh' => array('ж', 'ჟ', 'ژ'),
'(c)' => array('©'),
'A' => array('Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ',
'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Ä', 'Å', 'Ā',
'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ',
'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ',
'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А'),
'B' => array('Б', 'Β'),
'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Å', 'Ā', 'Ą',
'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', 'Ἇ',
'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', 'Ᾱ',
'Ὰ', 'Ά', 'ᾼ', 'А', 'Ǻ', 'Ǎ'),
'B' => array('Б', 'Β', 'ब'),
'C' => array('Ç','Ć', 'Č', 'Ĉ', 'Ċ'),
'D' => array('Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ'),
'E' => array('É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ',
@@ -1651,43 +1701,50 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
'Є', 'Ə'),
'F' => array('Ф', 'Φ'),
'G' => array('Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ'),
'H' => array('Η', 'Ή'),
'H' => array('Η', 'Ή', 'Ħ'),
'I' => array('Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į',
'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ',
'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї'),
'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', 'Ǐ', 'ϒ'),
'K' => array('К', 'Κ'),
'L' => array('Ĺ', 'Ł', 'Л', 'Λ', 'Ļ'),
'L' => array('Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल'),
'M' => array('М', 'Μ'),
'N' => array('Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν'),
'O' => array('Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ',
'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ö', 'Ø', 'Ō',
'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ',
'Ὸ', 'Ό', 'О', 'Θ', 'Ө'),
'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ø', 'Ō', 'Ő',
'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', 'Ὸ',
'Ό', 'О', 'Θ', 'Ө', 'Ǒ', 'Ǿ'),
'P' => array('П', 'Π'),
'R' => array('Ř', 'Ŕ', 'Р', 'Ρ'),
'R' => array('Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ'),
'S' => array('Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ'),
'T' => array('Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ'),
'U' => array('Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ',
'Ự', 'Û', 'Ü', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У'),
'Ự', 'Û', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', 'Ǔ', 'Ǖ',
'Ǘ', 'Ǚ', 'Ǜ'),
'V' => array('В'),
'W' => array('Ω', 'Ώ'),
'X' => array('Χ'),
'W' => array('Ω', 'Ώ', 'Ŵ'),
'X' => array('Χ', 'Ξ'),
'Y' => array('Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ',
'Ы', 'Й', 'Υ', 'Ϋ'),
'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ'),
'Z' => array('Ź', 'Ž', 'Ż', 'З', 'Ζ'),
'AE' => array('Æ'),
'AE' => array('Ä', 'Æ', '),
'CH' => array('Ч'),
'DJ' => array('Ђ'),
'DZ' => array('Џ'),
'GX' => array('Ĝ'),
'HX' => array('Ĥ'),
'IJ' => array('IJ'),
'JX' => array('Ĵ'),
'KH' => array('Х'),
'LJ' => array('Љ'),
'NJ' => array('Њ'),
'OE' => array('Ö', 'Œ'),
'PS' => array('Ψ'),
'SH' => array('Ш'),
'SHCH' => array('Щ'),
'SS' => array('ẞ'),
'TH' => array('Þ'),
'TS' => array('Ц'),
'UE' => array('Ü'),
'YA' => array('Я'),
'YU' => array('Ю'),
'ZH' => array('Ж'),
@@ -1711,7 +1768,7 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
private function applyPadding($left = 0, $right = 0, $padStr = ' ')
{
$stringy = static::create($this->str, $this->encoding);
$length = mb_strlen($padStr, $stringy->encoding);
$length = \mb_strlen($padStr, $stringy->encoding);
$strLength = $stringy->length();
$paddedLength = $strLength + $left + $right;
@@ -1720,9 +1777,9 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
return $stringy;
}
$leftPadding = mb_substr(str_repeat($padStr, ceil($left / $length)), 0,
$leftPadding = \mb_substr(str_repeat($padStr, ceil($left / $length)), 0,
$left, $stringy->encoding);
$rightPadding = mb_substr(str_repeat($padStr, ceil($right / $length)),
$rightPadding = \mb_substr(str_repeat($padStr, ceil($right / $length)),
0, $right, $stringy->encoding);
$stringy->str = $leftPadding . $stringy->str . $rightPadding;
@@ -1738,11 +1795,11 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
*/
private function matchesPattern($pattern)
{
$regexEncoding = mb_regex_encoding();
mb_regex_encoding($this->encoding);
$regexEncoding = \mb_regex_encoding();
\mb_regex_encoding($this->encoding);
$match = mb_ereg_match($pattern, $this->str);
mb_regex_encoding($regexEncoding);
$match = \mb_ereg_match($pattern, $this->str);
\mb_regex_encoding($regexEncoding);
return $match;
}

View File

@@ -1,7 +1,5 @@
<?php
require __DIR__ . '/../src/Create.php';
use function Stringy\create as s;
class CreateTestCase extends PHPUnit_Framework_TestCase

View File

@@ -0,0 +1,60 @@
<?php
use Stringy\StaticStringy as S;
class StaticStringyTestCase extends PHPUnit_Framework_TestCase
{
/**
* @expectedException BadMethodCallException
*/
public function testBadMethodCall()
{
$result = S::invalidMethod('foo');
}
public function testEmptyArgsInvocation()
{
$result = S::toLowerCase();
$this->assertEquals('', (string) $result);
}
public function testInvocation()
{
$result = S::toLowerCase('FOOBAR');
$this->assertEquals('foobar', (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);
}
}
}

View File

@@ -1,7 +1,5 @@
<?php
require __DIR__ . '/../src/Stringy.php';
use Stringy\Stringy as S;
class StringyTestCase extends PHPUnit_Framework_TestCase
@@ -24,6 +22,13 @@ class StringyTestCase extends PHPUnit_Framework_TestCase
$this->assertEquals('UTF-8', $stringy->getEncoding());
}
public function testEmptyConstruct()
{
$stringy = new S();
$this->assertStringy($stringy);
$this->assertEquals('', (string) $stringy);
}
/**
* @expectedException InvalidArgumentException
*/
@@ -2059,7 +2064,13 @@ class StringyTestCase extends PHPUnit_Framework_TestCase
public function isJsonProvider()
{
return array(
array(true, ''),
array(false, ''),
array(false, ' '),
array(true, 'null'),
array(true, 'true'),
array(true, 'false'),
array(true, '[]'),
array(true, '{}'),
array(true, '123'),
array(true, '{"foo": "bar"}'),
array(false, '{"foo":"bar",}'),
@@ -2157,6 +2168,31 @@ class StringyTestCase extends PHPUnit_Framework_TestCase
);
}
/**
* @dataProvider isBase64Provider()
*/
public function testIsBase64($expected, $str)
{
$stringy = S::create($str);
$result = $stringy->isBase64();
$this->assertInternalType('boolean', $result);
$this->assertEquals($expected, $result);
$this->assertEquals($str, $stringy);
}
public function isBase64Provider()
{
return array(
array(false, ' '),
array(true, ''),
array(true, base64_encode('FooBar') ),
array(true, base64_encode(' ') ),
array(true, base64_encode('FÒÔBÀŘ') ),
array(true, base64_encode('συγγραφέας') ),
array(false, 'Foobar'),
);
}
/**
* @dataProvider isUpperCaseProvider()
*/
@@ -2336,6 +2372,7 @@ class StringyTestCase extends PHPUnit_Framework_TestCase
array('foo', 'bar', '[[:alpha:]]{3}', 'foo'),
array('', '', '', '', 'msr', 'UTF-8'),
array('bàř', 'fòô ', 'f[òô]+\s', 'bàř', 'msr', 'UTF-8'),
array('fòô', 'fò', '(ò)', '\\1ô', 'msr', 'UTF-8'),
array('fòô', 'bàř', '[[:alpha:]]{3}', 'fòô', 'msr', 'UTF-8')
);
}