Page MenuHomeDevCentral

No OneTemporary

diff --git a/omnitools/src/Collections/TraversableUtilities.php b/omnitools/src/Collections/TraversableUtilities.php
index 52364ef..8e9773c 100644
--- a/omnitools/src/Collections/TraversableUtilities.php
+++ b/omnitools/src/Collections/TraversableUtilities.php
@@ -1,62 +1,46 @@
<?php
declare(strict_types=1);
namespace Keruald\OmniTools\Collections;
use Countable;
use InvalidArgumentException;
use ResourceBundle;
use SimpleXMLElement;
use TypeError;
class TraversableUtilities {
public static function count ($countable) : int {
if (is_countable($countable)) {
return count($countable);
}
if ($countable === null || $countable === false) {
return 0;
}
throw new TypeError;
}
public static function first (iterable $iterable) : mixed {
foreach ($iterable as $value) {
return $value;
}
throw new InvalidArgumentException(
"Can't call first() on an empty iterable."
);
}
public static function firstOr (
iterable $iterable, mixed $defaultValue = null
) : mixed {
foreach ($iterable as $value) {
return $value;
}
return $defaultValue;
}
- /**
- * @deprecated Use \is_countable
- */
- public static function isCountable ($countable) : bool {
- if (function_exists('is_countable')) {
- // PHP 7.3 has is_countable
- return is_countable($countable);
- }
-
- // https://github.com/Ayesh/is_countable-polyfill/blob/master/src/is_countable.php
- return is_array($countable)
- || $countable instanceof Countable
- || $countable instanceof SimpleXMLElement
- || $countable instanceof ResourceBundle;
- }
-
}
diff --git a/omnitools/src/HTTP/Requests/WithURL.php b/omnitools/src/HTTP/Requests/WithURL.php
index 5c21db2..bbd6ceb 100644
--- a/omnitools/src/HTTP/Requests/WithURL.php
+++ b/omnitools/src/HTTP/Requests/WithURL.php
@@ -1,102 +1,102 @@
<?php
namespace Keruald\OmniTools\HTTP\Requests;
use Keruald\OmniTools\HTTP\URL;
use Keruald\OmniTools\Strings\Multibyte\StringUtilities;
trait WithURL {
///
/// Main methods
///
public static function getServerURL () : string {
$scheme = self::getScheme();
$name = self::getServerName();
$port = self::getPort();
// If we forward for a proxy, trust the scheme instead of standard :80
$fixToHTTPS = $port === 80 && $scheme === "https";
if ($port === 443 || $fixToHTTPS) {
return "https://$name";
}
if ($port === 80) {
return "http://$name";
}
return "$scheme://$name:$port";
}
///
/// Helper methods
///
public static function getPort () : int {
return (int)($_SERVER['SERVER_PORT'] ?? 80);
}
public static function getServerName () : string {
return $_SERVER['SERVER_NAME'] ?? "localhost";
}
public static function getScheme () : string {
return $_SERVER['REQUEST_SCHEME']
?? $_SERVER['HTTP_X_FORWARDED_PROTO']
?? $_SERVER['HTTP_X_FORWARDED_PROTOCOL']
?? $_SERVER['HTTP_X_URL_SCHEME']
?? self::guessScheme();
}
private static function guessScheme () : string {
return self::isHTTPS() ? "https" : "http";
}
public static function isHTTPS () : bool {
// Legacy headers have been documented at MDN:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
$headers = self::getHTTPSHeadersTable();
foreach ($headers as $header => $value) {
if (isset($_SERVER[$header]) && $_SERVER[$header] === $value) {
return true;
}
}
if (isset($_SERVER['HTTP_FORWARDED'])) {
- return StringUtilities::contains($_SERVER['HTTP_FORWARDED'], "proto=https");
+ return str_contains($_SERVER['HTTP_FORWARDED'], "proto=https");
}
return false;
}
private static function getHTTPSHeadersTable () : array {
return [
"HTTPS" => "on",
"REQUEST_SCHEME" => "https",
"SERVER_PORT" => "443",
"HTTP_X_FORWARDED_PROTO" => "https",
"HTTP_FRONT_END_HTTPS" => "on",
"HTTP_X_FORWARDED_PROTOCOL" => "https",
"HTTP_X_FORWARDED_SSL" => "on",
"HTTP_X_URL_SCHEME" => "https",
];
}
/**
* Create a URL object, using the current request server URL for protocol
* and domain name.
*
* @param string $query The query part of the URL [facultative]
* @param int $encodeMode Encoding to use for the query [facultative]
*/
public static function createLocalURL (string $query = "",
int $encodeMode = URL::ENCODE_RFC3986_SLASH_EXCEPTED
) : URL {
return (new URL(self::getServerURL()))
->setQuery($query, $encodeMode);
}
}
diff --git a/omnitools/src/Strings/Multibyte/StringUtilities.php b/omnitools/src/Strings/Multibyte/StringUtilities.php
index 7172642..78c49be 100644
--- a/omnitools/src/Strings/Multibyte/StringUtilities.php
+++ b/omnitools/src/Strings/Multibyte/StringUtilities.php
@@ -1,94 +1,71 @@
<?php
declare(strict_types=1);
namespace Keruald\OmniTools\Strings\Multibyte;
class StringUtilities {
/**
* Pads a multibyte string to a certain length with another string
*
* @param string $input the input string
* @param int $padLength the target string size
* @param string $padString the padding characters (optional, default is space)
* @param int $padType STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH (optional, default is STR_PAD_RIGHT)
* @param string $encoding the character encoding (optional)
*
* @return string the padded string
*
*/
public static function pad (
string $input,
int $padLength,
string $padString = ' ',
int $padType = STR_PAD_RIGHT,
string $encoding = ''
) : string {
return (new StringPad)
->setInput($input)
->setPadLength($padLength)
->setPadString($padString)
->setPadType($padType)
->setEncoding($encoding ?: "UTF-8")
->pad();
}
public static function isSupportedEncoding (string $encoding) : bool {
return match ($encoding) {
"UTF-8" => true,
default => in_array($encoding, mb_list_encodings()),
};
}
- /**
- * @deprecated Since PHP 8.0, we can replace by \str_starts_with
- */
- public static function startsWith (string $string, string $start) : bool {
- $length = mb_strlen($start);
- return mb_substr($string, 0, $length) === $start;
- }
-
- /**
- * @deprecated Since PHP 8.0, we can replace by \str_ends_with
- */
- public static function endsWith (string $string, string $end) : bool {
- $length = mb_strlen($end);
- return $length === 0 || mb_substr($string, -$length) === $end;
- }
-
- /**
- * @deprecated Since PHP 8.0, we can replace by \str_contains
- */
- public static function contains (string $string, string $needle) : bool {
- return str_contains($string, $needle);
- }
-
/**
* Encode a string using a variant of the MIME base64 compatible with URLs.
*
* The '+' and '/' characters used in base64 are replaced by '-' and '_'.
* The '=' padding is removed.
*
* @param string $string The string to encode
* @return string The encoded string
*/
public static function encodeInBase64 (string $string) : string {
return str_replace(
['+', '/', '='],
['-', '_', ''],
base64_encode($string)
);
}
/**
* Decode a string encoded with StringUtilities::encodeInBase64
*
* @param string $string The string to decode
* @return string The decoded string
*/
public static function decodeFromBase64 (string $string) : string {
$toDecode = str_replace(['-', '_'], ['+', '/'], $string);
return base64_decode($toDecode);
}
}
diff --git a/omnitools/tests/Collections/TraversableUtilitiesTest.php b/omnitools/tests/Collections/TraversableUtilitiesTest.php
index e2cab7b..8a4be65 100644
--- a/omnitools/tests/Collections/TraversableUtilitiesTest.php
+++ b/omnitools/tests/Collections/TraversableUtilitiesTest.php
@@ -1,107 +1,91 @@
<?php
declare(strict_types=1);
namespace Keruald\OmniTools\Tests\Collections;
use Keruald\OmniTools\Collections\TraversableUtilities;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Countable;
use InvalidArgumentException;
use IteratorAggregate;
use Traversable;
class TraversableUtilitiesTest extends TestCase {
#[DataProvider('provideCountables')]
public function testCount ($expectedCount, $countable) {
$this->assertEquals(
$expectedCount, TraversableUtilities::count($countable)
);
}
#[DataProvider('provideNotCountables')]
public function testCountWithNotCountables ($notCountable) {
$this->expectException("TypeError");
TraversableUtilities::count($notCountable);
}
- #[DataProvider('providePureCountables')]
- public function testIsCountable ($countable) {
- $this->assertTrue(TraversableUtilities::isCountable($countable));
- }
-
#[DataProvider('provideIterableAndFirst')]
public function testIsFirst($expected, $iterable) {
$this->assertEquals($expected, TraversableUtilities::first($iterable));
}
public function testIsFirstWithEmptyCollection() {
$this->expectException(InvalidArgumentException::class);
TraversableUtilities::first([]);
}
#[DataProvider('provideIterableAndFirst')]
public function testIsFirstOr($expected, $iterable) {
$actual = TraversableUtilities::firstOr($iterable, 666);
$this->assertEquals($expected, $actual);
}
public function testIsFirstOrWithEmptyCollection() {
$actual = TraversableUtilities::firstOr([], 666);
$this->assertEquals(666, $actual);
}
///
/// Data providers
///
public static function provideCountables () : iterable {
yield [0, null];
yield [0, false];
yield [0, []];
yield [3, ["a", "b", "c"]];
yield [42, new class implements Countable {
public function count () : int {
return 42;
}
}
];
}
- public static function providePureCountables () : iterable {
- yield [[]];
- yield [["a", "b", "c"]];
- yield [new class implements Countable {
- public function count () : int {
- return 42;
- }
- }
- ];
- }
-
public static function provideNotCountables () : iterable {
yield [true];
yield [new \stdClass];
yield [0];
yield [""];
yield ["abc"];
}
public static function provideIterableAndFirst() : iterable {
yield ["a", ["a", "b", "c"]];
yield ["apple", ["fruit" => "apple", "vegetable" => "leeks"]];
yield [42, new class implements IteratorAggregate {
public function getIterator () : Traversable {
yield 42;
yield 100;
}
}];
}
}
diff --git a/omnitools/tests/Strings/Multibyte/StringUtilitiesTest.php b/omnitools/tests/Strings/Multibyte/StringUtilitiesTest.php
index 77c8092..b3ad4aa 100644
--- a/omnitools/tests/Strings/Multibyte/StringUtilitiesTest.php
+++ b/omnitools/tests/Strings/Multibyte/StringUtilitiesTest.php
@@ -1,116 +1,99 @@
<?php
declare(strict_types=1);
namespace Keruald\OmniTools\Tests\Strings\Multibyte;
use Keruald\OmniTools\Strings\Multibyte\StringUtilities;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class StringUtilitiesTest extends TestCase {
///
/// Tests
///
#[DataProvider('providePadding')]
public function testPad (
string $expected,
string $input, int $padLength, string $padString, int $padType
) : void {
$paddedString = StringUtilities::pad(
$input, $padLength, $padString, $padType, "UTF-8"
);
$this->assertEquals($expected, $paddedString);
}
public function testPadWithDefaultArguments () : void {
$this->assertEquals("foo ", StringUtilities::pad("foo", 4));
$this->assertEquals("foo_", StringUtilities::pad("foo", 4, '_'));
$this->assertEquals("_foo", StringUtilities::pad("foo", 4, '_', STR_PAD_LEFT));
}
public function testSupportedEncoding () : void {
$this->assertTrue(StringUtilities::isSupportedEncoding("UTF-8"));
$this->assertFalse(StringUtilities::isSupportedEncoding("notexisting"));
}
- public function testStartsWith () : void {
- $this->assertTrue(StringUtilities::startsWith("foo", "fo"));
- $this->assertTrue(StringUtilities::startsWith("foo", ""));
- $this->assertTrue(StringUtilities::startsWith("foo", "foo"));
-
- $this->assertFalse(StringUtilities::startsWith("foo", "bar"));
- }
-
- public function testEndsWith () : void {
- $this->assertTrue(StringUtilities::endsWith("foo", "oo"));
- $this->assertTrue(StringUtilities::endsWith("foo", ""));
- $this->assertTrue(StringUtilities::endsWith("foo", "foo"));
-
- $this->assertFalse(StringUtilities::endsWith("foo", "oO"));
- $this->assertFalse(StringUtilities::endsWith("foo", "bar"));
- }
-
#[DataProvider('provideBase64')]
public function testEncodeInBase64 (string $decoded, string $encoded) : void {
$actual = StringUtilities::encodeInBase64($decoded);
$this->assertEquals($encoded, $actual);
}
#[DataProvider('provideBase64')]
public function testDecodeFromBase64 (string $decoded, string $encoded) : void {
$actual = StringUtilities::decodeFromBase64($encoded);
$this->assertEquals($decoded, $actual);
}
///
/// Data providers
///
public static function providePadding () : iterable {
// Tests from http://3v4l.org/UnXTF
// http://web.archive.org/web/20150711100913/http://3v4l.org/UnXTF
yield ['àèòàFOOàèòà', "FOO", 11, "àèò", STR_PAD_BOTH];
yield ['àèòFOOàèòà', "FOO", 10, "àèò", STR_PAD_BOTH];
yield ['àèòBAAZàèòà', "BAAZ", 11, "àèò", STR_PAD_BOTH];
yield ['àèòBAAZàèò', "BAAZ", 10, "àèò", STR_PAD_BOTH];
yield ['FOOBAR', "FOOBAR", 6, "àèò", STR_PAD_BOTH];
yield ['FOOBAR', "FOOBAR", 1, "àèò", STR_PAD_BOTH];
yield ['FOOBAR', "FOOBAR", 0, "àèò", STR_PAD_BOTH];
yield ['FOOBAR', "FOOBAR", -10, "àèò", STR_PAD_BOTH];
yield ['àèòàèòàèFOO', "FOO", 11, "àèò", STR_PAD_LEFT];
yield ['àèòàèòàFOO', "FOO", 10, "àèò", STR_PAD_LEFT];
yield ['àèòàèòàBAAZ', "BAAZ", 11, "àèò", STR_PAD_LEFT];
yield ['àèòàèòBAAZ', "BAAZ", 10, "àèò", STR_PAD_LEFT];
yield ['FOOBAR', "FOOBAR", 6, "àèò", STR_PAD_LEFT];
yield ['FOOBAR', "FOOBAR", 1, "àèò", STR_PAD_LEFT];
yield ['FOOBAR', "FOOBAR", 0, "àèò", STR_PAD_LEFT];
yield ['FOOBAR', "FOOBAR", -10, "àèò", STR_PAD_LEFT];
yield ['FOOàèòàèòàè', "FOO", 11, "àèò", STR_PAD_RIGHT];
yield ['FOOàèòàèòà', "FOO", 10, "àèò", STR_PAD_RIGHT];
yield ['BAAZàèòàèòà', "BAAZ", 11, "àèò", STR_PAD_RIGHT];
yield ['BAAZàèòàèò', "BAAZ", 10, "àèò", STR_PAD_RIGHT];
yield ['FOOBAR', "FOOBAR", 6, "àèò", STR_PAD_RIGHT];
yield ['FOOBAR', "FOOBAR", 1, "àèò", STR_PAD_RIGHT];
yield ['FOOBAR', "FOOBAR", 0, "àèò", STR_PAD_RIGHT];
yield ['FOOBAR', "FOOBAR", -10, "àèò", STR_PAD_RIGHT];
}
public static function provideBase64 () : iterable {
yield ['foo', 'Zm9v', "This is the regular base test without any exception."];
yield ['', '', "An empty string should remain an empty string."];
yield [
"J'ai fait mes 60 prières par terre dans la poudrière.",
'SidhaSBmYWl0IG1lcyA2MCBwcmnDqHJlcyBwYXIgdGVycmUgZGFucyBsYSBwb3VkcmnDqHJlLg',
"No padding should be used."
];
yield [
"àèòàFOOàèòà", "w6DDqMOyw6BGT0_DoMOow7LDoA",
"Slashes / should be replaced by underscores _."
];
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Mar 18, 12:33 (20 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3539655
Default Alt Text
(16 KB)

Event Timeline