Add the Chronological

This commit is contained in:
2026-02-16 13:39:26 +01:00
parent c091ed1371
commit f1ac693fe8
162 changed files with 25868 additions and 1 deletions

27
vendor/sabre/uri/LICENSE vendored Normal file
View File

@@ -0,0 +1,27 @@
Copyright (C) 2014-2019 fruux GmbH (https://fruux.com/)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Sabre nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

68
vendor/sabre/uri/composer.json vendored Normal file
View File

@@ -0,0 +1,68 @@
{
"name": "sabre/uri",
"description": "Functions for making sense out of URIs.",
"keywords": [
"URI",
"URL",
"rfc3986"
],
"homepage": "http://sabre.io/uri/",
"license": "BSD-3-Clause",
"require": {
"php": "^7.4 || ^8.0"
},
"authors": [
{
"name": "Evert Pot",
"email": "me@evertpot.com",
"homepage": "http://evertpot.com/",
"role": "Developer"
}
],
"support": {
"forum": "https://groups.google.com/group/sabredav-discuss",
"source": "https://github.com/fruux/sabre-uri"
},
"autoload": {
"files" : [
"lib/functions.php"
],
"psr-4" : {
"Sabre\\Uri\\" : "lib/"
}
},
"autoload-dev": {
"psr-4": {
"Sabre\\Uri\\": "tests/Uri"
}
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.64",
"phpstan/phpstan": "^1.12",
"phpstan/phpstan-phpunit": "^1.4",
"phpstan/phpstan-strict-rules": "^1.6",
"phpstan/extension-installer": "^1.4",
"phpunit/phpunit" : "^9.6"
},
"scripts": {
"phpstan": [
"phpstan analyse lib tests"
],
"cs-fixer": [
"php-cs-fixer fix"
],
"phpunit": [
"phpunit --configuration tests/phpunit.xml"
],
"test": [
"composer phpstan",
"composer cs-fixer",
"composer phpunit"
]
},
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
}
}

View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Sabre\Uri;
/**
* Invalid Uri.
*
* This is thrown when an attempt was made to use Sabre\Uri parse a uri that
* it could not.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (https://evertpot.com/)
* @license http://sabre.io/license/
*/
class InvalidUriException extends \Exception
{
}

20
vendor/sabre/uri/lib/Version.php vendored Normal file
View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Sabre\Uri;
/**
* This class contains the version number for this package.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/
*/
class Version
{
/**
* Full version number.
*/
public const VERSION = '3.0.2';
}

425
vendor/sabre/uri/lib/functions.php vendored Normal file
View File

@@ -0,0 +1,425 @@
<?php
declare(strict_types=1);
namespace Sabre\Uri;
/**
* This file contains all the uri handling functions.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/
*/
/**
* Resolves relative urls, like a browser would.
*
* This function takes a basePath, which itself _may_ also be relative, and
* then applies the relative path on top of it.
*
* @throws InvalidUriException
*/
function resolve(string $basePath, string $newPath): string
{
$delta = parse($newPath);
// If the new path defines a scheme, it's absolute and we can just return
// that.
if (null !== $delta['scheme']) {
return build($delta);
}
$base = parse($basePath);
$pick = function ($part) use ($base, $delta) {
if (null !== $delta[$part]) {
return $delta[$part];
} elseif (null !== $base[$part]) {
return $base[$part];
}
return null;
};
$newParts = [];
$newParts['scheme'] = $pick('scheme');
$newParts['host'] = $pick('host');
$newParts['port'] = $pick('port');
if (is_string($delta['path']) and strlen($delta['path']) > 0) {
// If the path starts with a slash
if ('/' === $delta['path'][0]) {
$path = $delta['path'];
} else {
// Removing last component from base path.
$path = (string) $base['path'];
$length = strrpos($path, '/');
if (false !== $length) {
$path = substr($path, 0, $length);
}
$path .= '/'.$delta['path'];
}
} else {
$path = $base['path'] ?? '/';
if ('' === $path) {
$path = '/';
}
}
// Removing .. and .
$pathParts = explode('/', $path);
$newPathParts = [];
foreach ($pathParts as $pathPart) {
switch ($pathPart) {
// case '' :
case '.':
break;
case '..':
array_pop($newPathParts);
break;
default:
$newPathParts[] = $pathPart;
break;
}
}
$path = implode('/', $newPathParts);
// If the source url ended with a /, we want to preserve that.
$newParts['path'] = 0 === strpos($path, '/') ? $path : '/'.$path;
// From PHP 8, no "?" query at all causes 'query' to be null.
// An empty query "http://example.com/foo?" causes 'query' to be the empty string
if (null !== $delta['query'] && '' !== $delta['query']) {
$newParts['query'] = $delta['query'];
} elseif (isset($base['query']) && null === $delta['host'] && null === $delta['path']) {
// Keep the old query if host and path didn't change
$newParts['query'] = $base['query'];
}
// From PHP 8, no "#" fragment at all causes 'fragment' to be null.
// An empty fragment "http://example.com/foo#" causes 'fragment' to be the empty string
if (null !== $delta['fragment'] && '' !== $delta['fragment']) {
$newParts['fragment'] = $delta['fragment'];
}
return build($newParts);
}
/**
* Takes a URI or partial URI as its argument, and normalizes it.
*
* After normalizing a URI, you can safely compare it to other URIs.
* This function will for instance convert a %7E into a tilde, according to
* rfc3986.
*
* It will also change a %3a into a %3A.
*
* @throws InvalidUriException
*/
function normalize(string $uri): string
{
$parts = parse($uri);
if (null !== $parts['path']) {
$pathParts = explode('/', ltrim($parts['path'], '/'));
$newPathParts = [];
foreach ($pathParts as $pathPart) {
switch ($pathPart) {
case '.':
// skip
break;
case '..':
// One level up in the hierarchy
array_pop($newPathParts);
break;
default:
// Ensuring that everything is correctly percent-encoded.
$newPathParts[] = rawurlencode(rawurldecode($pathPart));
break;
}
}
$parts['path'] = '/'.implode('/', $newPathParts);
}
if (null !== $parts['scheme']) {
$parts['scheme'] = strtolower($parts['scheme']);
$defaultPorts = [
'http' => '80',
'https' => '443',
];
if (null !== $parts['port'] && isset($defaultPorts[$parts['scheme']]) && $defaultPorts[$parts['scheme']] == $parts['port']) {
// Removing default ports.
unset($parts['port']);
}
// A few HTTP specific rules.
switch ($parts['scheme']) {
case 'http':
case 'https':
if (null === $parts['path']) {
// An empty path is equivalent to / in http.
$parts['path'] = '/';
}
break;
}
}
if (null !== $parts['host']) {
$parts['host'] = strtolower($parts['host']);
}
return build($parts);
}
/**
* Parses a URI and returns its individual components.
*
* This method largely behaves the same as PHP's parse_url, except that it will
* return an array with all the array keys, including the ones that are not
* set by parse_url, which makes it a bit easier to work with.
*
* Unlike PHP's parse_url, it will also convert any non-ascii characters to
* percent-encoded strings. PHP's parse_url corrupts these characters on OS X.
*
* In the return array, key "port" is an int value. Other keys have a string value.
* "Unused" keys have value null.
*
* @return array{scheme: string|null, host: string|null, path: string|null, port: positive-int|null, user: string|null, query: string|null, fragment: string|null}
*
* @throws InvalidUriException
*/
function parse(string $uri): array
{
// Normally a URI must be ASCII. However, often it's not and
// parse_url might corrupt these strings.
//
// For that reason we take any non-ascii characters from the uri and
// uriencode them first.
$uri = preg_replace_callback(
'/[^[:ascii:]]/u',
function ($matches) {
return rawurlencode($matches[0]);
},
$uri
);
if (null === $uri) {
throw new InvalidUriException('Invalid, or could not parse URI');
}
$result = parse_url($uri);
if (false === $result) {
$result = _parse_fallback($uri);
} else {
// Add empty host and leading slash to Windows file paths
// file:///C:/path or file:///C:\path
// Note: the regex fragment [a-zA-Z]:[\/\\\\].* end up being
// [a-zA-Z]:[\/\\].*
// The 4 backslash in a row are the way to get 2 backslash into the actual string
// that is used as the regex. The 2 backslash are then the way to get 1 backslash
// character into the character set "a forward slash or a backslash"
if (isset($result['scheme']) && 'file' === $result['scheme'] && isset($result['path'])
&& 1 === preg_match('/^(?<windows_path> [a-zA-Z]:([\/\\\\].*)?)$/x', $result['path'])) {
$result['path'] = '/'.$result['path'];
$result['host'] = '';
}
}
/*
* phpstan is not able to process all the things that happen while this function
* constructs the result array. It only understands the $result is
* non-empty-array<string, mixed>
*
* But the detail of the returned array is correctly specified in the PHPdoc
* above the function call.
*
* @phpstan-ignore-next-line
*/
return
$result + [
'scheme' => null,
'host' => null,
'path' => null,
'port' => null,
'user' => null,
'query' => null,
'fragment' => null,
];
}
/**
* This function takes the components returned from PHP's parse_url, and uses
* it to generate a new uri.
*
* @param array<string, int|string|null> $parts
*/
function build(array $parts): string
{
$uri = '';
$authority = '';
if (isset($parts['host'])) {
$authority = $parts['host'];
if (isset($parts['user'])) {
$authority = $parts['user'].'@'.$authority;
}
if (isset($parts['port'])) {
$authority = $authority.':'.$parts['port'];
}
}
if (isset($parts['scheme'])) {
// If there's a scheme, there's also a host.
$uri = $parts['scheme'].':';
}
if ('' !== $authority || (isset($parts['scheme']) && 'file' === $parts['scheme'])) {
// No scheme, but there is a host.
$uri .= '//'.$authority;
}
if (isset($parts['path'])) {
$uri .= $parts['path'];
}
if (isset($parts['query'])) {
$uri .= '?'.$parts['query'];
}
if (isset($parts['fragment'])) {
$uri .= '#'.$parts['fragment'];
}
return $uri;
}
/**
* Returns the 'dirname' and 'basename' for a path.
*
* The reason there is a custom function for this purpose, is because
* basename() is locale aware (behaviour changes if C locale or a UTF-8 locale
* is used) and we need a method that just operates on UTF-8 characters.
*
* In addition basename and dirname are platform aware, and will treat
* backslash (\) as a directory separator on Windows.
*
* This method returns the 2 components as an array.
*
* If there is no dirname, it will return an empty string. Any / appearing at
* the end of the string is stripped off.
*
* @return list<mixed>
*/
function split(string $path): array
{
$matches = [];
if (1 === preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u', $path, $matches)) {
return [$matches[1], $matches[2]];
}
return [null, null];
}
/**
* This function is another implementation of parse_url, except this one is
* fully written in PHP.
*
* The reason is that the PHP bug team is not willing to admit that there are
* bugs in the parse_url implementation.
*
* This function is only called if the main parse method fails. It's pretty
* crude and probably slow, so the original parse_url is usually preferred.
*
* @return array{scheme: string|null, host: string|null, path: string|null, port: positive-int|null, user: string|null, query: string|null, fragment: string|null}
*
* @throws InvalidUriException
*/
function _parse_fallback(string $uri): array
{
// Normally a URI must be ASCII, however. However, often it's not and
// parse_url might corrupt these strings.
//
// For that reason we take any non-ascii characters from the uri and
// uriencode them first.
$uri = preg_replace_callback(
'/[^[:ascii:]]/u',
function ($matches) {
return rawurlencode($matches[0]);
},
$uri
);
if (null === $uri) {
throw new InvalidUriException('Invalid, or could not parse URI');
}
$result = [
'scheme' => null,
'host' => null,
'port' => null,
'user' => null,
'path' => null,
'fragment' => null,
'query' => null,
];
if (1 === preg_match('% ^([A-Za-z][A-Za-z0-9+-\.]+): %x', $uri, $matches)) {
$result['scheme'] = $matches[1];
// Take what's left.
$uri = substr($uri, strlen($result['scheme']) + 1);
if (false === $uri) {
// There was nothing left.
$uri = '';
}
}
// Taking off a fragment part
if (false !== strpos($uri, '#')) {
list($uri, $result['fragment']) = explode('#', $uri, 2);
}
// Taking off the query part
if (false !== strpos($uri, '?')) {
list($uri, $result['query']) = explode('?', $uri, 2);
}
if ('///' === substr($uri, 0, 3)) {
// The triple slash uris are a bit unusual, but we have special handling
// for them.
$path = substr($uri, 2);
if (false === $path) {
throw new \RuntimeException('The string cannot be false');
}
$result['path'] = $path;
$result['host'] = '';
} elseif ('//' === substr($uri, 0, 2)) {
// Uris that have an authority part.
$regex = '%^
//
(?: (?<user> [^:@]+) (: (?<pass> [^@]+)) @)?
(?<host> ( [^:/]* | \[ [^\]]+ \] ))
(?: : (?<port> [0-9]+))?
(?<path> / .*)?
$%x';
if (1 !== preg_match($regex, $uri, $matches)) {
throw new InvalidUriException('Invalid, or could not parse URI');
}
if (isset($matches['host']) && '' !== $matches['host']) {
$result['host'] = $matches['host'];
}
if (isset($matches['port'])) {
$port = (int) $matches['port'];
if ($port > 0) {
$result['port'] = $port;
}
}
if (isset($matches['path'])) {
$result['path'] = $matches['path'];
}
if (isset($matches['user']) && '' !== $matches['user']) {
$result['user'] = $matches['user'];
}
if (isset($matches['pass']) && '' !== $matches['pass']) {
$result['pass'] = $matches['pass'];
}
} else {
$result['path'] = $uri;
}
return $result;
}