Version 5.1 - All the GraphQL #32
@ -1,8 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## Version 5.2
|
||||
* Updated PHP requirement to 8
|
||||
* Updated to support PHP 8.1
|
||||
* Updated PHP requirement to 8.1
|
||||
* Updated to support PHP 8.2
|
||||
* Improve Anilist <-> Kitsu mappings to be more reliable
|
||||
|
||||
## Version 5.1
|
||||
* Added session check, so when coming back to a page, if the session is expired, the page will refresh.
|
||||
|
6
justfile
6
justfile
@ -4,11 +4,11 @@ default:
|
||||
|
||||
# Runs rector, showing what changes will be make
|
||||
rector-dry-run:
|
||||
tools/vendor/bin/rector process --config=tools/rector.php --dry-run src
|
||||
tools/vendor/bin/rector process --config=tools/rector.php --dry-run src tests
|
||||
|
||||
# Runs rector, and updates the files
|
||||
# Runs rector, and updates the source files
|
||||
rector:
|
||||
tools/vendor/bin/rector process --config=tools/rector.php src
|
||||
tools/vendor/bin/rector process --config=tools/rector.php src tests
|
||||
|
||||
# Check code formatting
|
||||
check-fmt:
|
||||
|
@ -17,6 +17,9 @@ namespace Aviat\Ion\Attribute;
|
||||
use Attribute;
|
||||
|
||||
#[Attribute(Attribute::TARGET_CLASS)]
|
||||
class Controller {
|
||||
public function __construct(public string $prefix = '') {}
|
||||
}
|
||||
class Controller
|
||||
{
|
||||
public function __construct(public string $prefix = '')
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -17,4 +17,6 @@ namespace Aviat\Ion\Attribute;
|
||||
use Attribute;
|
||||
|
||||
#[Attribute(Attribute::TARGET_CLASS)]
|
||||
class DefaultController {}
|
||||
class DefaultController
|
||||
{
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ namespace Aviat\Ion\Attribute;
|
||||
use Attribute;
|
||||
|
||||
#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
|
||||
class Route {
|
||||
class Route
|
||||
{
|
||||
public const GET = 'get';
|
||||
public const POST = 'post';
|
||||
|
||||
@ -25,8 +26,6 @@ class Route {
|
||||
public string $name,
|
||||
public string $path,
|
||||
public string $verb = self::GET,
|
||||
)
|
||||
{
|
||||
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ class Container implements ContainerInterface
|
||||
*/
|
||||
public function __construct(
|
||||
/**
|
||||
* Array of container Generator functions
|
||||
*/
|
||||
* Array of container Generator functions
|
||||
*/
|
||||
protected array $container = []
|
||||
) {
|
||||
$this->loggers = [];
|
||||
|
@ -156,7 +156,7 @@ class ArrayType
|
||||
/**
|
||||
* Find an array key by its associated value
|
||||
*/
|
||||
public function search(mixed $value, bool $strict = TRUE): int|string|FALSE|null
|
||||
public function search(mixed $value, bool $strict = TRUE): int|string|false|null
|
||||
{
|
||||
return array_search($value, $this->arr, $strict);
|
||||
}
|
||||
@ -172,7 +172,7 @@ class ArrayType
|
||||
/**
|
||||
* Return the array, or a key
|
||||
*/
|
||||
public function &get(string|int|NULL $key = NULL): mixed
|
||||
public function &get(string|int|null $key = NULL): mixed
|
||||
{
|
||||
$value = NULL;
|
||||
if ($key === NULL)
|
||||
|
@ -21,7 +21,22 @@ use Exception;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use OutOfBoundsException;
|
||||
use RuntimeException;
|
||||
use Traversable;
|
||||
use function mb_convert_case;
|
||||
use function mb_ereg_match;
|
||||
use function mb_ereg_replace;
|
||||
use function mb_internal_encoding;
|
||||
use function mb_regex_encoding;
|
||||
use function mb_split;
|
||||
use function mb_stripos;
|
||||
use function mb_strlen;
|
||||
use function mb_strrpos;
|
||||
use function mb_strtolower;
|
||||
use function mb_strtoupper;
|
||||
use function mb_substr;
|
||||
use function mb_substr_count;
|
||||
use const MB_CASE_TITLE;
|
||||
|
||||
/**
|
||||
* Vendored, slightly modernized version of Stringy
|
||||
@ -29,16 +44,12 @@ use Traversable;
|
||||
abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
/**
|
||||
* An instance's string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $str;
|
||||
|
||||
/**
|
||||
* The string's encoding, which should be one of the mbstring module's
|
||||
* supported encodings.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $encoding;
|
||||
|
||||
@ -51,8 +62,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param mixed $str Value to modify, after being cast to string
|
||||
* @param string|null $encoding The character encoding
|
||||
* @throws \InvalidArgumentException if an array or object without a
|
||||
* __toString method is passed as the first argument
|
||||
* @throws InvalidArgumentException if an array or object without a
|
||||
* __toString method is passed as the first argument
|
||||
*/
|
||||
public function __construct(mixed $str = '', ?string $encoding = NULL)
|
||||
{
|
||||
@ -61,7 +72,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
throw new InvalidArgumentException(
|
||||
'Passed value cannot be an array'
|
||||
);
|
||||
} elseif (is_object($str) && ! method_exists($str, '__toString'))
|
||||
}
|
||||
if (is_object($str) && ! method_exists($str, '__toString'))
|
||||
{
|
||||
throw new InvalidArgumentException(
|
||||
'Passed object must have a __toString method'
|
||||
@ -69,7 +81,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
}
|
||||
|
||||
$this->str = (string)$str;
|
||||
$this->encoding = $encoding ?: \mb_internal_encoding();
|
||||
$this->encoding = $encoding ?: mb_internal_encoding();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,8 +94,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* @param mixed $str Value to modify, after being cast to string
|
||||
* @param string|null $encoding The character encoding
|
||||
* @return static A Stringy object
|
||||
* @throws \InvalidArgumentException if an array or object without a
|
||||
* __toString method is passed as the first argument
|
||||
* @throws InvalidArgumentException if an array or object without a
|
||||
* __toString method is passed as the first argument
|
||||
*/
|
||||
public static function create(mixed $str = '', ?string $encoding = NULL): self
|
||||
{
|
||||
@ -140,7 +152,7 @@ abstract 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)
|
||||
{
|
||||
@ -165,10 +177,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
$stringy->str = preg_replace_callback(
|
||||
'/[-_\s]+(.)?/u',
|
||||
function ($match) use ($encoding) {
|
||||
static function ($match) use ($encoding): string {
|
||||
if (isset($match[1]))
|
||||
{
|
||||
return \mb_strtoupper($match[1], $encoding);
|
||||
return mb_strtoupper($match[1], $encoding);
|
||||
}
|
||||
|
||||
return '';
|
||||
@ -178,9 +190,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
$stringy->str = preg_replace_callback(
|
||||
'/[\d]+(.)?/u',
|
||||
function ($match) use ($encoding) {
|
||||
return \mb_strtoupper($match[0], $encoding);
|
||||
},
|
||||
static fn($match) => mb_strtoupper($match[0], $encoding),
|
||||
$stringy->str
|
||||
);
|
||||
|
||||
@ -195,6 +205,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
public function chars(): array
|
||||
{
|
||||
$chars = [];
|
||||
|
||||
for ($i = 0, $l = $this->length(); $i < $l; $i++)
|
||||
{
|
||||
$chars[] = $this->at($i)->str;
|
||||
@ -222,7 +233,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $needle Substring to look for
|
||||
* @param bool $caseSensitive Whether or not to enforce case-sensitivity
|
||||
* @return bool Whether or not $str contains $needle
|
||||
* @return bool Whether or not $str contains $needle
|
||||
*/
|
||||
public function contains(string $needle, bool $caseSensitive = TRUE): bool
|
||||
{
|
||||
@ -230,10 +241,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
if ($caseSensitive)
|
||||
{
|
||||
return (\mb_strpos($this->str, $needle, 0, $encoding) !== FALSE);
|
||||
return \mb_strpos($this->str, $needle, 0, $encoding) !== FALSE;
|
||||
}
|
||||
|
||||
return (\mb_stripos($this->str, $needle, 0, $encoding) !== FALSE);
|
||||
return mb_stripos($this->str, $needle, 0, $encoding) !== FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,7 +254,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string[] $needles Substrings to look for
|
||||
* @param bool $caseSensitive Whether or not to enforce case-sensitivity
|
||||
* @return bool Whether or not $str contains $needle
|
||||
* @return bool Whether or not $str contains $needle
|
||||
*/
|
||||
public function containsAll(array $needles, bool $caseSensitive = TRUE): bool
|
||||
{
|
||||
@ -270,7 +281,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string[] $needles Substrings to look for
|
||||
* @param bool $caseSensitive Whether or not to enforce case-sensitivity
|
||||
* @return bool Whether or not $str contains $needle
|
||||
* @return bool Whether or not $str contains $needle
|
||||
*/
|
||||
public function containsAny(array $needles, bool $caseSensitive = TRUE): bool
|
||||
{
|
||||
@ -307,19 +318,19 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $substring The substring to search for
|
||||
* @param bool $caseSensitive Whether or not to enforce case-sensitivity
|
||||
* @return int The number of $substring occurrences
|
||||
* @return int The number of $substring occurrences
|
||||
*/
|
||||
public function countSubstr(string $substring, bool $caseSensitive = TRUE): int
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -349,7 +360,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
$this->regexEncoding($this->encoding);
|
||||
|
||||
$str = $this->eregReplace('\B([A-Z])', '-\1', $this->trim()->__toString());
|
||||
$str = \mb_strtolower($str, $this->encoding);
|
||||
$str = mb_strtolower($str, $this->encoding);
|
||||
$str = $this->eregReplace('[-_\s]+', $delimiter, $str);
|
||||
|
||||
$this->regexEncoding($regexEncoding);
|
||||
@ -364,20 +375,24 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $substring The substring to look for
|
||||
* @param bool $caseSensitive Whether or not to enforce case-sensitivity
|
||||
* @return bool Whether or not $str ends with $substring
|
||||
* @return bool Whether or not $str ends with $substring
|
||||
*/
|
||||
public function endsWith(string $substring, bool $caseSensitive = TRUE): bool
|
||||
{
|
||||
$substringLength = \mb_strlen($substring, $this->encoding);
|
||||
$substringLength = mb_strlen($substring, $this->encoding);
|
||||
$strLength = $this->length();
|
||||
|
||||
$endOfStr = \mb_substr($this->str, $strLength - $substringLength,
|
||||
$substringLength, $this->encoding);
|
||||
$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;
|
||||
@ -390,8 +405,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string[] $substrings Substrings to look for
|
||||
* @param bool $caseSensitive Whether or not to enforce
|
||||
* case-sensitivity
|
||||
* @return bool Whether or not $str ends with $substring
|
||||
* case-sensitivity
|
||||
* @return bool Whether or not $str ends with $substring
|
||||
*/
|
||||
public function endsWithAny(array $substrings, bool $caseSensitive = TRUE): bool
|
||||
{
|
||||
@ -462,6 +477,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
if ($n < 0)
|
||||
{
|
||||
$stringy->str = '';
|
||||
|
||||
return $stringy;
|
||||
}
|
||||
|
||||
@ -513,14 +529,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
return $this->matchesPattern('.*[[:upper:]]');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert all HTML entities to their applicable characters. An alias of
|
||||
* html_entity_decode. For a list of flags, refer to
|
||||
* http://php.net/manual/en/function.html-entity-decode.php
|
||||
*
|
||||
* @param int|null $flags Optional flags
|
||||
* @return static Object with the resulting $str after being html decoded.
|
||||
* @return static Object with the resulting $str after being html decoded.
|
||||
*/
|
||||
public function htmlDecode(?int $flags = ENT_COMPAT): self
|
||||
{
|
||||
@ -535,7 +550,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* for a list of flags.
|
||||
*
|
||||
* @param int|null $flags Optional flags
|
||||
* @return static Object with the resulting $str after being html encoded.
|
||||
* @return static Object with the resulting $str after being html encoded.
|
||||
*/
|
||||
public function htmlEncode(?int $flags = ENT_COMPAT): self
|
||||
{
|
||||
@ -564,12 +579,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $needle Substring to look for
|
||||
* @param int $offset Offset from which to search
|
||||
* @return int|bool The occurrence's index if found, otherwise false
|
||||
* @return bool|int The occurrence's index if found, otherwise false
|
||||
*/
|
||||
public function indexOf(string $needle, int $offset = 0): int|false
|
||||
{
|
||||
return \mb_strpos($this->str, (string)$needle,
|
||||
(int)$offset, $this->encoding);
|
||||
return \mb_strpos(
|
||||
$this->str,
|
||||
(string)$needle,
|
||||
(int)$offset,
|
||||
$this->encoding
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -580,12 +599,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $needle Substring to look for
|
||||
* @param int $offset Offset from which to search
|
||||
* @return int|bool The last occurrence's index if found, otherwise false
|
||||
* @return bool|int The last occurrence's index if found, otherwise false
|
||||
*/
|
||||
public function indexOfLast(string $needle, int $offset = 0): int|false
|
||||
{
|
||||
return \mb_strrpos($this->str, (string)$needle,
|
||||
(int)$offset, $this->encoding);
|
||||
return mb_strrpos(
|
||||
$this->str,
|
||||
(string)$needle,
|
||||
(int)$offset,
|
||||
$this->encoding
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -603,9 +626,13 @@ abstract 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(),
|
||||
$stringy->encoding);
|
||||
$start = mb_substr($stringy->str, 0, $index, $stringy->encoding);
|
||||
$end = mb_substr(
|
||||
$stringy->str,
|
||||
$index,
|
||||
$stringy->length(),
|
||||
$stringy->encoding
|
||||
);
|
||||
|
||||
$stringy->str = $start . $substring . $end;
|
||||
|
||||
@ -672,7 +699,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
json_decode($this->str);
|
||||
|
||||
return (json_last_error() === JSON_ERROR_NONE);
|
||||
return json_last_error() === JSON_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -696,7 +723,6 @@ abstract 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.
|
||||
*
|
||||
@ -704,7 +730,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function isBase64(): bool
|
||||
{
|
||||
return (base64_encode(base64_decode($this->str, TRUE)) === $this->str);
|
||||
return base64_encode(base64_decode($this->str, TRUE)) === $this->str;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -731,6 +757,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
if ($n <= 0)
|
||||
{
|
||||
$stringy->str = '';
|
||||
|
||||
return $stringy;
|
||||
}
|
||||
|
||||
@ -744,7 +771,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function length(): int
|
||||
{
|
||||
return \mb_strlen($this->str, $this->encoding);
|
||||
return mb_strlen($this->str, $this->encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -756,7 +783,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
public function lines(): array
|
||||
{
|
||||
$array = $this->split('[\r\n]{1,2}', $this->str);
|
||||
for ($i = 0; $i < count($array); $i++)
|
||||
$arrayCount = count($array);
|
||||
|
||||
for ($i = 0; $i < $arrayCount; $i++)
|
||||
{
|
||||
$array[$i] = static::create($array[$i], $this->encoding);
|
||||
}
|
||||
@ -773,14 +802,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
public function longestCommonPrefix(string $otherStr): self
|
||||
{
|
||||
$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
|
||||
@ -801,14 +831,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
public function longestCommonSuffix(string $otherStr): self
|
||||
{
|
||||
$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
|
||||
@ -834,28 +865,32 @@ abstract 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)
|
||||
if ($strLength === 0 || $otherLength === 0)
|
||||
{
|
||||
$stringy->str = '';
|
||||
|
||||
return $stringy;
|
||||
}
|
||||
|
||||
$len = 0;
|
||||
$end = 0;
|
||||
$table = array_fill(0, $strLength + 1,
|
||||
array_fill(0, $otherLength + 1, 0));
|
||||
$table = array_fill(
|
||||
0,
|
||||
$strLength + 1,
|
||||
array_fill(0, $otherLength + 1, 0)
|
||||
);
|
||||
|
||||
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)
|
||||
if ($strChar === $otherChar)
|
||||
{
|
||||
$table[$i][$j] = $table[$i - 1][$j - 1] + 1;
|
||||
if ($table[$i][$j] > $len)
|
||||
@ -870,7 +905,7 @@ abstract 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;
|
||||
}
|
||||
@ -882,11 +917,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function lowerCaseFirst(): self
|
||||
{
|
||||
$first = \mb_substr($this->str, 0, 1, $this->encoding);
|
||||
$rest = \mb_substr($this->str, 1, $this->length() - 1,
|
||||
$this->encoding);
|
||||
$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);
|
||||
}
|
||||
@ -897,7 +936,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* part of the ArrayAccess interface.
|
||||
*
|
||||
* @param mixed $offset The index to check
|
||||
* @return boolean Whether or not the index exists
|
||||
* @return bool Whether or not the index exists
|
||||
*/
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
@ -906,10 +945,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
if ($offset >= 0)
|
||||
{
|
||||
return ($length > $offset);
|
||||
return $length > $offset;
|
||||
}
|
||||
|
||||
return ($length >= abs($offset));
|
||||
return $length >= abs($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -919,9 +958,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* does not exist.
|
||||
*
|
||||
* @param mixed $offset The index from which to retrieve the char
|
||||
* @return string The character at the specified index
|
||||
* @throws \OutOfBoundsException If the positive or negative offset does
|
||||
* not exist
|
||||
* @return string The character at the specified index
|
||||
* @throws OutOfBoundsException If the positive or negative offset does
|
||||
* not exist
|
||||
*/
|
||||
public function offsetGet(mixed $offset): string
|
||||
{
|
||||
@ -933,7 +972,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -942,7 +981,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param mixed $offset The index of the character
|
||||
* @param mixed $value Value to set
|
||||
* @throws \Exception When called
|
||||
* @throws Exception When called
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
@ -955,7 +994,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* when called. This maintains the immutability of Stringy objects.
|
||||
*
|
||||
* @param mixed $offset The index of the character
|
||||
* @throws \Exception When called
|
||||
* @throws Exception When called
|
||||
*/
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
@ -979,7 +1018,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self
|
||||
{
|
||||
if ( ! in_array($padType, ['left', 'right', 'both']))
|
||||
if ( ! in_array($padType, ['left', 'right', 'both'], TRUE))
|
||||
{
|
||||
throw new InvalidArgumentException('Pad expects $padType ' .
|
||||
"to be one of 'left', 'right' or 'both'");
|
||||
@ -989,8 +1028,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
{
|
||||
case 'left':
|
||||
return $this->padLeft($length, $padStr);
|
||||
|
||||
case 'right':
|
||||
return $this->padRight($length, $padStr);
|
||||
|
||||
default:
|
||||
return $this->padBoth($length, $padStr);
|
||||
}
|
||||
@ -1008,8 +1049,11 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
{
|
||||
$padding = $length - $this->length();
|
||||
|
||||
return $this->applyPadding(floor($padding / 2), ceil($padding / 2),
|
||||
$padStr);
|
||||
return $this->applyPadding(
|
||||
floor($padding / 2),
|
||||
ceil($padding / 2),
|
||||
$padStr
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1084,7 +1128,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
if ($stringy->startsWith($substring))
|
||||
{
|
||||
$substringLength = \mb_strlen($substring, $stringy->encoding);
|
||||
$substringLength = mb_strlen($substring, $stringy->encoding);
|
||||
|
||||
return $stringy->substr($substringLength);
|
||||
}
|
||||
|
||||
@ -1103,7 +1148,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
if ($stringy->endsWith($substring))
|
||||
{
|
||||
$substringLength = \mb_strlen($substring, $stringy->encoding);
|
||||
$substringLength = mb_strlen($substring, $stringy->encoding);
|
||||
|
||||
return $stringy->substr(0, $stringy->length() - $substringLength);
|
||||
}
|
||||
|
||||
@ -1148,7 +1194,7 @@ abstract 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);
|
||||
@ -1174,19 +1220,19 @@ abstract 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)
|
||||
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);
|
||||
$lastPos = mb_strrpos($truncated, ' ', 0, $encoding);
|
||||
if ($lastPos !== FALSE)
|
||||
{
|
||||
$truncated = \mb_substr($truncated, 0, $lastPos, $encoding);
|
||||
$truncated = mb_substr($truncated, 0, $lastPos, $encoding);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1195,7 +1241,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
return $stringy;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* A multibyte str_shuffle() function. It returns a string with its
|
||||
* characters in random order.
|
||||
*
|
||||
@ -1207,9 +1253,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
shuffle($indexes);
|
||||
|
||||
$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);
|
||||
@ -1233,7 +1280,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
$stringy->str = str_replace('@', $replacement, $stringy);
|
||||
$quotedReplacement = preg_quote($replacement);
|
||||
$pattern = "/[^a-zA-Z\d\s-_$quotedReplacement]/u";
|
||||
$pattern = "/[^a-zA-Z\\d\\s-_{$quotedReplacement}]/u";
|
||||
$stringy->str = preg_replace($pattern, '', $stringy);
|
||||
|
||||
return $stringy->toLowerCase()->delimit($replacement)
|
||||
@ -1247,19 +1294,23 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $substring The substring to look for
|
||||
* @param bool $caseSensitive Whether or not to enforce
|
||||
* case-sensitivity
|
||||
* @return bool Whether or not $str starts with $substring
|
||||
* case-sensitivity
|
||||
* @return bool Whether or not $str starts with $substring
|
||||
*/
|
||||
public function startsWith(string $substring, bool $caseSensitive = TRUE): bool
|
||||
{
|
||||
$substringLength = \mb_strlen($substring, $this->encoding);
|
||||
$startOfStr = \mb_substr($this->str, 0, $substringLength,
|
||||
$this->encoding);
|
||||
$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;
|
||||
@ -1272,8 +1323,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string[] $substrings Substrings to look for
|
||||
* @param bool $caseSensitive Whether or not to enforce
|
||||
* case-sensitivity
|
||||
* @return bool Whether or not $str starts with $substring
|
||||
* case-sensitivity
|
||||
* @return bool Whether or not $str starts with $substring
|
||||
*/
|
||||
public function startsWithAny(array $substrings, bool $caseSensitive = TRUE): bool
|
||||
{
|
||||
@ -1303,7 +1354,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* @param int $end Optional index at which to end extraction
|
||||
* @return static Object with its $str being the extracted substring
|
||||
*/
|
||||
public function slice(int $start, int $end = NULL): self
|
||||
public function slice(int $start, ?int $end = NULL): self
|
||||
{
|
||||
if ($end === NULL)
|
||||
{
|
||||
@ -1331,7 +1382,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* @param int $limit Optional maximum number of results to return
|
||||
* @return static[] An array of Stringy objects
|
||||
*/
|
||||
public function split(string $pattern, int $limit = NULL): array
|
||||
public function split(string $pattern, ?int $limit = NULL): array
|
||||
{
|
||||
if ($limit === 0)
|
||||
{
|
||||
@ -1350,7 +1401,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
// mb_split returns the remaining unsplit string in the last index when
|
||||
// supplying a limit
|
||||
$limit = ($limit > 0) ? $limit += 1 : -1;
|
||||
$limit = ($limit > 0) ? ++$limit : -1;
|
||||
|
||||
static $functionExists;
|
||||
if ($functionExists === NULL)
|
||||
@ -1360,10 +1411,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
if ($functionExists)
|
||||
{
|
||||
$array = \mb_split($pattern, $this->str, $limit);
|
||||
} else if ($this->supportsEncoding())
|
||||
$array = mb_split($pattern, $this->str, $limit);
|
||||
} elseif ($this->supportsEncoding())
|
||||
{
|
||||
$array = \preg_split("/$pattern/", $this->str, $limit);
|
||||
$array = \preg_split("/{$pattern}/", $this->str, $limit);
|
||||
}
|
||||
|
||||
$this->regexEncoding($regexEncoding);
|
||||
@ -1372,8 +1423,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
{
|
||||
array_pop($array);
|
||||
}
|
||||
$arrayCount = count($array);
|
||||
|
||||
for ($i = 0; $i < count($array); $i++)
|
||||
for ($i = 0; $i < $arrayCount; $i++)
|
||||
{
|
||||
$array[$i] = static::create($array[$i], $this->encoding);
|
||||
}
|
||||
@ -1405,7 +1457,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
public function substr(int $start, ?int $length = NULL): self
|
||||
{
|
||||
$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);
|
||||
}
|
||||
@ -1415,7 +1467,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $substring The substring to add to both sides
|
||||
* @return static Object whose $str had the substring both prepended and
|
||||
* appended
|
||||
* appended
|
||||
*/
|
||||
public function surround(string $substring): self
|
||||
{
|
||||
@ -1436,13 +1488,13 @@ abstract 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))
|
||||
static function ($match) use ($encoding): string {
|
||||
if ($match[0] === mb_strtoupper($match[0], $encoding))
|
||||
{
|
||||
return \mb_strtolower($match[0], $encoding);
|
||||
return mb_strtolower($match[0], $encoding);
|
||||
}
|
||||
|
||||
return \mb_strtoupper($match[0], $encoding);
|
||||
return mb_strtoupper($match[0], $encoding);
|
||||
},
|
||||
$stringy->str
|
||||
);
|
||||
@ -1489,8 +1541,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
$stringy->str = preg_replace_callback(
|
||||
'/([\S]+)/u',
|
||||
function ($match) use ($encoding, $ignore) {
|
||||
if ($ignore && in_array($match[0], $ignore))
|
||||
static function ($match) use ($encoding, $ignore): string {
|
||||
if ($ignore && in_array($match[0], $ignore, TRUE))
|
||||
{
|
||||
return $match[0];
|
||||
}
|
||||
@ -1515,7 +1567,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*
|
||||
* @param string $language Language of the source string
|
||||
* @param bool $removeUnsupported Whether or not to remove the
|
||||
* unsupported characters
|
||||
* unsupported characters
|
||||
* @return static Object whose $str contains only ASCII characters
|
||||
*/
|
||||
public function toAscii(string $language = 'en', bool $removeUnsupported = TRUE): self
|
||||
@ -1563,15 +1615,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
'false' => FALSE,
|
||||
'0' => FALSE,
|
||||
'off' => FALSE,
|
||||
'no' => FALSE
|
||||
'no' => FALSE,
|
||||
];
|
||||
|
||||
if (array_key_exists($key, $map))
|
||||
{
|
||||
return $map[$key];
|
||||
} elseif (is_numeric($this->str))
|
||||
}
|
||||
if (is_numeric($this->str))
|
||||
{
|
||||
return (intval($this->str) > 0);
|
||||
return (int)($this->str) > 0;
|
||||
}
|
||||
|
||||
return (bool)$this->regexReplace('[[:space:]]', '')->str;
|
||||
@ -1585,7 +1638,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function toLowerCase(): self
|
||||
{
|
||||
$str = \mb_strtolower($this->str, $this->encoding);
|
||||
$str = mb_strtolower($this->str, $this->encoding);
|
||||
|
||||
return static::create($str, $this->encoding);
|
||||
}
|
||||
@ -1628,7 +1681,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function toTitleCase(): self
|
||||
{
|
||||
$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);
|
||||
}
|
||||
@ -1641,7 +1694,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function toUpperCase(): self
|
||||
{
|
||||
$str = \mb_strtoupper($this->str, $this->encoding);
|
||||
$str = mb_strtoupper($this->str, $this->encoding);
|
||||
|
||||
return static::create($str, $this->encoding);
|
||||
}
|
||||
@ -1658,7 +1711,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
{
|
||||
$chars = ($chars) ? preg_quote($chars) : '[:space:]';
|
||||
|
||||
return $this->regexReplace("^[$chars]+|[$chars]+\$", '');
|
||||
return $this->regexReplace("^[{$chars}]+|[{$chars}]+\$", '');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1673,7 +1726,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
{
|
||||
$chars = ($chars) ? preg_quote($chars) : '[:space:]';
|
||||
|
||||
return $this->regexReplace("^[$chars]+", '');
|
||||
return $this->regexReplace("^[{$chars}]+", '');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1688,7 +1741,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
{
|
||||
$chars = ($chars) ? preg_quote($chars) : '[:space:]';
|
||||
|
||||
return $this->regexReplace("[$chars]+\$", '');
|
||||
return $this->regexReplace("[{$chars}]+\$", '');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1709,10 +1762,10 @@ abstract 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;
|
||||
@ -1750,11 +1803,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
*/
|
||||
public function upperCaseFirst(): self
|
||||
{
|
||||
$first = \mb_substr($this->str, 0, 1, $this->encoding);
|
||||
$rest = \mb_substr($this->str, 1, $this->length() - 1,
|
||||
$this->encoding);
|
||||
$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);
|
||||
}
|
||||
@ -1767,7 +1824,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
protected function charsArray(): array
|
||||
{
|
||||
static $charsArray;
|
||||
if (isset($charsArray)) return $charsArray;
|
||||
if (isset($charsArray))
|
||||
{
|
||||
return $charsArray;
|
||||
}
|
||||
|
||||
return $charsArray = [
|
||||
'0' => ['°', '₀', '۰', '0'],
|
||||
@ -1940,7 +2000,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* will simply return 'a'.
|
||||
*
|
||||
* @param string $language Language of the source string
|
||||
* @return array An array of replacements.
|
||||
* @return array An array of replacements.
|
||||
*/
|
||||
protected static function langSpecificCharsArray(string $language = 'en'): array
|
||||
{
|
||||
@ -1960,17 +2020,11 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
],
|
||||
'bg' => [
|
||||
['х', 'Х', 'щ', 'Щ', 'ъ', 'Ъ', 'ь', 'Ь'],
|
||||
['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y']
|
||||
]
|
||||
['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'],
|
||||
],
|
||||
];
|
||||
|
||||
if (isset($languageSpecific[$language]))
|
||||
{
|
||||
$charsArray[$language] = $languageSpecific[$language];
|
||||
} else
|
||||
{
|
||||
$charsArray[$language] = [];
|
||||
}
|
||||
$charsArray[$language] = isset($languageSpecific[$language]) ? $languageSpecific[$language] : [];
|
||||
|
||||
return $charsArray[$language];
|
||||
}
|
||||
@ -1987,7 +2041,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
protected function applyPadding(int $left = 0, int $right = 0, string $padStr = ' '): self
|
||||
{
|
||||
$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;
|
||||
@ -1997,10 +2051,18 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
return $stringy;
|
||||
}
|
||||
|
||||
$leftPadding = \mb_substr(str_repeat($padStr, ceil($left / $length)), 0,
|
||||
$left, $stringy->encoding);
|
||||
$rightPadding = \mb_substr(str_repeat($padStr, ceil($right / $length)),
|
||||
0, $right, $stringy->encoding);
|
||||
$leftPadding = mb_substr(
|
||||
str_repeat($padStr, ceil($left / $length)),
|
||||
0,
|
||||
$left,
|
||||
$stringy->encoding
|
||||
);
|
||||
$rightPadding = mb_substr(
|
||||
str_repeat($padStr, ceil($right / $length)),
|
||||
0,
|
||||
$right,
|
||||
$stringy->encoding
|
||||
);
|
||||
|
||||
$stringy->str = $leftPadding . $stringy->str . $rightPadding;
|
||||
|
||||
@ -2011,14 +2073,14 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
* Returns true if $str matches the supplied pattern, false otherwise.
|
||||
*
|
||||
* @param string $pattern Regex pattern to match against
|
||||
* @return bool Whether or not $str matches the pattern
|
||||
* @return bool Whether or not $str matches the pattern
|
||||
*/
|
||||
protected function matchesPattern(string $pattern): bool
|
||||
{
|
||||
$regexEncoding = $this->regexEncoding();
|
||||
$this->regexEncoding($this->encoding);
|
||||
|
||||
$match = \mb_ereg_match($pattern, $this->str);
|
||||
$match = mb_ereg_match($pattern, $this->str);
|
||||
$this->regexEncoding($regexEncoding);
|
||||
|
||||
return $match;
|
||||
@ -2038,11 +2100,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
|
||||
if ($functionExists)
|
||||
{
|
||||
return \mb_ereg_replace($pattern, $replacement, $string, $option);
|
||||
} else if ($this->supportsEncoding())
|
||||
return mb_ereg_replace($pattern, $replacement, $string, $option);
|
||||
}
|
||||
if ($this->supportsEncoding())
|
||||
{
|
||||
$option = str_replace('r', '', (string)$option);
|
||||
return \preg_replace("/$pattern/u$option", $replacement, $string);
|
||||
|
||||
return \preg_replace("/{$pattern}/u{$option}", $replacement, $string);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2062,7 +2126,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
if ($functionExists)
|
||||
{
|
||||
$args = func_get_args();
|
||||
return call_user_func_array('\mb_regex_encoding', $args);
|
||||
|
||||
return mb_regex_encoding(...$args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2073,11 +2138,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess {
|
||||
if (isset($supported[$this->encoding]))
|
||||
{
|
||||
return TRUE;
|
||||
} else
|
||||
{
|
||||
throw new \RuntimeException('Stringy method requires the ' .
|
||||
'mbstring module for encodings other than ASCII and UTF-8. ' .
|
||||
'Encoding used: ' . $this->encoding);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Stringy method requires the ' .
|
||||
'mbstring module for encodings other than ASCII and UTF-8. ' .
|
||||
'Encoding used: ' . $this->encoding);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use InvalidArgumentException;
|
||||
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||
use PHPUnit\Framework\Attributes\CodeCoverageIgnore;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Stringable;
|
||||
|
||||
@ -168,10 +169,10 @@ class HttpView implements HttpViewInterface, Stringable
|
||||
/**
|
||||
* Send the appropriate response
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @throws DoubleRenderException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
#[CodeCoverageIgnore]
|
||||
protected function output(): void
|
||||
{
|
||||
if ($this->hasRendered)
|
||||
|
@ -46,7 +46,7 @@ final class AnimeListTransformerTest extends AnimeClientTestCase
|
||||
$this->assertMatchesSnapshot($actual);
|
||||
}
|
||||
|
||||
public function dataUntransform(): array
|
||||
public static function dataUntransform(): array
|
||||
{
|
||||
return [[
|
||||
'input' => [
|
||||
@ -87,12 +87,10 @@ final class AnimeListTransformerTest extends AnimeClientTestCase
|
||||
]];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataUntransform
|
||||
*/
|
||||
public function testUntransform(array $input): void
|
||||
{
|
||||
$actual = $this->transformer->untransform($input);
|
||||
$this->assertMatchesSnapshot($actual);
|
||||
}
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataUntransform')]
|
||||
public function testUntransform(array $input): void
|
||||
{
|
||||
$actual = $this->transformer->untransform($input);
|
||||
$this->assertMatchesSnapshot($actual);
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ final class DispatcherTest extends AnimeClientTestCase
|
||||
$this->assertIsObject($this->router);
|
||||
}
|
||||
|
||||
public function dataRoute(): array
|
||||
public static function dataRoute(): array
|
||||
{
|
||||
$defaultConfig = [
|
||||
'routes' => [
|
||||
@ -141,35 +141,32 @@ final class DispatcherTest extends AnimeClientTestCase
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataRoute
|
||||
* @param mixed $config
|
||||
* @param mixed $controller
|
||||
* @param mixed $host
|
||||
* @param mixed $uri
|
||||
*/
|
||||
public function testRoute($config, $controller, $host, $uri): void
|
||||
{
|
||||
$this->doSetUp($config, $uri, $host);
|
||||
/**
|
||||
* @param mixed $config
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataRoute')]
|
||||
public function testRoute($config, mixed $controller, mixed $host, mixed $uri): void
|
||||
{
|
||||
$this->doSetUp($config, $uri, $host);
|
||||
|
||||
$request = $this->container->get('request');
|
||||
$request = $this->container->get('request');
|
||||
|
||||
// Check route setup
|
||||
$this->assertSame($config['routes'], $this->config->get('routes'), 'Incorrect route path');
|
||||
$this->assertIsArray($this->router->getOutputRoutes());
|
||||
// Check route setup
|
||||
$this->assertSame($config['routes'], $this->config->get('routes'), 'Incorrect route path');
|
||||
$this->assertIsArray($this->router->getOutputRoutes());
|
||||
|
||||
// Check environment variables
|
||||
$this->assertSame($uri, $request->getServerParams()['REQUEST_URI']);
|
||||
$this->assertSame($host, $request->getServerParams()['HTTP_HOST']);
|
||||
// Check environment variables
|
||||
$this->assertSame($uri, $request->getServerParams()['REQUEST_URI']);
|
||||
$this->assertSame($host, $request->getServerParams()['HTTP_HOST']);
|
||||
|
||||
// Make sure the route is an anime type
|
||||
//$this->assertTrue($matcher->count() > 0, '0 routes');
|
||||
$this->assertSame($controller, $this->router->getController(), 'Incorrect Route type');
|
||||
// Make sure the route is an anime type
|
||||
//$this->assertTrue($matcher->count() > 0, '0 routes');
|
||||
$this->assertSame($controller, $this->router->getController(), 'Incorrect Route type');
|
||||
|
||||
// Make sure the route matches, by checking that it is actually an object
|
||||
$route = $this->router->getRoute();
|
||||
$this->assertInstanceOf(Route::class, $route, 'Route is invalid, not matched');
|
||||
}
|
||||
// Make sure the route matches, by checking that it is actually an object
|
||||
$route = $this->router->getRoute();
|
||||
$this->assertInstanceOf(Route::class, $route, 'Route is invalid, not matched');
|
||||
}
|
||||
|
||||
public function testDefaultRoute(): void
|
||||
{
|
||||
@ -209,53 +206,51 @@ final class DispatcherTest extends AnimeClientTestCase
|
||||
}
|
||||
|
||||
#[ArrayShape(['controller_list_sanity_check' => 'array', 'empty_controller_list' => 'array'])]
|
||||
public function dataGetControllerList(): array
|
||||
{
|
||||
$expectedList = [
|
||||
'anime' => Controller\Anime::class,
|
||||
'anime-collection' => Controller\AnimeCollection::class,
|
||||
'character' => Controller\Character::class,
|
||||
'misc' => Controller\Misc::class,
|
||||
'manga' => Controller\Manga::class,
|
||||
'people' => Controller\People::class,
|
||||
'settings' => Controller\Settings::class,
|
||||
'user' => Controller\User::class,
|
||||
'images' => Controller\Images::class,
|
||||
'history' => Controller\History::class,
|
||||
];
|
||||
public static function dataGetControllerList(): array
|
||||
{
|
||||
$expectedList = [
|
||||
'anime' => Controller\Anime::class,
|
||||
'anime-collection' => Controller\AnimeCollection::class,
|
||||
'character' => Controller\Character::class,
|
||||
'misc' => Controller\Misc::class,
|
||||
'manga' => Controller\Manga::class,
|
||||
'people' => Controller\People::class,
|
||||
'settings' => Controller\Settings::class,
|
||||
'user' => Controller\User::class,
|
||||
'images' => Controller\Images::class,
|
||||
'history' => Controller\History::class,
|
||||
];
|
||||
|
||||
return [
|
||||
'controller_list_sanity_check' => [
|
||||
'config' => [
|
||||
'anime_path' => 'anime',
|
||||
'manga_path' => 'manga',
|
||||
'default_anime_list_path' => 'watching',
|
||||
'default_manga_list_path' => 'all',
|
||||
'default_list' => 'manga',
|
||||
'routes' => [],
|
||||
],
|
||||
'expected' => $expectedList,
|
||||
return [
|
||||
'controller_list_sanity_check' => [
|
||||
'config' => [
|
||||
'anime_path' => 'anime',
|
||||
'manga_path' => 'manga',
|
||||
'default_anime_list_path' => 'watching',
|
||||
'default_manga_list_path' => 'all',
|
||||
'default_list' => 'manga',
|
||||
'routes' => [],
|
||||
],
|
||||
'empty_controller_list' => [
|
||||
'config' => [
|
||||
'anime_path' => 'anime',
|
||||
'manga_path' => 'manga',
|
||||
'default_anime_path' => '/anime/watching',
|
||||
'default_manga_path' => '/manga/all',
|
||||
'default_list' => 'manga',
|
||||
'routes' => [],
|
||||
],
|
||||
'expected' => $expectedList,
|
||||
'expected' => $expectedList,
|
||||
],
|
||||
'empty_controller_list' => [
|
||||
'config' => [
|
||||
'anime_path' => 'anime',
|
||||
'manga_path' => 'manga',
|
||||
'default_anime_path' => '/anime/watching',
|
||||
'default_manga_path' => '/manga/all',
|
||||
'default_list' => 'manga',
|
||||
'routes' => [],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGetControllerList
|
||||
*/
|
||||
public function testGetControllerList(array $config, array $expected): void
|
||||
{
|
||||
$this->doSetUp($config, '/', 'localhost');
|
||||
$this->assertEquals($expected, $this->router->getControllerList());
|
||||
}
|
||||
'expected' => $expectedList,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataGetControllerList')]
|
||||
public function testGetControllerList(array $config, array $expected): void
|
||||
{
|
||||
$this->doSetUp($config, '/', 'localhost');
|
||||
$this->assertEquals($expected, $this->router->getControllerList());
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,7 @@ use Aviat\AnimeClient\Tests\AnimeClientTestCase;
|
||||
*/
|
||||
final class PictureHelperTest extends AnimeClientTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider dataPictureCase
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataPictureCase')]
|
||||
public function testPictureHelper(array $params): void
|
||||
{
|
||||
$helper = new PictureHelper();
|
||||
@ -35,9 +33,7 @@ final class PictureHelperTest extends AnimeClientTestCase
|
||||
$this->assertMatchesSnapshot($actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataSimpleImageCase
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataSimpleImageCase')]
|
||||
public function testSimpleImage(string $ext, bool $isSimple, string $fallbackExt = 'jpg'): void
|
||||
{
|
||||
$helper = new PictureHelper();
|
||||
@ -61,7 +57,7 @@ final class PictureHelperTest extends AnimeClientTestCase
|
||||
$this->assertTrue( ! str_contains($actual, '<picture'));
|
||||
}
|
||||
|
||||
public function dataPictureCase(): array
|
||||
public static function dataPictureCase(): array
|
||||
{
|
||||
return [
|
||||
'Full AVIF URL' => [
|
||||
@ -119,7 +115,7 @@ final class PictureHelperTest extends AnimeClientTestCase
|
||||
];
|
||||
}
|
||||
|
||||
public function dataSimpleImageCase(): array
|
||||
public static function dataSimpleImageCase(): array
|
||||
{
|
||||
return [
|
||||
'avif' => [
|
||||
|
@ -77,7 +77,7 @@ final class KitsuTest extends TestCase
|
||||
$this->assertSame(AnimeAiringStatus::AIRING, Kitsu::getAiringStatus('yesterday'));
|
||||
}
|
||||
|
||||
public function getPublishingStatus(): array
|
||||
public static function getPublishingStatus(): array
|
||||
{
|
||||
return [
|
||||
'current' => [
|
||||
@ -91,16 +91,14 @@ final class KitsuTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPublishingStatus
|
||||
*/
|
||||
public function testGetPublishingStatus(string $kitsuStatus, string $expected): void
|
||||
{
|
||||
$actual = Kitsu::getPublishingStatus($kitsuStatus);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('getPublishingStatus')]
|
||||
public function testGetPublishingStatus(string $kitsuStatus, string $expected): void
|
||||
{
|
||||
$actual = Kitsu::getPublishingStatus($kitsuStatus);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
public function getFriendlyTime(): array
|
||||
public static function getFriendlyTime(): array
|
||||
{
|
||||
$SECONDS_IN_DAY = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_DAY;
|
||||
$SECONDS_IN_HOUR = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_HOUR;
|
||||
@ -121,15 +119,13 @@ final class KitsuTest extends TestCase
|
||||
]];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getFriendlyTime
|
||||
*/
|
||||
public function testGetFriendlyTime(int $seconds, string $expected): void
|
||||
{
|
||||
$actual = Kitsu::friendlyTime($seconds);
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('getFriendlyTime')]
|
||||
public function testGetFriendlyTime(int $seconds, string $expected): void
|
||||
{
|
||||
$actual = Kitsu::friendlyTime($seconds);
|
||||
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
public function testFilterLocalizedTitles(): void
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ use JetBrains\PhpStorm\ArrayShape;
|
||||
final class RoutingBaseTest extends AnimeClientTestCase
|
||||
{
|
||||
#[ArrayShape(['empty_segment' => 'array', 'three_segments' => 'array'])]
|
||||
public function dataSegments()
|
||||
public static function dataSegments()
|
||||
{
|
||||
return [
|
||||
'empty_segment' => [
|
||||
@ -41,26 +41,24 @@ final class RoutingBaseTest extends AnimeClientTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataSegments
|
||||
*/
|
||||
public function testSegments(string $requestUri, string $path, array $segments, ?string $lastSegment): void
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $requestUri,
|
||||
],
|
||||
]);
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataSegments')]
|
||||
public function testSegments(string $requestUri, string $path, array $segments, ?string $lastSegment): void
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $requestUri,
|
||||
],
|
||||
]);
|
||||
|
||||
$routingBase = new RoutingBase($this->container);
|
||||
$routingBase = new RoutingBase($this->container);
|
||||
|
||||
$this->assertSame($path, $routingBase->path(), 'Path is invalid');
|
||||
$this->assertSame($segments, $routingBase->segments(), 'Segments array is invalid');
|
||||
$this->assertEquals($lastSegment, $routingBase->lastSegment(), 'Last segment is invalid');
|
||||
$this->assertSame($path, $routingBase->path(), 'Path is invalid');
|
||||
$this->assertSame($segments, $routingBase->segments(), 'Segments array is invalid');
|
||||
$this->assertEquals($lastSegment, $routingBase->lastSegment(), 'Last segment is invalid');
|
||||
|
||||
foreach ($segments as $i => $value)
|
||||
{
|
||||
$this->assertEquals($value, $routingBase->getSegment($i), "Segment {$i} is invalid");
|
||||
}
|
||||
}
|
||||
foreach ($segments as $i => $value)
|
||||
{
|
||||
$this->assertEquals($value, $routingBase->getSegment($i), "Segment {$i} is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,13 +16,14 @@ namespace Aviat\AnimeClient\Tests;
|
||||
|
||||
use Aviat\AnimeClient\UrlGenerator;
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class UrlGeneratorTest extends AnimeClientTestCase
|
||||
{
|
||||
public function assetUrlProvider()
|
||||
public static function assetUrlProvider(): array
|
||||
{
|
||||
return [
|
||||
'single argument' => [
|
||||
@ -40,12 +41,8 @@ final class UrlGeneratorTest extends AnimeClientTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider assetUrlProvider
|
||||
* @param mixed $args
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testAssetUrl($args, $expected)
|
||||
#[DataProvider('assetUrlProvider')]
|
||||
public function testAssetUrl(mixed $args, string $expected): void
|
||||
{
|
||||
$urlGenerator = new UrlGenerator($this->container);
|
||||
|
||||
|
@ -47,7 +47,7 @@ final class UtilTest extends AnimeClientTestCase
|
||||
$this->assertSame('', Util::isNotSelected('foo', 'foo'));
|
||||
}
|
||||
|
||||
public function dataIsViewPage()
|
||||
public static function dataIsViewPage()
|
||||
{
|
||||
return [
|
||||
[
|
||||
@ -69,35 +69,34 @@ final class UtilTest extends AnimeClientTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataIsViewPage
|
||||
* @param mixed $uri
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testIsViewPage($uri, $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri,
|
||||
],
|
||||
]);
|
||||
$this->assertSame($expected, $this->util->isViewPage());
|
||||
}
|
||||
/**
|
||||
* @param mixed $uri
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataIsViewPage')]
|
||||
public function testIsViewPage($uri, mixed $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri,
|
||||
],
|
||||
]);
|
||||
$this->assertSame($expected, $this->util->isViewPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataIsViewPage
|
||||
* @param mixed $uri
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testIsFormPage($uri, $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri,
|
||||
],
|
||||
]);
|
||||
$this->assertSame( ! $expected, $this->util->isFormPage());
|
||||
}
|
||||
/**
|
||||
* @param mixed $uri
|
||||
* @param mixed $expected
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataIsViewPage')]
|
||||
public function testIsFormPage($uri, $expected)
|
||||
{
|
||||
$this->setSuperGlobals([
|
||||
'_SERVER' => [
|
||||
'REQUEST_URI' => $uri,
|
||||
],
|
||||
]);
|
||||
$this->assertSame( ! $expected, $this->util->isFormPage());
|
||||
}
|
||||
|
||||
public function testAriaCurrent(): void
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
namespace Aviat\Ion\Tests;
|
||||
|
||||
use Aviat\Ion\Config;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -67,7 +68,7 @@ final class ConfigTest extends IonTestCase
|
||||
$this->assertSame('great', $this->config->get(['apple', 'sauce', 'is']), 'Array argument get for config failed.');
|
||||
}
|
||||
|
||||
public function dataConfigDelete(): array
|
||||
public static function dataConfigDelete(): array
|
||||
{
|
||||
return [
|
||||
'top level delete' => [
|
||||
@ -124,11 +125,8 @@ final class ConfigTest extends IonTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataConfigDelete
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function testConfigDelete($key, array $assertKeys): void
|
||||
#[DataProvider('dataConfigDelete')]
|
||||
public function testConfigDelete(string|array $key, array $assertKeys): void
|
||||
{
|
||||
$config = new Config([]);
|
||||
$config->set(['apple', 'sauce', 'is'], 'great');
|
||||
|
@ -20,6 +20,7 @@ use Aviat\Ion\Di\{Container, ContainerAware};
|
||||
use Aviat\Ion\Tests\IonTestCase;
|
||||
use Monolog\Handler\{NullHandler, TestHandler};
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Throwable;
|
||||
use TypeError;
|
||||
|
||||
@ -51,7 +52,7 @@ final class ContainerTest extends IonTestCase
|
||||
$this->container = new Container();
|
||||
}
|
||||
|
||||
public function dataGetWithException(): array
|
||||
public static function dataGetWithException(): array
|
||||
{
|
||||
return [
|
||||
'Bad index type: number' => [
|
||||
@ -71,9 +72,9 @@ final class ContainerTest extends IonTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGetWithException
|
||||
* @param mixed $exception
|
||||
*/
|
||||
#[DataProvider('dataGetWithException')]
|
||||
public function testGetWithException(mixed $id, $exception, ?string $message = NULL): void
|
||||
{
|
||||
try
|
||||
@ -92,9 +93,9 @@ final class ContainerTest extends IonTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGetWithException
|
||||
* @param mixed $exception
|
||||
*/
|
||||
#[DataProvider('dataGetWithException')]
|
||||
public function testGetNewWithException(mixed $id, $exception, ?string $message = NULL): void
|
||||
{
|
||||
$this->expectException($exception);
|
||||
@ -106,7 +107,7 @@ final class ContainerTest extends IonTestCase
|
||||
$this->container->getNew($id);
|
||||
}
|
||||
|
||||
public function dataSetInstanceWithException(): array
|
||||
public static function dataSetInstanceWithException(): array
|
||||
{
|
||||
return [
|
||||
'Non-existent id' => [
|
||||
@ -123,11 +124,11 @@ final class ContainerTest extends IonTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataSetInstanceWithException
|
||||
* @param mixed $id
|
||||
* @param mixed $exception
|
||||
* @param mixed $message
|
||||
*/
|
||||
#[DataProvider('dataSetInstanceWithException')]
|
||||
public function testSetInstanceWithException($id, $exception, $message): void
|
||||
{
|
||||
try
|
||||
|
@ -19,6 +19,7 @@ namespace Aviat\Ion\Tests;
|
||||
*/
|
||||
final class EnumTest extends IonTestCase
|
||||
{
|
||||
public $enum;
|
||||
protected $expectedConstList = [
|
||||
'FOO' => 'bar',
|
||||
'BAR' => 'foo',
|
||||
@ -43,7 +44,7 @@ final class EnumTest extends IonTestCase
|
||||
$this->assertSame($this->expectedConstList, $actual);
|
||||
}
|
||||
|
||||
public function dataIsValid()
|
||||
public static function dataIsValid()
|
||||
{
|
||||
return [
|
||||
'Valid' => [
|
||||
@ -69,18 +70,17 @@ final class EnumTest extends IonTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataIsValid
|
||||
* @param mixed $value
|
||||
* @param mixed $expected
|
||||
* @param mixed $static
|
||||
*/
|
||||
public function testIsValid($value, $expected, $static)
|
||||
{
|
||||
$actual = ($static)
|
||||
? TestEnum::isValid($value)
|
||||
: $this->enum->isValid($value);
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param mixed $static
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataIsValid')]
|
||||
public function testIsValid($value, mixed $expected, $static)
|
||||
{
|
||||
$actual = ($static)
|
||||
? TestEnum::isValid($value)
|
||||
: $this->enum->isValid($value);
|
||||
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ final class JsonTest extends IonTestCase
|
||||
$this->assertSame($expected, Json::encode($data));
|
||||
}
|
||||
|
||||
public function dataEncodeDecode(): array
|
||||
public static function dataEncodeDecode(): array
|
||||
{
|
||||
return [
|
||||
'set1' => [
|
||||
@ -47,24 +47,22 @@ final class JsonTest extends IonTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataEncodeDecode
|
||||
*/
|
||||
public function testEncodeDecodeFile(array $data, int $expected_size, string $expected_json): void
|
||||
{
|
||||
$target_file = _dir(self::TEST_DATA_DIR, 'json_write.json');
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataEncodeDecode')]
|
||||
public function testEncodeDecodeFile(array $data, int $expected_size, string $expected_json): void
|
||||
{
|
||||
$target_file = _dir(self::TEST_DATA_DIR, 'json_write.json');
|
||||
|
||||
$actual_size = Json::encodeFile($target_file, $data);
|
||||
$actual_json = file_get_contents($target_file);
|
||||
$actual_size = Json::encodeFile($target_file, $data);
|
||||
$actual_json = file_get_contents($target_file);
|
||||
|
||||
$this->assertTrue(Json::isJson($actual_json));
|
||||
$this->assertSame($expected_size, $actual_size);
|
||||
$this->assertSame($expected_json, $actual_json);
|
||||
$this->assertTrue(Json::isJson($actual_json));
|
||||
$this->assertSame($expected_size, $actual_size);
|
||||
$this->assertSame($expected_json, $actual_json);
|
||||
|
||||
$this->assertEquals($data, Json::decodeFile($target_file));
|
||||
$this->assertEquals($data, Json::decodeFile($target_file));
|
||||
|
||||
unlink($target_file);
|
||||
}
|
||||
unlink($target_file);
|
||||
}
|
||||
|
||||
public function testDecode()
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ final class AbstractTransformerTest extends IonTestCase
|
||||
$this->untransformer = new TestTransformerUntransform();
|
||||
}
|
||||
|
||||
public function dataTransformCollection()
|
||||
public static function dataTransformCollection()
|
||||
{
|
||||
return [
|
||||
'object' => [
|
||||
@ -90,7 +90,7 @@ final class AbstractTransformerTest extends IonTestCase
|
||||
];
|
||||
}
|
||||
|
||||
public function dataUnTransformCollection()
|
||||
public static function dataUnTransformCollection()
|
||||
{
|
||||
return [
|
||||
'object' => [
|
||||
@ -130,36 +130,34 @@ final class AbstractTransformerTest extends IonTestCase
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTransformCollection
|
||||
* @param mixed $original
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testTransformCollection($original, $expected)
|
||||
{
|
||||
$actual = $this->transformer->transformCollection($original);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
/**
|
||||
* @param mixed $original
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataTransformCollection')]
|
||||
public function testTransformCollection($original, mixed $expected)
|
||||
{
|
||||
$actual = $this->transformer->transformCollection($original);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataUnTransformCollection
|
||||
* @param mixed $original
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testUntransformCollection($original, $expected)
|
||||
{
|
||||
$actual = $this->untransformer->untransformCollection($original);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
/**
|
||||
* @param mixed $original
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataUnTransformCollection')]
|
||||
public function testUntransformCollection($original, mixed $expected)
|
||||
{
|
||||
$actual = $this->untransformer->untransformCollection($original);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataUnTransformCollection
|
||||
* @param mixed $original
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testUntransformCollectionWithException($original, $expected)
|
||||
{
|
||||
$this->expectException(BadMethodCallException::class);
|
||||
$this->transformer->untransformCollection($original);
|
||||
}
|
||||
/**
|
||||
* @param mixed $original
|
||||
* @param mixed $expected
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataUnTransformCollection')]
|
||||
public function testUntransformCollectionWithException($original, $expected)
|
||||
{
|
||||
$this->expectException(BadMethodCallException::class);
|
||||
$this->transformer->untransformCollection($original);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ use Aviat\Ion\Type\ArrayType;
|
||||
*/
|
||||
final class ArrayTypeTest extends IonTestCase
|
||||
{
|
||||
public function dataCall()
|
||||
public static function dataCall()
|
||||
{
|
||||
$method_map = [
|
||||
'chunk' => 'array_chunk',
|
||||
@ -80,18 +80,16 @@ final class ArrayTypeTest extends IonTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the array methods defined for the __Call method
|
||||
*
|
||||
* @dataProvider dataCall
|
||||
* @param $expected
|
||||
*/
|
||||
public function testCall(string $method, array $array, array $args, $expected): void
|
||||
{
|
||||
$obj = ArrayType::from($array);
|
||||
$actual = $obj->__call($method, $args);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
/**
|
||||
* Test the array methods defined for the __Call method
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataCall')]
|
||||
public function testCall(string $method, array $array, array $args, mixed $expected): void
|
||||
{
|
||||
$obj = ArrayType::from($array);
|
||||
$actual = $obj->__call($method, $args);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
public function testSet(): void
|
||||
{
|
||||
|
@ -16,13 +16,14 @@ namespace Aviat\Ion\Tests\Type;
|
||||
|
||||
use Aviat\Ion\Tests\IonTestCase;
|
||||
use Aviat\Ion\Type\StringType;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class StringTypeTest extends IonTestCase
|
||||
{
|
||||
public function dataFuzzyCaseMatch(): array
|
||||
public static function dataFuzzyCaseMatch(): array
|
||||
{
|
||||
return [
|
||||
'space separated' => [
|
||||
@ -53,9 +54,7 @@ final class StringTypeTest extends IonTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataFuzzyCaseMatch
|
||||
*/
|
||||
#[DataProvider('dataFuzzyCaseMatch')]
|
||||
public function testFuzzyCaseMatch(string $str1, string $str2, bool $expected): void
|
||||
{
|
||||
$actual = StringType::from($str1)->fuzzyCaseMatch($str2);
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"require": {
|
||||
"friendsofphp/php-cs-fixer": "^3.6",
|
||||
"rector/rector": "^0.12.16"
|
||||
"rector/rector": "^0.15.21"
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,11 @@
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 8
|
||||
* PHP version 8.1
|
||||
*
|
||||
* @copyright 2015 - 2022 Timothy J. Warren <tim@timshome.page>
|
||||
* @copyright 2015 - 2023 Timothy J. Warren <tim@timshome.page>
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 5.2
|
||||
* @link https://git.timshome.page/timw4mail/HummingBirdAnimeClient
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
|
0
tools/offline-db-update.php
Normal file
0
tools/offline-db-update.php
Normal file
@ -1,65 +1,54 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
use Rector\CodeQuality\Rector\BooleanNot\SimplifyDeMorganBinaryRector;
|
||||
use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector;
|
||||
use Rector\CodeQuality\Rector\For_\{ForRepeatedCountToOwnVariableRector, ForToForeachRector};
|
||||
use Rector\CodeQuality\Rector\If_\{ConsecutiveNullCompareReturnsToNullCoalesceQueueRector, SimplifyIfElseToTernaryRector, SimplifyIfReturnBoolRector};
|
||||
use Rector\CodeQuality\Rector\Ternary\{SimplifyDuplicatedTernaryRector, SimplifyTautologyTernaryRector, SwitchNegatedTernaryRector};
|
||||
use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector;
|
||||
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
|
||||
use Rector\Php81\Rector\Property\ReadOnlyPropertyRector;
|
||||
use Rector\Set\ValueObject\LevelSetList;
|
||||
use Rector\CodeQuality\Rector\Ternary\{SimplifyTautologyTernaryRector, SwitchNegatedTernaryRector};
|
||||
use Rector\CodingStyle\Rector\ArrowFunction\StaticArrowFunctionRector;
|
||||
use Rector\CodingStyle\Rector\Class_\AddArrayDefaultToArrayPropertyRector;
|
||||
use Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector;
|
||||
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
|
||||
use Rector\CodingStyle\Rector\ClassMethod\{NewlineBeforeNewAssignSetRector, OrderAttributesRector};
|
||||
use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector;
|
||||
use Rector\CodingStyle\Rector\FuncCall\{CallUserFuncArrayToVariadicRector, CallUserFuncToMethodCallRector, CountArrayToEmptyArrayComparisonRector};
|
||||
use Rector\CodingStyle\Rector\FuncCall\
|
||||
{CallUserFuncArrayToVariadicRector,
|
||||
CallUserFuncToMethodCallRector,
|
||||
CountArrayToEmptyArrayComparisonRector,
|
||||
VersionCompareFuncCallToConstantRector};
|
||||
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\DeadCode\Rector\ClassMethod\{RemoveUselessParamTagRector, RemoveUselessReturnTagRector};
|
||||
use Rector\DeadCode\Rector\Foreach_\RemoveUnusedForeachKeyRector;
|
||||
use Rector\DeadCode\Rector\Property\RemoveUselessVarTagRector;
|
||||
use Rector\DeadCode\Rector\Switch_\RemoveDuplicatedCaseInSwitchRector;
|
||||
use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector;
|
||||
use Rector\EarlyReturn\Rector\If_\{ChangeIfElseValueAssignToEarlyReturnRector, RemoveAlwaysElseRector};
|
||||
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
|
||||
use Rector\Php81\Rector\Property\ReadOnlyPropertyRector;
|
||||
use Rector\Restoration\Rector\Property\MakeTypedPropertyNullableIfCheckedRector;
|
||||
use Rector\Set\ValueObject\LevelSetList;
|
||||
use Rector\TypeDeclaration\Rector\ClassMethod\{AddArrayParamDocTypeRector, AddArrayReturnDocTypeRector, AddMethodCallBasedStrictParamTypeRector, ParamTypeByMethodCallTypeRector, ParamTypeByParentCallTypeRector};
|
||||
use Rector\PHPUnit\Set\PHPUnitSetList;
|
||||
use Rector\TypeDeclaration\Rector\ClassMethod\{AddMethodCallBasedStrictParamTypeRector, ParamTypeByMethodCallTypeRector, ParamTypeByParentCallTypeRector};
|
||||
use Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector;
|
||||
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
if ( ! function_exists('walk_array'))
|
||||
{
|
||||
function walk_array(callable $method, array $items): void
|
||||
{
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$method($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return static function (RectorConfig $config): void {
|
||||
// Import names with use statements
|
||||
$config->importNames();
|
||||
$config->importShortClasses(false);
|
||||
|
||||
return static function (ContainerConfigurator $config): void {
|
||||
$parameters = $config->parameters();
|
||||
$parameters->set(Option::AUTO_IMPORT_NAMES, FALSE);
|
||||
$parameters->set(Option::IMPORT_SHORT_CLASSES, FALSE);
|
||||
$parameters->set(Option::SKIP, [
|
||||
ReadOnlyPropertyRector::class,
|
||||
RestoreDefaultNullToNullableTypePropertyRector::class,
|
||||
$config->sets([
|
||||
LevelSetList::UP_TO_PHP_81,
|
||||
PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES,
|
||||
PHPUnitSetList::PHPUNIT_100,
|
||||
]);
|
||||
|
||||
walk_array([$config, 'import'], [
|
||||
LevelSetList::UP_TO_PHP_80,
|
||||
]);
|
||||
|
||||
$services = $config->services();
|
||||
walk_array([$services, 'set'], [
|
||||
$config->rules([
|
||||
AddArrayDefaultToArrayPropertyRector::class,
|
||||
AddArrayParamDocTypeRector::class,
|
||||
AddArrayReturnDocTypeRector::class,
|
||||
AddClosureReturnTypeRector::class,
|
||||
AddMethodCallBasedStrictParamTypeRector::class,
|
||||
CallUserFuncArrayToVariadicRector::class,
|
||||
CallUserFuncToMethodCallRector::class,
|
||||
CountArrayToEmptyArrayComparisonRector::class,
|
||||
ChangeIfElseValueAssignToEarlyReturnRector::class,
|
||||
ChangeNestedForeachIfsToEarlyContinueRector::class,
|
||||
CompleteDynamicPropertiesRector::class,
|
||||
@ -67,7 +56,6 @@ return static function (ContainerConfigurator $config): void {
|
||||
CountArrayToEmptyArrayComparisonRector::class,
|
||||
ForRepeatedCountToOwnVariableRector::class,
|
||||
ForToForeachRector::class,
|
||||
// MakeTypedPropertyNullableIfCheckedRector::class,
|
||||
// NewlineAfterStatementRector::class,
|
||||
NewlineBeforeNewAssignSetRector::class,
|
||||
ParamTypeByMethodCallTypeRector::class,
|
||||
@ -79,13 +67,23 @@ return static function (ContainerConfigurator $config): void {
|
||||
RemoveUselessParamTagRector::class,
|
||||
RemoveUselessReturnTagRector::class,
|
||||
RemoveUselessVarTagRector::class,
|
||||
// SimplifyDeMorganBinaryRector::class,
|
||||
SimplifyDuplicatedTernaryRector::class,
|
||||
SimplifyIfElseToTernaryRector::class,
|
||||
SimplifyIfReturnBoolRector::class,
|
||||
SimplifyTautologyTernaryRector::class,
|
||||
SymplifyQuoteEscapeRector::class,
|
||||
StaticArrowFunctionRector::class,
|
||||
SwitchNegatedTernaryRector::class,
|
||||
TypedPropertyFromAssignsRector::class,
|
||||
VersionCompareFuncCallToConstantRector::class,
|
||||
WrapEncapsedVariableInCurlyBracesRector::class,
|
||||
]);
|
||||
|
||||
$config->ruleWithConfiguration(OrderAttributesRector::class, [
|
||||
'alphabetically',
|
||||
]);
|
||||
|
||||
$config->skip([
|
||||
ReadOnlyPropertyRector::class,
|
||||
RestoreDefaultNullToNullableTypePropertyRector::class,
|
||||
]);
|
||||
};
|
||||
|
@ -39,7 +39,7 @@ function get_text_to_replace(array $tokens): string
|
||||
// [0] => token type constant
|
||||
// [1] => raw syntax parsed to that token
|
||||
// [2] => line number
|
||||
foreach($tokens as $token)
|
||||
foreach ($tokens as $token)
|
||||
{
|
||||
// Since we only care about opening docblocks,
|
||||
// bail out when we get to the namespace token
|
||||
@ -81,9 +81,9 @@ function replace_file(string $file, string $template): void
|
||||
|
||||
$files = array_filter(
|
||||
glob_recursive('*.php'),
|
||||
fn (string $file) => ! (str_contains($file, '/vendor/') || str_contains($file, '/tmp/'))
|
||||
static fn (string $file) => ! (str_contains($file, '/vendor/') || str_contains($file, '/tmp/'))
|
||||
);
|
||||
array_walk($files, fn (string $file) => replace_file($file, '/header_comment.txt'));
|
||||
array_walk($files, static fn (string $file) => replace_file($file, '/header_comment.txt'));
|
||||
|
||||
echo json_encode(array_values($files), JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . "\n";
|
||||
printf("Successfully updated header comments in %d files\n", count($files));
|
||||
|
Loading…
Reference in New Issue
Block a user