[Web] Update composer libraries

This commit is contained in:
FreddleSpl0it committed 2026-10-28 11:56:29 +01:00
1 parent 9cc8ac2908
commit bd8c784118
1297 files changed
+71585 -24460

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
Copyright (c) 2026-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+21
View File
@@ -0,0 +1,21 @@
Symfony Polyfill / Time
=======================
This component provides the [`Time` API](https://wiki.php.net/rfc/duration_class)
added to PHP 8.6 core, for PHP >= 8.1:
- `Time\TimeException`, `Time\Duration`
The phpt tests of the native implementation, borrowed from php-src, run against
the polyfill as part of the test suite. One divergence remains: `Duration` is a
plain final class with readonly properties instead of a `readonly` class, so
`ReflectionClass::newInstanceWithoutConstructor()` succeeds where the native
class rejects it. Dynamic properties are rejected as they are natively.
More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
License
=======
This library is released under the [MIT license](LICENSE).
@@ -0,0 +1,489 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Time;
if (\PHP_VERSION_ID < 80600) {
/**
* @see https://wiki.php.net/rfc/duration_class
*/
final class Duration
{
private const NANOS_PER_SECOND = 1_000_000_000;
/**
* Maximum seconds accepted by Duration.
*
* One second is reserved to avoid overflowing when arithmetic operations
* temporarily require carrying nanoseconds into the seconds component.
*/
private const MAX_SECONDS = \PHP_INT_SIZE >= 8 ? 9_223_372_035 : \PHP_INT_MAX;
private const RANGE_ERROR = \PHP_INT_SIZE >= 8
? 'The maximum representable range is 9_223_372_035 seconds (roughly 292 years)'
: 'The maximum representable range is 2_147_483_647 seconds (roughly 68 years)';
/**
* Regular expression to parse an ISO-8601 duration string.
*
* Year, Month, Week and Day components are intentionally not supported.
* The biggest supported component is Hour.
*/
private const REGEXP_ISO8601 = '@^
PT
(?=(?:\d+H|\d+M|\d+S)) # look ahead to avoid PT without argument
(?:(?<hour>\d+)H)?
(?:(?<minute>\d+)M)?
(?:(?<second>\d+)S)?
$@x';
/**
* Regular expression matching any ISO-8601 duration, including the
* date components that Duration does not support.
*/
private const REGEXP_ISO8601_ANY = '@^
P
(?:(?<year>\d+)Y)?
(?:(?<month>\d+)M)?
(?:(?<week>\d+)W)?
(?:(?<day>\d+)D)?
(?:T(?:\d+H)?(?:\d+M)?(?:\d+S)?)?
$@x';
private function __construct(
public readonly int $seconds,
public readonly int $nanoseconds,
public readonly bool $negative,
) {}
/**
* Create a duration representing $seconds seconds and $nanoseconds nanoseconds. Neither parameter
* may be negative. $nanoseconds must be less than 1_000_000_000 (the number of nanoseconds in a
* second).
*
* This constructor creates a Duration from its “atomic” components.
*
* @throws TimeException
*/
public static function fromSeconds(int $seconds, int $nanoseconds = 0): self
{
if ($seconds < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($seconds) must be greater than or equal to 0');
}
if ($nanoseconds < 0) {
throw new \ValueError(__METHOD__.'(): Argument #2 ($nanoseconds) must be greater than or equal to 0');
}
if ($nanoseconds >= self::NANOS_PER_SECOND) {
throw new \ValueError(__METHOD__.'(): Argument #2 ($nanoseconds) must be less than 1_000_000_000');
}
return self::create($seconds, $nanoseconds, false);
}
/**
* Create a duration representing $nanoseconds nanoseconds. $nanoseconds must not be negative.
*
* @throws TimeException
*/
public static function fromNanoseconds(int $nanoseconds): self
{
if ($nanoseconds < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($nanoseconds) must be greater than or equal to 0');
}
return self::create(intdiv($nanoseconds, self::NANOS_PER_SECOND), $nanoseconds % self::NANOS_PER_SECOND, false);
}
/**
* Create a duration representing $microseconds microseconds. $microseconds must not be negative.
*
* @throws TimeException
*/
public static function fromMicroseconds(int $microseconds): self
{
if ($microseconds < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($microseconds) must be greater than or equal to 0');
}
return self::create(intdiv($microseconds, 1_000_000), ($microseconds % 1_000_000) * 1_000, false);
}
/**
* Create a duration representing $milliseconds milliseconds. $milliseconds must not be negative.
*
* @throws TimeException
*/
public static function fromMilliseconds(int $milliseconds): self
{
if ($milliseconds < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($milliseconds) must be greater than or equal to 0');
}
return self::create(intdiv($milliseconds, 1_000), ($milliseconds % 1_000) * 1_000_000, false);
}
/**
* Create a duration representing $minutes minutes. $minutes must not be negative.
*
* @throws TimeException
*/
public static function fromMinutes(int $minutes): self
{
if ($minutes < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($minutes) must be greater than or equal to 0');
}
if ($minutes > intdiv(self::MAX_SECONDS, 60)) {
throw new TimeException(self::RANGE_ERROR);
}
return self::create($minutes * 60, 0, false);
}
/**
* Create a duration representing $hours hours. $hours must not be negative.
*
* @throws TimeException
*/
public static function fromHours(int $hours): self
{
if ($hours < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($hours) must be greater than or equal to 0');
}
if ($hours > intdiv(self::MAX_SECONDS, 3_600)) {
throw new TimeException(self::RANGE_ERROR);
}
return self::create($hours * 3_600, 0, false);
}
/**
* Parse a ISO-8601 period. ISO-8601 periods with a date component will be rejected.
* The biggest allowed component is H.
*
* @throws TimeException
*/
public static function fromIso8601DurationString(string $specification): self
{
if (!preg_match(self::REGEXP_ISO8601, $specification, $parts)) {
throw new TimeException(self::iso8601Error($specification));
}
$hours = (int) ($parts['hour'] ?? 0);
$minutes = (int) ($parts['minute'] ?? 0);
$seconds = (int) ($parts['second'] ?? 0);
// each step is checked against the maximum so that no intermediate value can overflow
if ($hours > intdiv(self::MAX_SECONDS, 3_600)) {
throw new TimeException(self::RANGE_ERROR);
}
$total = $hours * 3_600;
if ($minutes > intdiv(self::MAX_SECONDS - $total, 60)) {
throw new TimeException(self::RANGE_ERROR);
}
$total += $minutes * 60;
if ($seconds > self::MAX_SECONDS - $total) {
throw new TimeException(self::RANGE_ERROR);
}
return self::create($total + $seconds, 0, false);
}
/**
* Negates the duration.
*
* @return self -$this
*/
public function negate(): self
{
if (0 === $this->seconds && 0 === $this->nanoseconds) {
return $this;
}
return new self($this->seconds, $this->nanoseconds, !$this->negative);
}
/**
* Returns the absolute value of the duration.
*
* @return self abs($this)
*/
public function absolute(): self
{
if (!$this->negative) {
return $this;
}
return new self($this->seconds, $this->nanoseconds, false);
}
/**
* Add the given duration to the duration.
*
* @return self $this + $duration
*
* @throws TimeException
*/
public function add(self $duration): self
{
$seconds = $this->negative ? -$this->seconds : $this->seconds;
$nanoseconds = $this->negative ? -$this->nanoseconds : $this->nanoseconds;
$addSeconds = $duration->negative ? -$duration->seconds : $duration->seconds;
$addNanoseconds = $duration->negative ? -$duration->nanoseconds : $duration->nanoseconds;
if ($this->negative === $duration->negative && $this->seconds > self::MAX_SECONDS - $duration->seconds) {
throw new TimeException(self::RANGE_ERROR);
}
$seconds += $addSeconds;
$nanoseconds += $addNanoseconds;
if ($nanoseconds >= self::NANOS_PER_SECOND || $nanoseconds <= -self::NANOS_PER_SECOND) {
$carry = intdiv($nanoseconds, self::NANOS_PER_SECOND);
$nanoseconds %= self::NANOS_PER_SECOND;
if ($carry > 0 ? $seconds > self::MAX_SECONDS - $carry : $seconds < -self::MAX_SECONDS - $carry) {
throw new TimeException(self::RANGE_ERROR);
}
$seconds += $carry;
}
if (0 < $seconds && 0 > $nanoseconds) {
--$seconds;
$nanoseconds += self::NANOS_PER_SECOND;
}
if (0 > $seconds && 0 < $nanoseconds) {
++$seconds;
$nanoseconds -= self::NANOS_PER_SECOND;
}
return self::create(abs($seconds), abs($nanoseconds), 0 > $seconds || 0 > $nanoseconds);
}
/**
* Subtract the given duration from the duration.
*
* @return self $this - $duration
*
* @throws TimeException
*/
public function sub(self $duration): self
{
return $this->add($duration->negate());
}
/**
* Multiply the length of the duration by the given factor. $factor must not be negative.
*
* @return self $this * $factor
*
* @throws TimeException
*/
public function multiplyBy(int $factor): self
{
if ($factor < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($factor) must be greater than or equal to 0');
}
if (0 === $factor) {
return new self(0, 0, false);
}
if (1 === $factor) {
return $this;
}
// double-and-add: multiplying the nanoseconds directly would overflow
$seconds = 0;
$nanoseconds = 0;
$addSeconds = $this->seconds;
$addNanoseconds = $this->nanoseconds;
while (true) {
if (1 & $factor) {
[$seconds, $nanoseconds] = self::addMagnitudes($seconds, $nanoseconds, $addSeconds, $addNanoseconds);
}
if (0 === $factor >>= 1) {
break;
}
// the remaining factor is not zero, so an out of range double is out of range for the result too
[$addSeconds, $addNanoseconds] = self::addMagnitudes($addSeconds, $addNanoseconds, $addSeconds, $addNanoseconds);
}
return self::create($seconds, $nanoseconds, $this->negative);
}
/**
* Divide the length of the duration by the given divisor. $divisor must be positive.
*
* Fractional nanoseconds will be truncated.
*
* @return self $this / $divisor
*
* @throws TimeException
*/
public function divideBy(int $divisor): self
{
if ($divisor < 0) {
throw new \ValueError(__METHOD__.'(): Argument #1 ($divisor) must be greater than or equal to 0');
}
if (0 === $divisor) {
throw new \DivisionByZeroError('Division by zero');
}
if (1 === $divisor) {
return $this;
}
$remainder = $this->seconds % $divisor;
$nanoseconds = $remainder > intdiv(\PHP_INT_MAX - $this->nanoseconds, self::NANOS_PER_SECOND)
? self::divideNanoseconds($remainder, $this->nanoseconds, $divisor)
: intdiv($this->nanoseconds + $remainder * self::NANOS_PER_SECOND, $divisor);
return self::create(intdiv($this->seconds, $divisor), $nanoseconds, $this->negative);
}
/**
* Returns -1, 0, 1 if $a is less than, equal to, or greater than $b respectively.
*/
public static function compare(self $a, self $b): int
{
if ($a->negative !== $b->negative) {
return $a->negative ? -1 : 1;
}
$comparison = $a->seconds <=> $b->seconds ?: $a->nanoseconds <=> $b->nanoseconds;
return $a->negative ? -$comparison : $comparison;
}
/**
* The native class is declared readonly, which forbids dynamic properties.
*/
public function __set(string $name, mixed $value): void
{
throw new \Error(\sprintf('Cannot create dynamic property %s::$%s', self::class, $name));
}
/**
* Adds two non-negative (seconds, nanoseconds) pairs.
*
* @return array{0: int, 1: int}
*
* @throws TimeException when the sum is out of the representable range
*/
private static function addMagnitudes(int $seconds, int $nanoseconds, int $addSeconds, int $addNanoseconds): array
{
if ($seconds > self::MAX_SECONDS - $addSeconds) {
throw new TimeException(self::RANGE_ERROR);
}
$seconds += $addSeconds;
// the sum of two nanoseconds components is always below 2**31
$nanoseconds += $addNanoseconds;
if ($nanoseconds >= self::NANOS_PER_SECOND) {
if (self::MAX_SECONDS === $seconds) {
throw new TimeException(self::RANGE_ERROR);
}
++$seconds;
$nanoseconds -= self::NANOS_PER_SECOND;
}
return [$seconds, $nanoseconds];
}
/**
* Returns intdiv($remainder * 1_000_000_000 + $nanoseconds, $divisor) for
* a $remainder that is lower than $divisor.
*
* The dividend does not fit in an integer on 32 bit platforms, so the
* division is done one decimal digit at a time. Every intermediate value
* stays below 2**53, where floats represent integers exactly.
*/
private static function divideNanoseconds(int $remainder, int $nanoseconds, int $divisor): int
{
$quotient = 0;
$rest = (float) $remainder;
foreach (str_split(str_pad((string) $nanoseconds, 9, '0', \STR_PAD_LEFT)) as $digit) {
$rest = $rest * 10 + (int) $digit;
$digit = (int) ($rest / $divisor);
$rest -= $digit * $divisor;
// the float division may be off by one in either direction
while (0 > $rest) {
--$digit;
$rest += $divisor;
}
while ($rest >= $divisor) {
++$digit;
$rest -= $divisor;
}
$quotient = $quotient * 10 + $digit;
}
return $quotient;
}
/**
* @throws TimeException when the duration is out of the representable range
*/
private static function create(int $seconds, int $nanoseconds, bool $negative): self
{
if ($seconds > self::MAX_SECONDS) {
throw new TimeException(self::RANGE_ERROR);
}
// a zero duration is never negative
return new self($seconds, $nanoseconds, $negative && (0 !== $seconds || 0 !== $nanoseconds));
}
/**
* Mirrors the error reporting of timelib_duration_create_from_iso8601string().
*/
private static function iso8601Error(string $specification): string
{
if (preg_match(self::REGEXP_ISO8601_ANY, $specification, $parts)) {
if ((int) ($parts['year'] ?? 0) || (int) ($parts['month'] ?? 0) || (int) ($parts['week'] ?? 0) || (int) ($parts['day'] ?? 0)) {
return 'The ISO 8601 duration string may only contain the time (T) aspect';
}
return 'The ISO 8601 duration string could not be parsed';
}
if (str_contains($specification, '/')) {
return 'The ISO 8601 duration string may only contain the period (P) aspect';
}
if (!str_contains($specification, 'P') && false !== @strtotime($specification)) {
return 'The ISO 8601 duration string is missing the period (P) aspect';
}
return 'The ISO 8601 duration string could not be parsed';
}
}
}
@@ -0,0 +1,18 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Time;
if (\PHP_VERSION_ID < 80600) {
class TimeException extends \Exception
{
}
}
@@ -0,0 +1,36 @@
{
"name": "symfony/polyfill-time",
"type": "library",
"description": "Symfony polyfill for the Time API added to PHP 8.6",
"keywords": ["polyfill", "shim", "compatibility", "portable", "time", "duration"],
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Ignace Philippe Nyamagana Butera",
"email": "nyamsprod@gmail.com"
},
{
"name": "Tim Düsterhus",
"email": "tim@tideways-gmbh.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"require": {
"php": ">=8.1"
},
"autoload": {
"psr-4": { "Symfony\\Polyfill\\Time\\": "" },
"classmap": [ "Resources/stubs" ]
},
"minimum-stability": "dev",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
}
}