mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-19 23:32:17 +02:00
Merge remote-tracking branch 'origin/support/3.2' into develop
This commit is contained in:
@@ -14,30 +14,31 @@
|
|||||||
"ext-soap": "*",
|
"ext-soap": "*",
|
||||||
"apereo/phpcas": "~1.6.0",
|
"apereo/phpcas": "~1.6.0",
|
||||||
"combodo/tcpdf": "~6.4.4",
|
"combodo/tcpdf": "~6.4.4",
|
||||||
"firebase/php-jwt": "~6.4.0",
|
"firebase/php-jwt": "^6.4.0",
|
||||||
"guzzlehttp/guzzle": "^7.5.1",
|
"guzzlehttp/guzzle": "^7.5.1",
|
||||||
"laminas/laminas-mail": "^2.11",
|
"laminas/laminas-mail": "^2.11",
|
||||||
"laminas/laminas-servicemanager": "^3.5",
|
"laminas/laminas-servicemanager": "^3.5",
|
||||||
"league/oauth2-google": "^3.0",
|
"league/oauth2-google": "^4.0.1",
|
||||||
"nikic/php-parser": "~4.14.0",
|
"nikic/php-parser": "^4.14.0",
|
||||||
"pear/archive_tar": "~1.4.14",
|
"pear/archive_tar": "~1.4.14",
|
||||||
"pelago/emogrifier": "^6.0.0",
|
"pelago/emogrifier": "^6.0.0",
|
||||||
|
"psr/log": "^3.0.0",
|
||||||
"scssphp/scssphp": "^1.10.3",
|
"scssphp/scssphp": "^1.10.3",
|
||||||
"symfony/console": "~6.4.0",
|
"symfony/console": "~6.4.0",
|
||||||
"symfony/dotenv": "~6.4.0",
|
"symfony/dotenv": "~6.4.0",
|
||||||
"symfony/framework-bundle": "~6.4.0",
|
"symfony/framework-bundle": "~6.4.0",
|
||||||
"symfony/var-dumper": "~6.4.0",
|
|
||||||
"symfony/runtime": "~6.4.0",
|
|
||||||
"symfony/http-foundation": "~6.4.0",
|
"symfony/http-foundation": "~6.4.0",
|
||||||
"symfony/http-kernel": "~6.4.0",
|
"symfony/http-kernel": "~6.4.0",
|
||||||
|
"symfony/runtime": "~6.4.0",
|
||||||
"symfony/twig-bundle": "~6.4.0",
|
"symfony/twig-bundle": "~6.4.0",
|
||||||
|
"symfony/var-dumper": "~6.4.0",
|
||||||
"symfony/yaml": "~6.4.0",
|
"symfony/yaml": "~6.4.0",
|
||||||
"thenetworg/oauth2-azure": "^2.0"
|
"thenetworg/oauth2-azure": "^2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"symfony/debug-bundle": "~6.4.0",
|
||||||
"symfony/stopwatch": "~6.4.0",
|
"symfony/stopwatch": "~6.4.0",
|
||||||
"symfony/web-profiler-bundle": "~6.4.0",
|
"symfony/web-profiler-bundle": "~6.4.0"
|
||||||
"symfony/debug-bundle": "~6.4.0"
|
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-libsodium": "Required to use the AttributeEncryptedString.",
|
"ext-libsodium": "Required to use the AttributeEncryptedString.",
|
||||||
|
|||||||
577
composer.lock
generated
577
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ class CASLogger implements LoggerInterface
|
|||||||
CASLog::Enable($sDebugFile);
|
CASLog::Enable($sDebugFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LEVEL_COMPAT = [
|
public const LEVEL_COMPAT = [
|
||||||
LogLevel::EMERGENCY => LogAPI::LEVEL_ERROR,
|
LogLevel::EMERGENCY => LogAPI::LEVEL_ERROR,
|
||||||
LogLevel::ALERT => LogAPI::LEVEL_ERROR,
|
LogLevel::ALERT => LogAPI::LEVEL_ERROR,
|
||||||
LogLevel::CRITICAL => LogAPI::LEVEL_ERROR,
|
LogLevel::CRITICAL => LogAPI::LEVEL_ERROR,
|
||||||
@@ -29,51 +29,51 @@ class CASLogger implements LoggerInterface
|
|||||||
LogLevel::DEBUG => LogAPI::LEVEL_DEBUG,
|
LogLevel::DEBUG => LogAPI::LEVEL_DEBUG,
|
||||||
];
|
];
|
||||||
|
|
||||||
public function emergency($message, array $context = array())
|
public function emergency($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
IssueLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
IssueLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function alert($message, array $context = array())
|
public function alert($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
IssueLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
IssueLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function critical($message, array $context = array())
|
public function critical($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
IssueLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
IssueLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function error($message, array $context = array())
|
public function error($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
IssueLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
IssueLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function warning($message, array $context = array())
|
public function warning($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Warning('WARNING: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Warning('WARNING: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function notice($message, array $context = array())
|
public function notice($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Info('NOTICE: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Info('NOTICE: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function info($message, array $context = array())
|
public function info($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Info('INFO: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Info('INFO: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function debug($message, array $context = array())
|
public function debug($message, array $context = array()):void
|
||||||
{
|
{
|
||||||
CASLog::Debug('DEBUG: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Debug('DEBUG: '.$message, CASLog::CHANNEL_DEFAULT, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function log($level, $message, array $context = array())
|
public function log($level, $message, array $context = array()):void
|
||||||
{
|
{
|
||||||
$sLevel = self::LEVEL_COMPAT[$level] ?? LogAPI::LEVEL_ERROR;
|
$sLevel = self::LEVEL_COMPAT[$level] ?? LogAPI::LEVEL_ERROR;
|
||||||
CASLog::Log($sLevel, strtoupper($level).": $message", CASLog::CHANNEL_DEFAULT, $context);
|
CASLog::Log($sLevel, strtoupper($level).": $message", CASLog::CHANNEL_DEFAULT, $context);
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
codecov:
|
|
||||||
strict_yaml_branch: master
|
|
||||||
|
|
||||||
coverage:
|
|
||||||
round: up
|
|
||||||
precision: 2
|
|
||||||
status:
|
|
||||||
project:
|
|
||||||
default:
|
|
||||||
target: "70%"
|
|
||||||
informational: true
|
|
||||||
patch: # temporarily disabled
|
|
||||||
default:
|
|
||||||
target: "70%"
|
|
||||||
informational: true
|
|
||||||
|
|
||||||
comment: false
|
|
||||||
7
lib/apereo/phpcas/.gitattributes
vendored
7
lib/apereo/phpcas/.gitattributes
vendored
@@ -1,7 +0,0 @@
|
|||||||
/docs/ export-ignore
|
|
||||||
/test/ export-ignore
|
|
||||||
/utils/ export-ignore
|
|
||||||
/.buildpath export-ignore
|
|
||||||
/.gitignore export-ignore
|
|
||||||
/.project export-ignore
|
|
||||||
/.travis.yml export-ignore
|
|
||||||
7
lib/apereo/phpcas/.github/dependabot.yml
vendored
7
lib/apereo/phpcas/.github/dependabot.yml
vendored
@@ -1,7 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: composer
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
43
lib/apereo/phpcas/.github/workflows/test.yml
vendored
43
lib/apereo/phpcas/.github/workflows/test.yml
vendored
@@ -1,43 +0,0 @@
|
|||||||
name: Test
|
|
||||||
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
php-version:
|
|
||||||
- php: '7.2'
|
|
||||||
phpunit: '8'
|
|
||||||
- php: '7.3'
|
|
||||||
phpunit: latest
|
|
||||||
- php: '7.4'
|
|
||||||
phpunit: latest
|
|
||||||
- php: '8.0'
|
|
||||||
phpunit: latest
|
|
||||||
- php: '8.1'
|
|
||||||
phpunit: latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: php-actions/composer@v6
|
|
||||||
with:
|
|
||||||
php_version: "${{ matrix.php-version.php }}"
|
|
||||||
- name: Run PHPUnit
|
|
||||||
uses: php-actions/phpunit@v3
|
|
||||||
with:
|
|
||||||
version: "${{ matrix.php-version.phpunit }}"
|
|
||||||
php_version: "${{ matrix.php-version.php }}"
|
|
||||||
php_extensions: xdebug
|
|
||||||
args: --verbose --coverage-clover=coverage.xml
|
|
||||||
bootstrap: vendor/autoload.php
|
|
||||||
env:
|
|
||||||
XDEBUG_MODE: coverage
|
|
||||||
- name: Report coverage
|
|
||||||
uses: codecov/codecov-action@v1
|
|
||||||
with:
|
|
||||||
files: coverage.xml
|
|
||||||
@@ -33,12 +33,12 @@
|
|||||||
"phpstan/phpstan" : "^1.5"
|
"phpstan/phpstan" : "^1.5"
|
||||||
},
|
},
|
||||||
"autoload" : {
|
"autoload" : {
|
||||||
|
"files": ["source/CAS.php"],
|
||||||
"classmap" : [
|
"classmap" : [
|
||||||
"source/"
|
"source/"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"autoload-dev" : {
|
"autoload-dev" : {
|
||||||
"files": ["source/CAS.php"],
|
|
||||||
"psr-4" : {
|
"psr-4" : {
|
||||||
"PhpCas\\" : "test/CAS/"
|
"PhpCas\\" : "test/CAS/"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="source/CAS.php" convertNoticesToExceptions="false" colors="true" stderr="true" backupGlobals="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
|
|
||||||
<coverage includeUncoveredFiles="false">
|
|
||||||
<include>
|
|
||||||
<directory>source/</directory>
|
|
||||||
</include>
|
|
||||||
</coverage>
|
|
||||||
<testsuites>
|
|
||||||
<testsuite name="phpCAS Tests">
|
|
||||||
<directory>test/CAS/Tests/</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
</phpunit>
|
|
||||||
@@ -57,7 +57,7 @@ if (!isset($_SERVER['REQUEST_URI']) && isset($_SERVER['SCRIPT_NAME']) && isset($
|
|||||||
/**
|
/**
|
||||||
* phpCAS version. accessible for the user by phpCAS::getVersion().
|
* phpCAS version. accessible for the user by phpCAS::getVersion().
|
||||||
*/
|
*/
|
||||||
define('PHPCAS_VERSION', '1.6.0');
|
define('PHPCAS_VERSION', '1.6.1');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup public
|
* @addtogroup public
|
||||||
|
|||||||
@@ -973,11 +973,6 @@ class CAS_Client
|
|||||||
session_start();
|
session_start();
|
||||||
phpCAS :: trace("Starting a new session " . session_id());
|
phpCAS :: trace("Starting a new session " . session_id());
|
||||||
}
|
}
|
||||||
// init phpCAS session array
|
|
||||||
if (!isset($_SESSION[static::PHPCAS_SESSION_PREFIX])
|
|
||||||
|| !is_array($_SESSION[static::PHPCAS_SESSION_PREFIX])) {
|
|
||||||
$_SESSION[static::PHPCAS_SESSION_PREFIX] = array();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only for debug purposes
|
// Only for debug purposes
|
||||||
@@ -1198,9 +1193,21 @@ class CAS_Client
|
|||||||
{
|
{
|
||||||
$this->validateSession($key);
|
$this->validateSession($key);
|
||||||
|
|
||||||
|
$this->ensureSessionArray();
|
||||||
$_SESSION[static::PHPCAS_SESSION_PREFIX][$key] = $value;
|
$_SESSION[static::PHPCAS_SESSION_PREFIX][$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that the session array is initialized before writing to it.
|
||||||
|
*/
|
||||||
|
protected function ensureSessionArray() {
|
||||||
|
// init phpCAS session array
|
||||||
|
if (!isset($_SESSION[static::PHPCAS_SESSION_PREFIX])
|
||||||
|
|| !is_array($_SESSION[static::PHPCAS_SESSION_PREFIX])) {
|
||||||
|
$_SESSION[static::PHPCAS_SESSION_PREFIX] = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a session value with the given key.
|
* Remove a session value with the given key.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -4,15 +4,16 @@
|
|||||||
/**
|
/**
|
||||||
* Proxy PHP file generated by Composer
|
* Proxy PHP file generated by Composer
|
||||||
*
|
*
|
||||||
* This file includes the referenced bin path (../laminas/laminas-servicemanager/bin/generate-deps-for-config-factory) using ob_start to remove the shebang if present
|
* This file includes the referenced bin path (../laminas/laminas-servicemanager/bin/generate-deps-for-config-factory)
|
||||||
* to prevent the shebang from being output on PHP<8
|
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||||
*
|
*
|
||||||
* @generated
|
* @generated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Composer;
|
namespace Composer;
|
||||||
|
|
||||||
$binPath = __DIR__ . "/" . '../laminas/laminas-servicemanager/bin/generate-deps-for-config-factory';
|
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||||
|
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
if (PHP_VERSION_ID < 80000) {
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||||
@@ -23,18 +24,17 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
{
|
{
|
||||||
private $handle;
|
private $handle;
|
||||||
private $position;
|
private $position;
|
||||||
|
private $realpath;
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
public function stream_open($path, $mode, $options, &$opened_path)
|
||||||
{
|
{
|
||||||
// get rid of composer-bin-proxy:// prefix for __FILE__ & __DIR__ resolution
|
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||||
$opened_path = substr($path, 21);
|
$opened_path = substr($path, 17);
|
||||||
$opened_path = realpath($opened_path) ?: $opened_path;
|
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||||
$this->handle = fopen($opened_path, $mode);
|
$opened_path = $this->realpath;
|
||||||
|
$this->handle = fopen($this->realpath, $mode);
|
||||||
$this->position = 0;
|
$this->position = 0;
|
||||||
|
|
||||||
// remove all traces of this stream wrapper once it has been used
|
|
||||||
stream_wrapper_unregister('composer-bin-proxy');
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
return (bool) $this->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +66,16 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
return $operation ? flock($this->handle, $operation) : true;
|
return $operation ? flock($this->handle, $operation) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function stream_seek($offset, $whence)
|
||||||
|
{
|
||||||
|
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||||
|
$this->position = ftell($this->handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function stream_tell()
|
public function stream_tell()
|
||||||
{
|
{
|
||||||
return $this->position;
|
return $this->position;
|
||||||
@@ -78,20 +88,32 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
|
|
||||||
public function stream_stat()
|
public function stream_stat()
|
||||||
{
|
{
|
||||||
return fstat($this->handle);
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
public function stream_set_option($option, $arg1, $arg2)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function url_stat($path, $flags)
|
||||||
|
{
|
||||||
|
$path = substr($path, 17);
|
||||||
|
if (file_exists($path)) {
|
||||||
|
return stat($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('composer-bin-proxy', 'Composer\BinProxyWrapper')) {
|
if (
|
||||||
include("composer-bin-proxy://" . $binPath);
|
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||||
exit(0);
|
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||||
|
) {
|
||||||
|
return include("phpvfscomposer://" . __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-deps-for-config-factory');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include $binPath;
|
return include __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-deps-for-config-factory';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
setlocal DISABLEDELAYEDEXPANSION
|
||||||
SET BIN_TARGET=%~dp0/../laminas/laminas-servicemanager/bin/generate-deps-for-config-factory
|
SET BIN_TARGET=%~dp0/generate-deps-for-config-factory
|
||||||
|
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||||
php "%BIN_TARGET%" %*
|
php "%BIN_TARGET%" %*
|
||||||
|
|||||||
@@ -4,15 +4,16 @@
|
|||||||
/**
|
/**
|
||||||
* Proxy PHP file generated by Composer
|
* Proxy PHP file generated by Composer
|
||||||
*
|
*
|
||||||
* This file includes the referenced bin path (../laminas/laminas-servicemanager/bin/generate-factory-for-class) using ob_start to remove the shebang if present
|
* This file includes the referenced bin path (../laminas/laminas-servicemanager/bin/generate-factory-for-class)
|
||||||
* to prevent the shebang from being output on PHP<8
|
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||||
*
|
*
|
||||||
* @generated
|
* @generated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Composer;
|
namespace Composer;
|
||||||
|
|
||||||
$binPath = __DIR__ . "/" . '../laminas/laminas-servicemanager/bin/generate-factory-for-class';
|
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||||
|
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
if (PHP_VERSION_ID < 80000) {
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||||
@@ -23,18 +24,17 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
{
|
{
|
||||||
private $handle;
|
private $handle;
|
||||||
private $position;
|
private $position;
|
||||||
|
private $realpath;
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
public function stream_open($path, $mode, $options, &$opened_path)
|
||||||
{
|
{
|
||||||
// get rid of composer-bin-proxy:// prefix for __FILE__ & __DIR__ resolution
|
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||||
$opened_path = substr($path, 21);
|
$opened_path = substr($path, 17);
|
||||||
$opened_path = realpath($opened_path) ?: $opened_path;
|
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||||
$this->handle = fopen($opened_path, $mode);
|
$opened_path = $this->realpath;
|
||||||
|
$this->handle = fopen($this->realpath, $mode);
|
||||||
$this->position = 0;
|
$this->position = 0;
|
||||||
|
|
||||||
// remove all traces of this stream wrapper once it has been used
|
|
||||||
stream_wrapper_unregister('composer-bin-proxy');
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
return (bool) $this->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +66,16 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
return $operation ? flock($this->handle, $operation) : true;
|
return $operation ? flock($this->handle, $operation) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function stream_seek($offset, $whence)
|
||||||
|
{
|
||||||
|
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||||
|
$this->position = ftell($this->handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function stream_tell()
|
public function stream_tell()
|
||||||
{
|
{
|
||||||
return $this->position;
|
return $this->position;
|
||||||
@@ -78,20 +88,32 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
|
|
||||||
public function stream_stat()
|
public function stream_stat()
|
||||||
{
|
{
|
||||||
return fstat($this->handle);
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
public function stream_set_option($option, $arg1, $arg2)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function url_stat($path, $flags)
|
||||||
|
{
|
||||||
|
$path = substr($path, 17);
|
||||||
|
if (file_exists($path)) {
|
||||||
|
return stat($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('composer-bin-proxy', 'Composer\BinProxyWrapper')) {
|
if (
|
||||||
include("composer-bin-proxy://" . $binPath);
|
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||||
exit(0);
|
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||||
|
) {
|
||||||
|
return include("phpvfscomposer://" . __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-factory-for-class');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include $binPath;
|
return include __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-factory-for-class';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
setlocal DISABLEDELAYEDEXPANSION
|
||||||
SET BIN_TARGET=%~dp0/../laminas/laminas-servicemanager/bin/generate-factory-for-class
|
SET BIN_TARGET=%~dp0/generate-factory-for-class
|
||||||
|
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||||
php "%BIN_TARGET%" %*
|
php "%BIN_TARGET%" %*
|
||||||
|
|||||||
@@ -112,9 +112,8 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||||
) {
|
) {
|
||||||
include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse');
|
return include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse');
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse';
|
return include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse';
|
||||||
|
|||||||
@@ -630,6 +630,7 @@ return array(
|
|||||||
'Firebase\\JWT\\ExpiredException' => $vendorDir . '/firebase/php-jwt/src/ExpiredException.php',
|
'Firebase\\JWT\\ExpiredException' => $vendorDir . '/firebase/php-jwt/src/ExpiredException.php',
|
||||||
'Firebase\\JWT\\JWK' => $vendorDir . '/firebase/php-jwt/src/JWK.php',
|
'Firebase\\JWT\\JWK' => $vendorDir . '/firebase/php-jwt/src/JWK.php',
|
||||||
'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php',
|
'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php',
|
||||||
|
'Firebase\\JWT\\JWTExceptionWithPayloadInterface' => $vendorDir . '/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
|
||||||
'Firebase\\JWT\\Key' => $vendorDir . '/firebase/php-jwt/src/Key.php',
|
'Firebase\\JWT\\Key' => $vendorDir . '/firebase/php-jwt/src/Key.php',
|
||||||
'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
||||||
'FunctionExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
'FunctionExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||||
@@ -816,6 +817,8 @@ return array(
|
|||||||
'Laminas\\Mail\\Protocol\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Exception/RuntimeException.php',
|
'Laminas\\Mail\\Protocol\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Exception/RuntimeException.php',
|
||||||
'Laminas\\Mail\\Protocol\\Imap' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Imap.php',
|
'Laminas\\Mail\\Protocol\\Imap' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Imap.php',
|
||||||
'Laminas\\Mail\\Protocol\\Pop3' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Pop3.php',
|
'Laminas\\Mail\\Protocol\\Pop3' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Pop3.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Pop3\\Response' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Pop3/Response.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Pop3\\Xoauth2\\Microsoft' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Pop3/Xoauth2/Microsoft.php',
|
||||||
'Laminas\\Mail\\Protocol\\ProtocolTrait' => $vendorDir . '/laminas/laminas-mail/src/Protocol/ProtocolTrait.php',
|
'Laminas\\Mail\\Protocol\\ProtocolTrait' => $vendorDir . '/laminas/laminas-mail/src/Protocol/ProtocolTrait.php',
|
||||||
'Laminas\\Mail\\Protocol\\Smtp' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp.php',
|
'Laminas\\Mail\\Protocol\\Smtp' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp.php',
|
||||||
'Laminas\\Mail\\Protocol\\SmtpPluginManager' => $vendorDir . '/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php',
|
'Laminas\\Mail\\Protocol\\SmtpPluginManager' => $vendorDir . '/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php',
|
||||||
@@ -823,6 +826,8 @@ return array(
|
|||||||
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Crammd5' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php',
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Crammd5' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php',
|
||||||
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Login' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php',
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Login' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php',
|
||||||
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Plain' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php',
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Plain' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Xoauth2' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Xoauth2.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Xoauth2\\Xoauth2' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Xoauth2/Xoauth2.php',
|
||||||
'Laminas\\Mail\\Storage' => $vendorDir . '/laminas/laminas-mail/src/Storage.php',
|
'Laminas\\Mail\\Storage' => $vendorDir . '/laminas/laminas-mail/src/Storage.php',
|
||||||
'Laminas\\Mail\\Storage\\AbstractStorage' => $vendorDir . '/laminas/laminas-mail/src/Storage/AbstractStorage.php',
|
'Laminas\\Mail\\Storage\\AbstractStorage' => $vendorDir . '/laminas/laminas-mail/src/Storage/AbstractStorage.php',
|
||||||
'Laminas\\Mail\\Storage\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php',
|
'Laminas\\Mail\\Storage\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php',
|
||||||
@@ -1212,6 +1217,7 @@ return array(
|
|||||||
'PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php',
|
||||||
|
'PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
|
||||||
@@ -1453,14 +1459,14 @@ return array(
|
|||||||
'Psr\\Http\\Message\\UploadedFileInterface' => $vendorDir . '/psr/http-message/src/UploadedFileInterface.php',
|
'Psr\\Http\\Message\\UploadedFileInterface' => $vendorDir . '/psr/http-message/src/UploadedFileInterface.php',
|
||||||
'Psr\\Http\\Message\\UriFactoryInterface' => $vendorDir . '/psr/http-factory/src/UriFactoryInterface.php',
|
'Psr\\Http\\Message\\UriFactoryInterface' => $vendorDir . '/psr/http-factory/src/UriFactoryInterface.php',
|
||||||
'Psr\\Http\\Message\\UriInterface' => $vendorDir . '/psr/http-message/src/UriInterface.php',
|
'Psr\\Http\\Message\\UriInterface' => $vendorDir . '/psr/http-message/src/UriInterface.php',
|
||||||
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
|
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/src/AbstractLogger.php',
|
||||||
'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
|
'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/src/InvalidArgumentException.php',
|
||||||
'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
|
'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/src/LogLevel.php',
|
||||||
'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php',
|
'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/src/LoggerAwareInterface.php',
|
||||||
'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php',
|
'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/src/LoggerAwareTrait.php',
|
||||||
'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
|
'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/src/LoggerInterface.php',
|
||||||
'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
|
'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/src/LoggerTrait.php',
|
||||||
'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
|
'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/src/NullLogger.php',
|
||||||
'QRcode' => $vendorDir . '/combodo/tcpdf/include/barcodes/qrcode.php',
|
'QRcode' => $vendorDir . '/combodo/tcpdf/include/barcodes/qrcode.php',
|
||||||
'Query' => $baseDir . '/application/query.class.inc.php',
|
'Query' => $baseDir . '/application/query.class.inc.php',
|
||||||
'QueryBuilderContext' => $baseDir . '/core/querybuildercontext.class.inc.php',
|
'QueryBuilderContext' => $baseDir . '/core/querybuildercontext.class.inc.php',
|
||||||
@@ -2944,6 +2950,8 @@ return array(
|
|||||||
'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
|
'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\GreaterBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
|
'Twig\\Node\\Expression\\Binary\\GreaterBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
|
'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
|
||||||
|
'Twig\\Node\\Expression\\Binary\\HasEveryBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php',
|
||||||
|
'Twig\\Node\\Expression\\Binary\\HasSomeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\InBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
|
'Twig\\Node\\Expression\\Binary\\InBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\LessBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
|
'Twig\\Node\\Expression\\Binary\\LessBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
|
'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
|
||||||
|
|||||||
@@ -20,5 +20,6 @@ return array(
|
|||||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
|
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
|
||||||
|
'344f11dc3484aaed5cbde58e23513be4' => $vendorDir . '/apereo/phpcas/source/CAS.php',
|
||||||
'6997bc0ca52a383ea79e2a4a84bb1f3e' => $baseDir . '/sources/alias.php',
|
'6997bc0ca52a383ea79e2a4a84bb1f3e' => $baseDir . '/sources/alias.php',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ return array(
|
|||||||
'Symfony\\Bridge\\Twig\\' => array($vendorDir . '/symfony/twig-bridge'),
|
'Symfony\\Bridge\\Twig\\' => array($vendorDir . '/symfony/twig-bridge'),
|
||||||
'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'),
|
'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'),
|
||||||
'Sabberworm\\CSS\\' => array($vendorDir . '/sabberworm/php-css-parser/src'),
|
'Sabberworm\\CSS\\' => array($vendorDir . '/sabberworm/php-css-parser/src'),
|
||||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
'Psr\\Log\\' => array($vendorDir . '/psr/log/src'),
|
||||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
||||||
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
|
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
|
||||||
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
|
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
|
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
|
||||||
|
'344f11dc3484aaed5cbde58e23513be4' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS.php',
|
||||||
'6997bc0ca52a383ea79e2a4a84bb1f3e' => __DIR__ . '/../..' . '/sources/alias.php',
|
'6997bc0ca52a383ea79e2a4a84bb1f3e' => __DIR__ . '/../..' . '/sources/alias.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -280,7 +281,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
),
|
),
|
||||||
'Psr\\Log\\' =>
|
'Psr\\Log\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
|
0 => __DIR__ . '/..' . '/psr/log/src',
|
||||||
),
|
),
|
||||||
'Psr\\Http\\Message\\' =>
|
'Psr\\Http\\Message\\' =>
|
||||||
array (
|
array (
|
||||||
@@ -1004,6 +1005,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Firebase\\JWT\\ExpiredException' => __DIR__ . '/..' . '/firebase/php-jwt/src/ExpiredException.php',
|
'Firebase\\JWT\\ExpiredException' => __DIR__ . '/..' . '/firebase/php-jwt/src/ExpiredException.php',
|
||||||
'Firebase\\JWT\\JWK' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWK.php',
|
'Firebase\\JWT\\JWK' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWK.php',
|
||||||
'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php',
|
'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php',
|
||||||
|
'Firebase\\JWT\\JWTExceptionWithPayloadInterface' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
|
||||||
'Firebase\\JWT\\Key' => __DIR__ . '/..' . '/firebase/php-jwt/src/Key.php',
|
'Firebase\\JWT\\Key' => __DIR__ . '/..' . '/firebase/php-jwt/src/Key.php',
|
||||||
'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
||||||
'FunctionExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
'FunctionExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||||
@@ -1190,6 +1192,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Laminas\\Mail\\Protocol\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Exception/RuntimeException.php',
|
'Laminas\\Mail\\Protocol\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Exception/RuntimeException.php',
|
||||||
'Laminas\\Mail\\Protocol\\Imap' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Imap.php',
|
'Laminas\\Mail\\Protocol\\Imap' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Imap.php',
|
||||||
'Laminas\\Mail\\Protocol\\Pop3' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Pop3.php',
|
'Laminas\\Mail\\Protocol\\Pop3' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Pop3.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Pop3\\Response' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Pop3/Response.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Pop3\\Xoauth2\\Microsoft' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Pop3/Xoauth2/Microsoft.php',
|
||||||
'Laminas\\Mail\\Protocol\\ProtocolTrait' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/ProtocolTrait.php',
|
'Laminas\\Mail\\Protocol\\ProtocolTrait' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/ProtocolTrait.php',
|
||||||
'Laminas\\Mail\\Protocol\\Smtp' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp.php',
|
'Laminas\\Mail\\Protocol\\Smtp' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp.php',
|
||||||
'Laminas\\Mail\\Protocol\\SmtpPluginManager' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php',
|
'Laminas\\Mail\\Protocol\\SmtpPluginManager' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php',
|
||||||
@@ -1197,6 +1201,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Crammd5' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php',
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Crammd5' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php',
|
||||||
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Login' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php',
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Login' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php',
|
||||||
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Plain' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php',
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Plain' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Xoauth2' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Xoauth2.php',
|
||||||
|
'Laminas\\Mail\\Protocol\\Xoauth2\\Xoauth2' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Xoauth2/Xoauth2.php',
|
||||||
'Laminas\\Mail\\Storage' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage.php',
|
'Laminas\\Mail\\Storage' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage.php',
|
||||||
'Laminas\\Mail\\Storage\\AbstractStorage' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/AbstractStorage.php',
|
'Laminas\\Mail\\Storage\\AbstractStorage' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/AbstractStorage.php',
|
||||||
'Laminas\\Mail\\Storage\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php',
|
'Laminas\\Mail\\Storage\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php',
|
||||||
@@ -1586,6 +1592,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php',
|
||||||
|
'PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
|
||||||
'PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
|
'PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
|
||||||
@@ -1827,14 +1834,14 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Psr\\Http\\Message\\UploadedFileInterface' => __DIR__ . '/..' . '/psr/http-message/src/UploadedFileInterface.php',
|
'Psr\\Http\\Message\\UploadedFileInterface' => __DIR__ . '/..' . '/psr/http-message/src/UploadedFileInterface.php',
|
||||||
'Psr\\Http\\Message\\UriFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/UriFactoryInterface.php',
|
'Psr\\Http\\Message\\UriFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/UriFactoryInterface.php',
|
||||||
'Psr\\Http\\Message\\UriInterface' => __DIR__ . '/..' . '/psr/http-message/src/UriInterface.php',
|
'Psr\\Http\\Message\\UriInterface' => __DIR__ . '/..' . '/psr/http-message/src/UriInterface.php',
|
||||||
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php',
|
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/src/AbstractLogger.php',
|
||||||
'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php',
|
'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/src/InvalidArgumentException.php',
|
||||||
'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php',
|
'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/src/LogLevel.php',
|
||||||
'Psr\\Log\\LoggerAwareInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerAwareInterface.php',
|
'Psr\\Log\\LoggerAwareInterface' => __DIR__ . '/..' . '/psr/log/src/LoggerAwareInterface.php',
|
||||||
'Psr\\Log\\LoggerAwareTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerAwareTrait.php',
|
'Psr\\Log\\LoggerAwareTrait' => __DIR__ . '/..' . '/psr/log/src/LoggerAwareTrait.php',
|
||||||
'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php',
|
'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/src/LoggerInterface.php',
|
||||||
'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php',
|
'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/src/LoggerTrait.php',
|
||||||
'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php',
|
'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/src/NullLogger.php',
|
||||||
'QRcode' => __DIR__ . '/..' . '/combodo/tcpdf/include/barcodes/qrcode.php',
|
'QRcode' => __DIR__ . '/..' . '/combodo/tcpdf/include/barcodes/qrcode.php',
|
||||||
'Query' => __DIR__ . '/../..' . '/application/query.class.inc.php',
|
'Query' => __DIR__ . '/../..' . '/application/query.class.inc.php',
|
||||||
'QueryBuilderContext' => __DIR__ . '/../..' . '/core/querybuildercontext.class.inc.php',
|
'QueryBuilderContext' => __DIR__ . '/../..' . '/core/querybuildercontext.class.inc.php',
|
||||||
@@ -3318,6 +3325,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
|
'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\GreaterBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
|
'Twig\\Node\\Expression\\Binary\\GreaterBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
|
'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
|
||||||
|
'Twig\\Node\\Expression\\Binary\\HasEveryBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php',
|
||||||
|
'Twig\\Node\\Expression\\Binary\\HasSomeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\InBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
|
'Twig\\Node\\Expression\\Binary\\InBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\LessBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
|
'Twig\\Node\\Expression\\Binary\\LessBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
|
||||||
'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
|
'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
|||||||
'name' => 'combodo/itop',
|
'name' => 'combodo/itop',
|
||||||
'pretty_version' => 'dev-develop',
|
'pretty_version' => 'dev-develop',
|
||||||
'version' => 'dev-develop',
|
'version' => 'dev-develop',
|
||||||
'reference' => '02b3e7b6212c01722fdc90b2f636aef42af9a62b',
|
'reference' => '1878aafd4399ad3109742460b5de84883ee87db2',
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -11,9 +11,9 @@
|
|||||||
),
|
),
|
||||||
'versions' => array(
|
'versions' => array(
|
||||||
'apereo/phpcas' => array(
|
'apereo/phpcas' => array(
|
||||||
'pretty_version' => '1.6.0',
|
'pretty_version' => '1.6.1',
|
||||||
'version' => '1.6.0.0',
|
'version' => '1.6.1.0',
|
||||||
'reference' => 'f817c72a961484afef95ac64a9257c8e31f063b9',
|
'reference' => 'c129708154852656aabb13d8606cd5b12dbbabac',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../apereo/phpcas',
|
'install_path' => __DIR__ . '/../apereo/phpcas',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
'combodo/itop' => array(
|
'combodo/itop' => array(
|
||||||
'pretty_version' => 'dev-develop',
|
'pretty_version' => 'dev-develop',
|
||||||
'version' => 'dev-develop',
|
'version' => 'dev-develop',
|
||||||
'reference' => '02b3e7b6212c01722fdc90b2f636aef42af9a62b',
|
'reference' => '1878aafd4399ad3109742460b5de84883ee87db2',
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -44,117 +44,117 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
'firebase/php-jwt' => array(
|
'firebase/php-jwt' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.10.0',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.10.0.0',
|
||||||
'reference' => '4dd1e007f22a927ac77da5a3fbb067b42d3bc224',
|
'reference' => 'a49db6f0a5033aef5143295342f1c95521b075ff',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'guzzlehttp/guzzle' => array(
|
'guzzlehttp/guzzle' => array(
|
||||||
'pretty_version' => '7.7.0',
|
'pretty_version' => '7.8.1',
|
||||||
'version' => '7.7.0.0',
|
'version' => '7.8.1.0',
|
||||||
'reference' => 'fb7566caccf22d74d1ab270de3551f72a58399f5',
|
'reference' => '41042bc7ab002487b876a0683fc8dce04ddce104',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
|
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'guzzlehttp/promises' => array(
|
'guzzlehttp/promises' => array(
|
||||||
'pretty_version' => '2.0.0',
|
'pretty_version' => '2.0.2',
|
||||||
'version' => '2.0.0.0',
|
'version' => '2.0.2.0',
|
||||||
'reference' => '3a494dc7dc1d7d12e511890177ae2d0e6c107da6',
|
'reference' => 'bbff78d96034045e58e13dedd6ad91b5d1253223',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../guzzlehttp/promises',
|
'install_path' => __DIR__ . '/../guzzlehttp/promises',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'guzzlehttp/psr7' => array(
|
'guzzlehttp/psr7' => array(
|
||||||
'pretty_version' => '2.5.0',
|
'pretty_version' => '2.6.2',
|
||||||
'version' => '2.5.0.0',
|
'version' => '2.6.2.0',
|
||||||
'reference' => 'b635f279edd83fc275f822a1188157ffea568ff6',
|
'reference' => '45b30f99ac27b5ca93cb4831afe16285f57b8221',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'laminas/laminas-loader' => array(
|
'laminas/laminas-loader' => array(
|
||||||
'pretty_version' => '2.8.0',
|
'pretty_version' => '2.10.0',
|
||||||
'version' => '2.8.0.0',
|
'version' => '2.10.0.0',
|
||||||
'reference' => 'd0589ec9dd48365fd95ad10d1c906efd7711c16b',
|
'reference' => 'e6fe952304ef40ce45cd814751ab35d42afdad12',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../laminas/laminas-loader',
|
'install_path' => __DIR__ . '/../laminas/laminas-loader',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'laminas/laminas-mail' => array(
|
'laminas/laminas-mail' => array(
|
||||||
'pretty_version' => '2.16.0',
|
'pretty_version' => '2.22.0',
|
||||||
'version' => '2.16.0.0',
|
'version' => '2.22.0.0',
|
||||||
'reference' => '1ee1a384b96c8af29ecad9b3a7adc27a150ebc49',
|
'reference' => '1d307ff65328c00117c6d90ba0084fdd0fc2bd5c',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../laminas/laminas-mail',
|
'install_path' => __DIR__ . '/../laminas/laminas-mail',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'laminas/laminas-mime' => array(
|
'laminas/laminas-mime' => array(
|
||||||
'pretty_version' => '2.9.1',
|
'pretty_version' => '2.12.0',
|
||||||
'version' => '2.9.1.0',
|
'version' => '2.12.0.0',
|
||||||
'reference' => '72d21a1b4bb7086d4a4d7058c0abca180b209184',
|
'reference' => '08cc544778829b7d68d27a097885bd6e7130135e',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../laminas/laminas-mime',
|
'install_path' => __DIR__ . '/../laminas/laminas-mime',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'laminas/laminas-servicemanager' => array(
|
'laminas/laminas-servicemanager' => array(
|
||||||
'pretty_version' => '3.16.0',
|
'pretty_version' => '3.22.1',
|
||||||
'version' => '3.16.0.0',
|
'version' => '3.22.1.0',
|
||||||
'reference' => '863c66733740cd36ebf5e700f4258ef2c68a2a24',
|
'reference' => 'de98d297d4743956a0558a6d71616979ff779328',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../laminas/laminas-servicemanager',
|
'install_path' => __DIR__ . '/../laminas/laminas-servicemanager',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'laminas/laminas-stdlib' => array(
|
'laminas/laminas-stdlib' => array(
|
||||||
'pretty_version' => '3.12.0',
|
'pretty_version' => '3.19.0',
|
||||||
'version' => '3.12.0.0',
|
'version' => '3.19.0.0',
|
||||||
'reference' => 'c5aed3c798018e31fbb7b1e421b8d96bf2cda453',
|
'reference' => '6a192dd0882b514e45506f533b833b623b78fff3',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../laminas/laminas-stdlib',
|
'install_path' => __DIR__ . '/../laminas/laminas-stdlib',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'laminas/laminas-validator' => array(
|
'laminas/laminas-validator' => array(
|
||||||
'pretty_version' => '2.23.0',
|
'pretty_version' => '2.27.0',
|
||||||
'version' => '2.23.0.0',
|
'version' => '2.27.0.0',
|
||||||
'reference' => '6d61b6cc3b222f13807a18d9247cdfb084958b03',
|
'reference' => '451f5e24574a99b86e8e22f0431ccfc6d5c7318b',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../laminas/laminas-validator',
|
'install_path' => __DIR__ . '/../laminas/laminas-validator',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'league/oauth2-client' => array(
|
'league/oauth2-client' => array(
|
||||||
'pretty_version' => '2.6.1',
|
'pretty_version' => '2.7.0',
|
||||||
'version' => '2.6.1.0',
|
'version' => '2.7.0.0',
|
||||||
'reference' => '2334c249907190c132364f5dae0287ab8666aa19',
|
'reference' => '160d6274b03562ebeb55ed18399281d8118b76c8',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../league/oauth2-client',
|
'install_path' => __DIR__ . '/../league/oauth2-client',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'league/oauth2-google' => array(
|
'league/oauth2-google' => array(
|
||||||
'pretty_version' => '3.0.4',
|
'pretty_version' => '4.0.1',
|
||||||
'version' => '3.0.4.0',
|
'version' => '4.0.1.0',
|
||||||
'reference' => '6b79441f244040760bed5fdcd092a2bda7cf34c6',
|
'reference' => '1b01ba18ba31b29e88771e3e0979e5c91d4afe76',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../league/oauth2-google',
|
'install_path' => __DIR__ . '/../league/oauth2-google',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'nikic/php-parser' => array(
|
'nikic/php-parser' => array(
|
||||||
'pretty_version' => 'v4.14.0',
|
'pretty_version' => 'v4.18.0',
|
||||||
'version' => '4.14.0.0',
|
'version' => '4.18.0.0',
|
||||||
'reference' => '34bea19b6e03d8153165d8f30bba4c3be86184c1',
|
'reference' => '1bcbb2179f97633e98bbbc87044ee2611c7d7999',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../nikic/php-parser',
|
'install_path' => __DIR__ . '/../nikic/php-parser',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -261,9 +261,9 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
'psr/http-client' => array(
|
'psr/http-client' => array(
|
||||||
'pretty_version' => '1.0.2',
|
'pretty_version' => '1.0.3',
|
||||||
'version' => '1.0.2.0',
|
'version' => '1.0.3.0',
|
||||||
'reference' => '0955afe48220520692d2d09f7ab7e0f93ffd6a31',
|
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../psr/http-client',
|
'install_path' => __DIR__ . '/../psr/http-client',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -306,9 +306,9 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
'psr/log' => array(
|
'psr/log' => array(
|
||||||
'pretty_version' => '1.1.4',
|
'pretty_version' => '3.0.0',
|
||||||
'version' => '1.1.4.0',
|
'version' => '3.0.0.0',
|
||||||
'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
|
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../psr/log',
|
'install_path' => __DIR__ . '/../psr/log',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -360,9 +360,9 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/cache' => array(
|
'symfony/cache' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'ac2d25f97b17eec6e19760b6b9962a4f7c44356a',
|
'reference' => '14a75869bbb41cb35bc5d9d322473928c6f3f978',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/cache',
|
'install_path' => __DIR__ . '/../symfony/cache',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -393,9 +393,9 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/console' => array(
|
'symfony/console' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'cd9864b47c367450e14ab32f78fdbf98c44c26b6',
|
'reference' => '0254811a143e6bc6c8deea08b589a7e68a37f625',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/console',
|
'install_path' => __DIR__ . '/../symfony/console',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -420,9 +420,9 @@
|
|||||||
'dev_requirement' => true,
|
'dev_requirement' => true,
|
||||||
),
|
),
|
||||||
'symfony/dependency-injection' => array(
|
'symfony/dependency-injection' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => '5dc8ad5f2bbba7046f5947682bf7d868ce80d4e8',
|
'reference' => '226ea431b1eda6f0d9f5a4b278757171960bb195',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/dependency-injection',
|
'install_path' => __DIR__ . '/../symfony/dependency-injection',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -438,9 +438,9 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/dotenv' => array(
|
'symfony/dotenv' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'd0d584a91422ddaa2c94317200d4c4e5b935555f',
|
'reference' => '835f8d2d1022934ac038519de40b88158798c96f',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/dotenv',
|
'install_path' => __DIR__ . '/../symfony/dotenv',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -456,9 +456,9 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/event-dispatcher' => array(
|
'symfony/event-dispatcher' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'd76d2632cfc2206eecb5ad2b26cd5934082941b6',
|
'reference' => 'e95216850555cd55e71b857eb9d6c2674124603a',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
|
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -498,27 +498,27 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/framework-bundle' => array(
|
'symfony/framework-bundle' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => '981e016715b4a7f22f58c1d9fdf444311965d25e',
|
'reference' => 'c26a221e0462027d1f9d4a802ed63f8ab07a43d0',
|
||||||
'type' => 'symfony-bundle',
|
'type' => 'symfony-bundle',
|
||||||
'install_path' => __DIR__ . '/../symfony/framework-bundle',
|
'install_path' => __DIR__ . '/../symfony/framework-bundle',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/http-foundation' => array(
|
'symfony/http-foundation' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => '44a6d39a9cc11e154547d882d5aac1e014440771',
|
'reference' => '172d807f9ef3fc3fbed8377cc57c20d389269271',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/http-kernel' => array(
|
'symfony/http-kernel' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => '16a29c453966f29466ad34444ce97970a336f3c8',
|
'reference' => '13e8387320b5942d0dc408440c888e2d526efef4',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/http-kernel',
|
'install_path' => __DIR__ . '/../symfony/http-kernel',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -597,9 +597,9 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/routing' => array(
|
'symfony/routing' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'ae014d60d7c8e80be5c3b644a286e91249a3e8f4',
|
'reference' => '98eab13a07fddc85766f1756129c69f207ffbc21',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/routing',
|
'install_path' => __DIR__ . '/../symfony/routing',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -615,9 +615,9 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/service-contracts' => array(
|
'symfony/service-contracts' => array(
|
||||||
'pretty_version' => 'v2.5.2',
|
'pretty_version' => 'v3.4.1',
|
||||||
'version' => '2.5.2.0',
|
'version' => '3.4.1.0',
|
||||||
'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c',
|
'reference' => 'fe07cbc8d837f60caf7018068e350cc5163681a0',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/service-contracts',
|
'install_path' => __DIR__ . '/../symfony/service-contracts',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -639,9 +639,9 @@
|
|||||||
'dev_requirement' => true,
|
'dev_requirement' => true,
|
||||||
),
|
),
|
||||||
'symfony/string' => array(
|
'symfony/string' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'b45fcf399ea9c3af543a92edf7172ba21174d809',
|
'reference' => '7cb80bc10bfcdf6b5492741c0b9357dac66940bc',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/string',
|
'install_path' => __DIR__ . '/../symfony/string',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -675,27 +675,27 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/var-dumper' => array(
|
'symfony/var-dumper' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'c40f7d17e91d8b407582ed51a2bbf83c52c367f6',
|
'reference' => '68d6573ec98715ddcae5a0a85bee3c1c27a4c33f',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/var-exporter' => array(
|
'symfony/var-exporter' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => 'd6081c0316f0f5921f2010d1766925005a82ea3b',
|
'reference' => '5fe9a0021b8d35e67d914716ec8de50716a68e7e',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/var-exporter',
|
'install_path' => __DIR__ . '/../symfony/var-exporter',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/web-profiler-bundle' => array(
|
'symfony/web-profiler-bundle' => array(
|
||||||
'pretty_version' => 'v6.4.0',
|
'pretty_version' => 'v6.4.2',
|
||||||
'version' => '6.4.0.0',
|
'version' => '6.4.2.0',
|
||||||
'reference' => '14752d3fb77c3c69b6cee7c03c06e2d6494a196b',
|
'reference' => '38462d16856740ec0d1ba2cb902eebf09100dde2',
|
||||||
'type' => 'symfony-bundle',
|
'type' => 'symfony-bundle',
|
||||||
'install_path' => __DIR__ . '/../symfony/web-profiler-bundle',
|
'install_path' => __DIR__ . '/../symfony/web-profiler-bundle',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -717,18 +717,18 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
'thenetworg/oauth2-azure' => array(
|
'thenetworg/oauth2-azure' => array(
|
||||||
'pretty_version' => 'v2.1.1',
|
'pretty_version' => 'v2.2.2',
|
||||||
'version' => '2.1.1.0',
|
'version' => '2.2.2.0',
|
||||||
'reference' => '06fb2d620fb6e6c934f632c7ec7c5ea2e978a844',
|
'reference' => 'be204a5135f016470a9c33e82ab48785bbc11af2',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../thenetworg/oauth2-azure',
|
'install_path' => __DIR__ . '/../thenetworg/oauth2-azure',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'twig/twig' => array(
|
'twig/twig' => array(
|
||||||
'pretty_version' => 'v3.4.3',
|
'pretty_version' => 'v3.8.0',
|
||||||
'version' => '3.4.3.0',
|
'version' => '3.8.0.0',
|
||||||
'reference' => 'c38fd6b0b7f370c198db91ffd02e23b517426b58',
|
'reference' => '9d15f0ac07f44dc4217883ec6ae02fd555c6f71d',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../twig/twig',
|
'install_path' => __DIR__ . '/../twig/twig',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
|
|||||||
@@ -1,5 +1,70 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* allow typ header override ([#546](https://github.com/firebase/php-jwt/issues/546)) ([79cb30b](https://github.com/firebase/php-jwt/commit/79cb30b729a22931b2fbd6b53f20629a83031ba9))
|
||||||
|
|
||||||
|
## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2))
|
||||||
|
|
||||||
|
## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* accept float claims but round down to ignore them ([#492](https://github.com/firebase/php-jwt/issues/492)) ([3936842](https://github.com/firebase/php-jwt/commit/39368423beeaacb3002afa7dcb75baebf204fe7e))
|
||||||
|
* different BeforeValidException messages for nbf and iat ([#526](https://github.com/firebase/php-jwt/issues/526)) ([0a53cf2](https://github.com/firebase/php-jwt/commit/0a53cf2986e45c2bcbf1a269f313ebf56a154ee4))
|
||||||
|
|
||||||
|
## [6.8.0](https://github.com/firebase/php-jwt/compare/v6.7.0...v6.8.0) (2023-06-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add support for P-384 curve ([#515](https://github.com/firebase/php-jwt/issues/515)) ([5de4323](https://github.com/firebase/php-jwt/commit/5de4323f4baf4d70bca8663bd87682a69c656c3d))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* handle invalid http responses ([#508](https://github.com/firebase/php-jwt/issues/508)) ([91c39c7](https://github.com/firebase/php-jwt/commit/91c39c72b22fc3e1191e574089552c1f2041c718))
|
||||||
|
|
||||||
|
## [6.7.0](https://github.com/firebase/php-jwt/compare/v6.6.0...v6.7.0) (2023-06-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add ed25519 support to JWK (public keys) ([#452](https://github.com/firebase/php-jwt/issues/452)) ([e53979a](https://github.com/firebase/php-jwt/commit/e53979abae927de916a75b9d239cfda8ce32be2a))
|
||||||
|
|
||||||
|
## [6.6.0](https://github.com/firebase/php-jwt/compare/v6.5.0...v6.6.0) (2023-06-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* allow get headers when decoding token ([#442](https://github.com/firebase/php-jwt/issues/442)) ([fb85f47](https://github.com/firebase/php-jwt/commit/fb85f47cfaeffdd94faf8defdf07164abcdad6c3))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* only check iat if nbf is not used ([#493](https://github.com/firebase/php-jwt/issues/493)) ([398ccd2](https://github.com/firebase/php-jwt/commit/398ccd25ea12fa84b9e4f1085d5ff448c21ec797))
|
||||||
|
|
||||||
|
## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* allow KID of '0' ([#505](https://github.com/firebase/php-jwt/issues/505)) ([9dc46a9](https://github.com/firebase/php-jwt/commit/9dc46a9c3e5801294249cfd2554c5363c9f9326a))
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Chores
|
||||||
|
|
||||||
|
* drop support for PHP 7.3 ([#495](https://github.com/firebase/php-jwt/issues/495))
|
||||||
|
|
||||||
## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08)
|
## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,12 @@ $payload = [
|
|||||||
*/
|
*/
|
||||||
$jwt = JWT::encode($payload, $key, 'HS256');
|
$jwt = JWT::encode($payload, $key, 'HS256');
|
||||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||||
|
|
||||||
print_r($decoded);
|
print_r($decoded);
|
||||||
|
|
||||||
|
// Pass a stdClass in as the third parameter to get the decoded header values
|
||||||
|
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass());
|
||||||
|
print_r($headers);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE: This will now be an object instead of an associative array. To get
|
NOTE: This will now be an object instead of an associative array. To get
|
||||||
an associative array, you will need to cast it as such:
|
an associative array, you will need to cast it as such:
|
||||||
@@ -65,6 +68,40 @@ $decoded_array = (array) $decoded;
|
|||||||
JWT::$leeway = 60; // $leeway in seconds
|
JWT::$leeway = 60; // $leeway in seconds
|
||||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||||
```
|
```
|
||||||
|
Example encode/decode headers
|
||||||
|
-------
|
||||||
|
Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by
|
||||||
|
this library. This is because without verifying the JWT, the header values could have been tampered with.
|
||||||
|
Any value pulled from an unverified header should be treated as if it could be any string sent in from an
|
||||||
|
attacker. If this is something you still want to do in your application for whatever reason, it's possible to
|
||||||
|
decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT
|
||||||
|
header part:
|
||||||
|
```php
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
|
||||||
|
$key = 'example_key';
|
||||||
|
$payload = [
|
||||||
|
'iss' => 'http://example.org',
|
||||||
|
'aud' => 'http://example.com',
|
||||||
|
'iat' => 1356999524,
|
||||||
|
'nbf' => 1357000000
|
||||||
|
];
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'x-forwarded-for' => 'www.google.com'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Encode headers in the JWT string
|
||||||
|
$jwt = JWT::encode($payload, $key, 'HS256', null, $headers);
|
||||||
|
|
||||||
|
// Decode headers from the JWT string WITHOUT validation
|
||||||
|
// **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified.
|
||||||
|
// These headers could be any value sent by an attacker.
|
||||||
|
list($headersB64, $payloadB64, $sig) = explode('.', $jwt);
|
||||||
|
$decoded = json_decode(base64_decode($headersB64), true);
|
||||||
|
|
||||||
|
print_r($decoded);
|
||||||
|
```
|
||||||
Example with RS256 (openssl)
|
Example with RS256 (openssl)
|
||||||
----------------------------
|
----------------------------
|
||||||
```php
|
```php
|
||||||
@@ -73,28 +110,43 @@ use Firebase\JWT\Key;
|
|||||||
|
|
||||||
$privateKey = <<<EOD
|
$privateKey = <<<EOD
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn
|
MIIEowIBAAKCAQEAuzWHNM5f+amCjQztc5QTfJfzCC5J4nuW+L/aOxZ4f8J3Frew
|
||||||
vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9
|
M2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJhzkPYLae7bTVro3hok0zDITR8F6S
|
||||||
5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB
|
JGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548tu4czCuqU8BGVOlnp6IqBHhAswNMM
|
||||||
AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz
|
78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vSopcT51koWOgiTf3C7nJUoMWZHZI5
|
||||||
bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J
|
HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTzTTqo1SCSH2pooJl9O8at6kkRYsrZ
|
||||||
Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1
|
WwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/BwQIDAQABAoIBAFtGaOqNKGwggn9k
|
||||||
cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5
|
6yzr6GhZ6Wt2rh1Xpq8XUz514UBhPxD7dFRLpbzCrLVpzY80LbmVGJ9+1pJozyWc
|
||||||
5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck
|
VKeCeUdNwbqkr240Oe7GTFmGjDoxU+5/HX/SJYPpC8JZ9oqgEA87iz+WQX9hVoP2
|
||||||
ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe
|
oF6EB4ckDvXmk8FMwVZW2l2/kd5mrEVbDaXKxhvUDf52iVD+sGIlTif7mBgR99/b
|
||||||
k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb
|
c3qiCnxCMmfYUnT2eh7Vv2LhCR/G9S6C3R4lA71rEyiU3KgsGfg0d82/XWXbegJW
|
||||||
qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k
|
h3QbWNtQLxTuIvLq5aAryV3PfaHlPgdgK0ft6ocU2de2FagFka3nfVEyC7IUsNTK
|
||||||
eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm
|
bq6nhAECgYEA7d/0DPOIaItl/8BWKyCuAHMss47j0wlGbBSHdJIiS55akMvnAG0M
|
||||||
B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM=
|
39y22Qqfzh1at9kBFeYeFIIU82ZLF3xOcE3z6pJZ4Dyvx4BYdXH77odo9uVK9s1l
|
||||||
|
3T3BlMcqd1hvZLMS7dviyH79jZo4CXSHiKzc7pQ2YfK5eKxKqONeXuECgYEAyXlG
|
||||||
|
vonaus/YTb1IBei9HwaccnQ/1HRn6MvfDjb7JJDIBhNClGPt6xRlzBbSZ73c2QEC
|
||||||
|
6Fu9h36K/HZ2qcLd2bXiNyhIV7b6tVKk+0Psoj0dL9EbhsD1OsmE1nTPyAc9XZbb
|
||||||
|
OPYxy+dpBCUA8/1U9+uiFoCa7mIbWcSQ+39gHuECgYAz82pQfct30aH4JiBrkNqP
|
||||||
|
nJfRq05UY70uk5k1u0ikLTRoVS/hJu/d4E1Kv4hBMqYCavFSwAwnvHUo51lVCr/y
|
||||||
|
xQOVYlsgnwBg2MX4+GjmIkqpSVCC8D7j/73MaWb746OIYZervQ8dbKahi2HbpsiG
|
||||||
|
8AHcVSA/agxZr38qvWV54QKBgCD5TlDE8x18AuTGQ9FjxAAd7uD0kbXNz2vUYg9L
|
||||||
|
hFL5tyL3aAAtUrUUw4xhd9IuysRhW/53dU+FsG2dXdJu6CxHjlyEpUJl2iZu/j15
|
||||||
|
YnMzGWHIEX8+eWRDsw/+Ujtko/B7TinGcWPz3cYl4EAOiCeDUyXnqnO1btCEUU44
|
||||||
|
DJ1BAoGBAJuPD27ErTSVtId90+M4zFPNibFP50KprVdc8CR37BE7r8vuGgNYXmnI
|
||||||
|
RLnGP9p3pVgFCktORuYS2J/6t84I3+A17nEoB4xvhTLeAinAW/uTQOUmNicOP4Ek
|
||||||
|
2MsLL2kHgL8bLTmvXV4FX+PXphrDKg1XxzOYn0otuoqdAQrkK4og
|
||||||
-----END RSA PRIVATE KEY-----
|
-----END RSA PRIVATE KEY-----
|
||||||
EOD;
|
EOD;
|
||||||
|
|
||||||
$publicKey = <<<EOD
|
$publicKey = <<<EOD
|
||||||
-----BEGIN PUBLIC KEY-----
|
-----BEGIN PUBLIC KEY-----
|
||||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzWHNM5f+amCjQztc5QT
|
||||||
4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t
|
fJfzCC5J4nuW+L/aOxZ4f8J3FrewM2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJ
|
||||||
0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4
|
hzkPYLae7bTVro3hok0zDITR8F6SJGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548t
|
||||||
ehde/zUxo6UvS7UrBQIDAQAB
|
u4czCuqU8BGVOlnp6IqBHhAswNMM78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vS
|
||||||
|
opcT51koWOgiTf3C7nJUoMWZHZI5HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTz
|
||||||
|
TTqo1SCSH2pooJl9O8at6kkRYsrZWwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/B
|
||||||
|
wQIDAQAB
|
||||||
-----END PUBLIC KEY-----
|
-----END PUBLIC KEY-----
|
||||||
EOD;
|
EOD;
|
||||||
|
|
||||||
@@ -187,6 +239,44 @@ $decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA'));
|
|||||||
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
|
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
|
||||||
````
|
````
|
||||||
|
|
||||||
|
Example with multiple keys
|
||||||
|
--------------------------
|
||||||
|
```php
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
use Firebase\JWT\Key;
|
||||||
|
|
||||||
|
// Example RSA keys from previous example
|
||||||
|
// $privateKey1 = '...';
|
||||||
|
// $publicKey1 = '...';
|
||||||
|
|
||||||
|
// Example EdDSA keys from previous example
|
||||||
|
// $privateKey2 = '...';
|
||||||
|
// $publicKey2 = '...';
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'iss' => 'example.org',
|
||||||
|
'aud' => 'example.com',
|
||||||
|
'iat' => 1356999524,
|
||||||
|
'nbf' => 1357000000
|
||||||
|
];
|
||||||
|
|
||||||
|
$jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1');
|
||||||
|
$jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2');
|
||||||
|
echo "Encode 1:\n" . print_r($jwt1, true) . "\n";
|
||||||
|
echo "Encode 2:\n" . print_r($jwt2, true) . "\n";
|
||||||
|
|
||||||
|
$keys = [
|
||||||
|
'kid1' => new Key($publicKey1, 'RS256'),
|
||||||
|
'kid2' => new Key($publicKey2, 'EdDSA'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$decoded1 = JWT::decode($jwt1, $keys);
|
||||||
|
$decoded2 = JWT::decode($jwt2, $keys);
|
||||||
|
|
||||||
|
echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n";
|
||||||
|
echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n";
|
||||||
|
```
|
||||||
|
|
||||||
Using JWKs
|
Using JWKs
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@@ -286,6 +376,8 @@ All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`
|
|||||||
like this:
|
like this:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
use UnexpectedValueException;
|
||||||
try {
|
try {
|
||||||
$decoded = JWT::decode($payload, $keys);
|
$decoded = JWT::decode($payload, $keys);
|
||||||
} catch (LogicException $e) {
|
} catch (LogicException $e) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
],
|
],
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.1||^8.0"
|
"php": "^7.4||^8.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
|
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||||
"phpspec/prophecy-phpunit": "^1.1",
|
"phpspec/prophecy-phpunit": "^2.0",
|
||||||
"phpunit/phpunit": "^7.5||^9.5",
|
"phpunit/phpunit": "^9.5",
|
||||||
"psr/cache": "^1.0||^2.0",
|
"psr/cache": "^1.0||^2.0",
|
||||||
"psr/http-client": "^1.0",
|
"psr/http-client": "^1.0",
|
||||||
"psr/http-factory": "^1.0"
|
"psr/http-factory": "^1.0"
|
||||||
|
|||||||
@@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
namespace Firebase\JWT;
|
namespace Firebase\JWT;
|
||||||
|
|
||||||
class BeforeValidException extends \UnexpectedValueException
|
class BeforeValidException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface
|
||||||
{
|
{
|
||||||
|
private object $payload;
|
||||||
|
|
||||||
|
public function setPayload(object $payload): void
|
||||||
|
{
|
||||||
|
$this->payload = $payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPayload(): object
|
||||||
|
{
|
||||||
|
return $this->payload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,16 @@ class CachedKeySet implements ArrayAccess
|
|||||||
}
|
}
|
||||||
$request = $this->httpFactory->createRequest('GET', $this->jwksUri);
|
$request = $this->httpFactory->createRequest('GET', $this->jwksUri);
|
||||||
$jwksResponse = $this->httpClient->sendRequest($request);
|
$jwksResponse = $this->httpClient->sendRequest($request);
|
||||||
|
if ($jwksResponse->getStatusCode() !== 200) {
|
||||||
|
throw new UnexpectedValueException(
|
||||||
|
sprintf('HTTP Error: %d %s for URI "%s"',
|
||||||
|
$jwksResponse->getStatusCode(),
|
||||||
|
$jwksResponse->getReasonPhrase(),
|
||||||
|
$this->jwksUri,
|
||||||
|
),
|
||||||
|
$jwksResponse->getStatusCode()
|
||||||
|
);
|
||||||
|
}
|
||||||
$this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody());
|
$this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody());
|
||||||
|
|
||||||
if (!isset($this->keySet[$keyId])) {
|
if (!isset($this->keySet[$keyId])) {
|
||||||
|
|||||||
@@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
namespace Firebase\JWT;
|
namespace Firebase\JWT;
|
||||||
|
|
||||||
class ExpiredException extends \UnexpectedValueException
|
class ExpiredException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface
|
||||||
{
|
{
|
||||||
|
private object $payload;
|
||||||
|
|
||||||
|
public function setPayload(object $payload): void
|
||||||
|
{
|
||||||
|
$this->payload = $payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPayload(): object
|
||||||
|
{
|
||||||
|
return $this->payload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,16 @@ class JWK
|
|||||||
private const EC_CURVES = [
|
private const EC_CURVES = [
|
||||||
'P-256' => '1.2.840.10045.3.1.7', // Len: 64
|
'P-256' => '1.2.840.10045.3.1.7', // Len: 64
|
||||||
'secp256k1' => '1.3.132.0.10', // Len: 64
|
'secp256k1' => '1.3.132.0.10', // Len: 64
|
||||||
// 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported)
|
'P-384' => '1.3.132.0.34', // Len: 96
|
||||||
// 'P-521' => '1.3.132.0.35', // Len: 132 (not supported)
|
// 'P-521' => '1.3.132.0.35', // Len: 132 (not supported)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// For keys with "kty" equal to "OKP" (Octet Key Pair), the "crv" parameter must contain the key subtype.
|
||||||
|
// This library supports the following subtypes:
|
||||||
|
private const OKP_SUBTYPES = [
|
||||||
|
'Ed25519' => true, // RFC 8037
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a set of JWK keys
|
* Parse a set of JWK keys
|
||||||
*
|
*
|
||||||
@@ -145,8 +151,28 @@ class JWK
|
|||||||
|
|
||||||
$publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']);
|
$publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']);
|
||||||
return new Key($publicKey, $jwk['alg']);
|
return new Key($publicKey, $jwk['alg']);
|
||||||
|
case 'OKP':
|
||||||
|
if (isset($jwk['d'])) {
|
||||||
|
// The key is actually a private key
|
||||||
|
throw new UnexpectedValueException('Key data must be for a public key');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($jwk['crv'])) {
|
||||||
|
throw new UnexpectedValueException('crv not set');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty(self::OKP_SUBTYPES[$jwk['crv']])) {
|
||||||
|
throw new DomainException('Unrecognised or unsupported OKP key subtype');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($jwk['x'])) {
|
||||||
|
throw new UnexpectedValueException('x not set');
|
||||||
|
}
|
||||||
|
|
||||||
|
// This library works internally with EdDSA keys (Ed25519) encoded in standard base64.
|
||||||
|
$publicKey = JWT::convertBase64urlToBase64($jwk['x']);
|
||||||
|
return new Key($publicKey, $jwk['alg']);
|
||||||
default:
|
default:
|
||||||
// Currently only RSA is supported
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +182,7 @@ class JWK
|
|||||||
/**
|
/**
|
||||||
* Converts the EC JWK values to pem format.
|
* Converts the EC JWK values to pem format.
|
||||||
*
|
*
|
||||||
* @param string $crv The EC curve (only P-256 is supported)
|
* @param string $crv The EC curve (only P-256 & P-384 is supported)
|
||||||
* @param string $x The EC x-coordinate
|
* @param string $x The EC x-coordinate
|
||||||
* @param string $y The EC y-coordinate
|
* @param string $y The EC y-coordinate
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -69,11 +69,16 @@ class JWT
|
|||||||
* Decodes a JWT string into a PHP object.
|
* Decodes a JWT string into a PHP object.
|
||||||
*
|
*
|
||||||
* @param string $jwt The JWT
|
* @param string $jwt The JWT
|
||||||
* @param Key|array<string,Key> $keyOrKeyArray The Key or associative array of key IDs (kid) to Key objects.
|
* @param Key|ArrayAccess<string,Key>|array<string,Key> $keyOrKeyArray The Key or associative array of key IDs
|
||||||
* If the algorithm used is asymmetric, this is the public key
|
* (kid) to Key objects.
|
||||||
* Each Key object contains an algorithm and matching key.
|
* If the algorithm used is asymmetric, this is
|
||||||
* Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
|
* the public key.
|
||||||
* 'HS512', 'RS256', 'RS384', and 'RS512'
|
* Each Key object contains an algorithm and
|
||||||
|
* matching key.
|
||||||
|
* Supported algorithms are 'ES384','ES256',
|
||||||
|
* 'HS256', 'HS384', 'HS512', 'RS256', 'RS384'
|
||||||
|
* and 'RS512'.
|
||||||
|
* @param stdClass $headers Optional. Populates stdClass with headers.
|
||||||
*
|
*
|
||||||
* @return stdClass The JWT's payload as a PHP object
|
* @return stdClass The JWT's payload as a PHP object
|
||||||
*
|
*
|
||||||
@@ -90,7 +95,8 @@ class JWT
|
|||||||
*/
|
*/
|
||||||
public static function decode(
|
public static function decode(
|
||||||
string $jwt,
|
string $jwt,
|
||||||
$keyOrKeyArray
|
$keyOrKeyArray,
|
||||||
|
stdClass &$headers = null
|
||||||
): stdClass {
|
): stdClass {
|
||||||
// Validate JWT
|
// Validate JWT
|
||||||
$timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
|
$timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
|
||||||
@@ -107,6 +113,9 @@ class JWT
|
|||||||
if (null === ($header = static::jsonDecode($headerRaw))) {
|
if (null === ($header = static::jsonDecode($headerRaw))) {
|
||||||
throw new UnexpectedValueException('Invalid header encoding');
|
throw new UnexpectedValueException('Invalid header encoding');
|
||||||
}
|
}
|
||||||
|
if ($headers !== null) {
|
||||||
|
$headers = $header;
|
||||||
|
}
|
||||||
$payloadRaw = static::urlsafeB64Decode($bodyb64);
|
$payloadRaw = static::urlsafeB64Decode($bodyb64);
|
||||||
if (null === ($payload = static::jsonDecode($payloadRaw))) {
|
if (null === ($payload = static::jsonDecode($payloadRaw))) {
|
||||||
throw new UnexpectedValueException('Invalid claims encoding');
|
throw new UnexpectedValueException('Invalid claims encoding');
|
||||||
@@ -143,24 +152,30 @@ class JWT
|
|||||||
|
|
||||||
// Check the nbf if it is defined. This is the time that the
|
// Check the nbf if it is defined. This is the time that the
|
||||||
// token can actually be used. If it's not yet that time, abort.
|
// token can actually be used. If it's not yet that time, abort.
|
||||||
if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
|
if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) {
|
||||||
throw new BeforeValidException(
|
$ex = new BeforeValidException(
|
||||||
'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf)
|
'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf)
|
||||||
);
|
);
|
||||||
|
$ex->setPayload($payload);
|
||||||
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that this token has been created before 'now'. This prevents
|
// Check that this token has been created before 'now'. This prevents
|
||||||
// using tokens that have been created for later use (and haven't
|
// using tokens that have been created for later use (and haven't
|
||||||
// correctly used the nbf claim).
|
// correctly used the nbf claim).
|
||||||
if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
|
if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) {
|
||||||
throw new BeforeValidException(
|
$ex = new BeforeValidException(
|
||||||
'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat)
|
'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat)
|
||||||
);
|
);
|
||||||
|
$ex->setPayload($payload);
|
||||||
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this token has expired.
|
// Check if this token has expired.
|
||||||
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
|
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
|
||||||
throw new ExpiredException('Expired token');
|
$ex = new ExpiredException('Expired token');
|
||||||
|
$ex->setPayload($payload);
|
||||||
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $payload;
|
return $payload;
|
||||||
@@ -188,13 +203,14 @@ class JWT
|
|||||||
string $keyId = null,
|
string $keyId = null,
|
||||||
array $head = null
|
array $head = null
|
||||||
): string {
|
): string {
|
||||||
$header = ['typ' => 'JWT', 'alg' => $alg];
|
$header = ['typ' => 'JWT'];
|
||||||
|
if (isset($head) && \is_array($head)) {
|
||||||
|
$header = \array_merge($header, $head);
|
||||||
|
}
|
||||||
|
$header['alg'] = $alg;
|
||||||
if ($keyId !== null) {
|
if ($keyId !== null) {
|
||||||
$header['kid'] = $keyId;
|
$header['kid'] = $keyId;
|
||||||
}
|
}
|
||||||
if (isset($head) && \is_array($head)) {
|
|
||||||
$header = \array_merge($head, $header);
|
|
||||||
}
|
|
||||||
$segments = [];
|
$segments = [];
|
||||||
$segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header));
|
$segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header));
|
||||||
$segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload));
|
$segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload));
|
||||||
@@ -211,7 +227,7 @@ class JWT
|
|||||||
*
|
*
|
||||||
* @param string $msg The message to sign
|
* @param string $msg The message to sign
|
||||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
||||||
* @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
|
* @param string $alg Supported algorithms are 'EdDSA', 'ES384', 'ES256', 'ES256K', 'HS256',
|
||||||
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
|
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
|
||||||
*
|
*
|
||||||
* @return string An encrypted message
|
* @return string An encrypted message
|
||||||
@@ -274,7 +290,7 @@ class JWT
|
|||||||
*
|
*
|
||||||
* @param string $msg The original message (header and body)
|
* @param string $msg The original message (header and body)
|
||||||
* @param string $signature The original signature
|
* @param string $signature The original signature
|
||||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey
|
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey
|
||||||
* @param string $alg The algorithm
|
* @param string $alg The algorithm
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
@@ -376,7 +392,7 @@ class JWT
|
|||||||
}
|
}
|
||||||
if ($errno = \json_last_error()) {
|
if ($errno = \json_last_error()) {
|
||||||
self::handleJsonError($errno);
|
self::handleJsonError($errno);
|
||||||
} elseif ($json === 'null' && $input !== null) {
|
} elseif ($json === 'null') {
|
||||||
throw new DomainException('Null result with non-null input');
|
throw new DomainException('Null result with non-null input');
|
||||||
}
|
}
|
||||||
if ($json === false) {
|
if ($json === false) {
|
||||||
@@ -395,13 +411,28 @@ class JWT
|
|||||||
* @throws InvalidArgumentException invalid base64 characters
|
* @throws InvalidArgumentException invalid base64 characters
|
||||||
*/
|
*/
|
||||||
public static function urlsafeB64Decode(string $input): string
|
public static function urlsafeB64Decode(string $input): string
|
||||||
|
{
|
||||||
|
return \base64_decode(self::convertBase64UrlToBase64($input));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a string in the base64url (URL-safe Base64) encoding to standard base64.
|
||||||
|
*
|
||||||
|
* @param string $input A Base64 encoded string with URL-safe characters (-_ and no padding)
|
||||||
|
*
|
||||||
|
* @return string A Base64 encoded string with standard characters (+/) and padding (=), when
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* @see https://www.rfc-editor.org/rfc/rfc4648
|
||||||
|
*/
|
||||||
|
public static function convertBase64UrlToBase64(string $input): string
|
||||||
{
|
{
|
||||||
$remainder = \strlen($input) % 4;
|
$remainder = \strlen($input) % 4;
|
||||||
if ($remainder) {
|
if ($remainder) {
|
||||||
$padlen = 4 - $remainder;
|
$padlen = 4 - $remainder;
|
||||||
$input .= \str_repeat('=', $padlen);
|
$input .= \str_repeat('=', $padlen);
|
||||||
}
|
}
|
||||||
return \base64_decode(\strtr($input, '-_', '+/'));
|
return \strtr($input, '-_', '+/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -435,7 +466,7 @@ class JWT
|
|||||||
return $keyOrKeyArray;
|
return $keyOrKeyArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($kid)) {
|
if (empty($kid) && $kid !== '0') {
|
||||||
throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
|
throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
namespace Firebase\JWT;
|
||||||
|
|
||||||
|
interface JWTExceptionWithPayloadInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the payload that caused this exception.
|
||||||
|
*
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function getPayload(): object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the payload that caused this exception.
|
||||||
|
*
|
||||||
|
* @param object $payload
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setPayload(object $payload): void;
|
||||||
|
}
|
||||||
@@ -3,6 +3,29 @@
|
|||||||
Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version.
|
Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version.
|
||||||
|
|
||||||
|
|
||||||
|
## 7.8.1 - 2023-12-03
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Updated links in docs to their canonical versions
|
||||||
|
- Replaced `call_user_func*` with native calls
|
||||||
|
|
||||||
|
|
||||||
|
## 7.8.0 - 2023-08-27
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for PHP 8.3
|
||||||
|
- Added automatic closing of handles on `CurlFactory` object destruction
|
||||||
|
|
||||||
|
|
||||||
|
## 7.7.1 - 2023-08-27
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Remove the need for `AllowDynamicProperties` in `CurlMultiHandler`
|
||||||
|
|
||||||
|
|
||||||
## 7.7.0 - 2023-05-21
|
## 7.7.0 - 2023-05-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -628,7 +651,8 @@ object).
|
|||||||
* Note: This has been changed in 5.0.3 to now encode query string values by
|
* Note: This has been changed in 5.0.3 to now encode query string values by
|
||||||
default unless the `rawString` argument is provided when setting the query
|
default unless the `rawString` argument is provided when setting the query
|
||||||
string on a URL: Now allowing many more characters to be present in the
|
string on a URL: Now allowing many more characters to be present in the
|
||||||
query string without being percent encoded. See https://tools.ietf.org/html/rfc3986#appendix-A
|
query string without being percent encoded. See
|
||||||
|
https://datatracker.ietf.org/doc/html/rfc3986#appendix-A
|
||||||
|
|
||||||
|
|
||||||
## 5.0.1 - 2014-10-16
|
## 5.0.1 - 2014-10-16
|
||||||
@@ -1167,7 +1191,7 @@ interfaces.
|
|||||||
|
|
||||||
## 3.4.0 - 2013-04-11
|
## 3.4.0 - 2013-04-11
|
||||||
|
|
||||||
* Bug fix: URLs are now resolved correctly based on https://tools.ietf.org/html/rfc3986#section-5.2. #289
|
* Bug fix: URLs are now resolved correctly based on https://datatracker.ietf.org/doc/html/rfc3986#section-5.2. #289
|
||||||
* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
|
* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
|
||||||
* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
|
* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
|
||||||
* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
|
* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Guzzle, PHP HTTP client
|
# Guzzle, PHP HTTP client
|
||||||
|
|
||||||
[](https://github.com/guzzle/guzzle/releases)
|
[](https://github.com/guzzle/guzzle/releases)
|
||||||
[](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI)
|
[](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI)
|
||||||
[](https://packagist.org/packages/guzzlehttp/guzzle)
|
[](https://packagist.org/packages/guzzlehttp/guzzle)
|
||||||
|
|
||||||
Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and
|
Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and
|
||||||
@@ -66,7 +66,7 @@ composer require guzzlehttp/guzzle
|
|||||||
| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 |
|
| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 |
|
||||||
| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 |
|
| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 |
|
||||||
| 6.x | Security fixes only | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 |
|
| 6.x | Security fixes only | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 |
|
||||||
| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.3 |
|
| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.4 |
|
||||||
|
|
||||||
[guzzle-3-repo]: https://github.com/guzzle/guzzle3
|
[guzzle-3-repo]: https://github.com/guzzle/guzzle3
|
||||||
[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x
|
[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Please make sure:
|
|||||||
- Function `GuzzleHttp\Exception\RequestException::getResponseBodySummary` is removed.
|
- Function `GuzzleHttp\Exception\RequestException::getResponseBodySummary` is removed.
|
||||||
Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative.
|
Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative.
|
||||||
- Function `GuzzleHttp\Cookie\CookieJar::getCookieValue` is removed.
|
- Function `GuzzleHttp\Cookie\CookieJar::getCookieValue` is removed.
|
||||||
- Request option `exception` is removed. Please use `http_errors`.
|
- Request option `exceptions` is removed. Please use `http_errors`.
|
||||||
- Request option `save_to` is removed. Please use `sink`.
|
- Request option `save_to` is removed. Please use `sink`.
|
||||||
- Pool option `pool_size` is removed. Please use `concurrency`.
|
- Pool option `pool_size` is removed. Please use `concurrency`.
|
||||||
- We now look for environment variables in the `$_SERVER` super global, due to thread safety issues with `getenv`. We continue to fallback to `getenv` in CLI environments, for maximum compatibility.
|
- We now look for environment variables in the `$_SERVER` super global, due to thread safety issues with `getenv`. We continue to fallback to `getenv` in CLI environments, for maximum compatibility.
|
||||||
@@ -189,11 +189,11 @@ $client = new GuzzleHttp\Client(['handler' => $handler]);
|
|||||||
|
|
||||||
## POST Requests
|
## POST Requests
|
||||||
|
|
||||||
This version added the [`form_params`](http://guzzle.readthedocs.org/en/latest/request-options.html#form_params)
|
This version added the [`form_params`](https://docs.guzzlephp.org/en/latest/request-options.html#form_params)
|
||||||
and `multipart` request options. `form_params` is an associative array of
|
and `multipart` request options. `form_params` is an associative array of
|
||||||
strings or array of strings and is used to serialize an
|
strings or array of strings and is used to serialize an
|
||||||
`application/x-www-form-urlencoded` POST request. The
|
`application/x-www-form-urlencoded` POST request. The
|
||||||
[`multipart`](http://guzzle.readthedocs.org/en/latest/request-options.html#multipart)
|
[`multipart`](https://docs.guzzlephp.org/en/latest/request-options.html#multipart)
|
||||||
option is now used to send a multipart/form-data POST request.
|
option is now used to send a multipart/form-data POST request.
|
||||||
|
|
||||||
`GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add
|
`GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add
|
||||||
@@ -209,7 +209,7 @@ The `base_url` option has been renamed to `base_uri`.
|
|||||||
|
|
||||||
## Rewritten Adapter Layer
|
## Rewritten Adapter Layer
|
||||||
|
|
||||||
Guzzle now uses [RingPHP](http://ringphp.readthedocs.org/en/latest) to send
|
Guzzle now uses [RingPHP](https://ringphp.readthedocs.org/en/latest) to send
|
||||||
HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor
|
HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor
|
||||||
is still supported, but it has now been renamed to `handler`. Instead of
|
is still supported, but it has now been renamed to `handler`. Instead of
|
||||||
passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP
|
passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP
|
||||||
@@ -575,7 +575,7 @@ You can intercept a request and inject a response using the `intercept()` event
|
|||||||
of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and
|
of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and
|
||||||
`GuzzleHttp\Event\ErrorEvent` event.
|
`GuzzleHttp\Event\ErrorEvent` event.
|
||||||
|
|
||||||
See: http://docs.guzzlephp.org/en/latest/events.html
|
See: https://docs.guzzlephp.org/en/latest/events.html
|
||||||
|
|
||||||
## Inflection
|
## Inflection
|
||||||
|
|
||||||
@@ -668,9 +668,9 @@ in separate repositories:
|
|||||||
|
|
||||||
The service description layer of Guzzle has moved into two separate packages:
|
The service description layer of Guzzle has moved into two separate packages:
|
||||||
|
|
||||||
- http://github.com/guzzle/command Provides a high level abstraction over web
|
- https://github.com/guzzle/command Provides a high level abstraction over web
|
||||||
services by representing web service operations using commands.
|
services by representing web service operations using commands.
|
||||||
- http://github.com/guzzle/guzzle-services Provides an implementation of
|
- https://github.com/guzzle/guzzle-services Provides an implementation of
|
||||||
guzzle/command that provides request serialization and response parsing using
|
guzzle/command that provides request serialization and response parsing using
|
||||||
Guzzle service descriptions.
|
Guzzle service descriptions.
|
||||||
|
|
||||||
@@ -870,7 +870,7 @@ HeaderInterface (e.g. toArray(), getAll(), etc.).
|
|||||||
3.3 to 3.4
|
3.3 to 3.4
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Base URLs of a client now follow the rules of https://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs.
|
Base URLs of a client now follow the rules of https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.2 when merging URLs.
|
||||||
|
|
||||||
3.2 to 3.3
|
3.2 to 3.3
|
||||||
----------
|
----------
|
||||||
|
|||||||
@@ -53,8 +53,8 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.5 || ^8.0",
|
"php": "^7.2.5 || ^8.0",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"guzzlehttp/promises": "^1.5.3 || ^2.0",
|
"guzzlehttp/promises": "^1.5.3 || ^2.0.1",
|
||||||
"guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
|
"guzzlehttp/psr7": "^1.9.1 || ^2.5.1",
|
||||||
"psr/http-client": "^1.0",
|
"psr/http-client": "^1.0",
|
||||||
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||||
},
|
},
|
||||||
@@ -63,10 +63,10 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
|
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
|
||||||
"php-http/message-factory": "^1.1",
|
"php-http/message-factory": "^1.1",
|
||||||
"phpunit/phpunit": "^8.5.29 || ^9.5.23",
|
"phpunit/phpunit": "^8.5.36 || ^9.6.15",
|
||||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||||||
*
|
*
|
||||||
* @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
|
* @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
|
||||||
*/
|
*/
|
||||||
public function getConfig(?string $option = null)
|
public function getConfig(string $option = null)
|
||||||
{
|
{
|
||||||
return $option === null
|
return $option === null
|
||||||
? $this->config
|
? $this->config
|
||||||
|
|||||||
@@ -80,5 +80,5 @@ interface ClientInterface
|
|||||||
*
|
*
|
||||||
* @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0.
|
* @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0.
|
||||||
*/
|
*/
|
||||||
public function getConfig(?string $option = null);
|
public function getConfig(string $option = null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,9 +96,6 @@ class CookieJar implements CookieJarInterface
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function toArray(): array
|
public function toArray(): array
|
||||||
{
|
{
|
||||||
return \array_map(static function (SetCookie $cookie): array {
|
return \array_map(static function (SetCookie $cookie): array {
|
||||||
@@ -106,10 +103,7 @@ class CookieJar implements CookieJarInterface
|
|||||||
}, $this->getIterator()->getArrayCopy());
|
}, $this->getIterator()->getArrayCopy());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function clear(string $domain = null, string $path = null, string $name = null): void
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void
|
|
||||||
{
|
{
|
||||||
if (!$domain) {
|
if (!$domain) {
|
||||||
$this->cookies = [];
|
$this->cookies = [];
|
||||||
@@ -126,25 +120,22 @@ class CookieJar implements CookieJarInterface
|
|||||||
$this->cookies = \array_filter(
|
$this->cookies = \array_filter(
|
||||||
$this->cookies,
|
$this->cookies,
|
||||||
static function (SetCookie $cookie) use ($path, $domain): bool {
|
static function (SetCookie $cookie) use ($path, $domain): bool {
|
||||||
return !($cookie->matchesPath($path) &&
|
return !($cookie->matchesPath($path)
|
||||||
$cookie->matchesDomain($domain));
|
&& $cookie->matchesDomain($domain));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->cookies = \array_filter(
|
$this->cookies = \array_filter(
|
||||||
$this->cookies,
|
$this->cookies,
|
||||||
static function (SetCookie $cookie) use ($path, $domain, $name) {
|
static function (SetCookie $cookie) use ($path, $domain, $name) {
|
||||||
return !($cookie->getName() == $name &&
|
return !($cookie->getName() == $name
|
||||||
$cookie->matchesPath($path) &&
|
&& $cookie->matchesPath($path)
|
||||||
$cookie->matchesDomain($domain));
|
&& $cookie->matchesDomain($domain));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function clearSessionCookies(): void
|
public function clearSessionCookies(): void
|
||||||
{
|
{
|
||||||
$this->cookies = \array_filter(
|
$this->cookies = \array_filter(
|
||||||
@@ -155,9 +146,6 @@ class CookieJar implements CookieJarInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function setCookie(SetCookie $cookie): bool
|
public function setCookie(SetCookie $cookie): bool
|
||||||
{
|
{
|
||||||
// If the name string is empty (but not 0), ignore the set-cookie
|
// If the name string is empty (but not 0), ignore the set-cookie
|
||||||
@@ -182,9 +170,9 @@ class CookieJar implements CookieJarInterface
|
|||||||
foreach ($this->cookies as $i => $c) {
|
foreach ($this->cookies as $i => $c) {
|
||||||
// Two cookies are identical, when their path, and domain are
|
// Two cookies are identical, when their path, and domain are
|
||||||
// identical.
|
// identical.
|
||||||
if ($c->getPath() != $cookie->getPath() ||
|
if ($c->getPath() != $cookie->getPath()
|
||||||
$c->getDomain() != $cookie->getDomain() ||
|
|| $c->getDomain() != $cookie->getDomain()
|
||||||
$c->getName() != $cookie->getName()
|
|| $c->getName() != $cookie->getName()
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -255,7 +243,7 @@ class CookieJar implements CookieJarInterface
|
|||||||
/**
|
/**
|
||||||
* Computes cookie path following RFC 6265 section 5.1.4
|
* Computes cookie path following RFC 6265 section 5.1.4
|
||||||
*
|
*
|
||||||
* @see https://tools.ietf.org/html/rfc6265#section-5.1.4
|
* @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
|
||||||
*/
|
*/
|
||||||
private function getCookiePathFromRequest(RequestInterface $request): string
|
private function getCookiePathFromRequest(RequestInterface $request): string
|
||||||
{
|
{
|
||||||
@@ -286,10 +274,10 @@ class CookieJar implements CookieJarInterface
|
|||||||
$path = $uri->getPath() ?: '/';
|
$path = $uri->getPath() ?: '/';
|
||||||
|
|
||||||
foreach ($this->cookies as $cookie) {
|
foreach ($this->cookies as $cookie) {
|
||||||
if ($cookie->matchesPath($path) &&
|
if ($cookie->matchesPath($path)
|
||||||
$cookie->matchesDomain($host) &&
|
&& $cookie->matchesDomain($host)
|
||||||
!$cookie->isExpired() &&
|
&& !$cookie->isExpired()
|
||||||
(!$cookie->getSecure() || $scheme === 'https')
|
&& (!$cookie->getSecure() || $scheme === 'https')
|
||||||
) {
|
) {
|
||||||
$values[] = $cookie->getName().'='
|
$values[] = $cookie->getName().'='
|
||||||
.$cookie->getValue();
|
.$cookie->getValue();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use Psr\Http\Message\ResponseInterface;
|
|||||||
* cookies from a file, database, etc.
|
* cookies from a file, database, etc.
|
||||||
*
|
*
|
||||||
* @see https://docs.python.org/2/library/cookielib.html Inspiration
|
* @see https://docs.python.org/2/library/cookielib.html Inspiration
|
||||||
|
*
|
||||||
* @extends \IteratorAggregate<SetCookie>
|
* @extends \IteratorAggregate<SetCookie>
|
||||||
*/
|
*/
|
||||||
interface CookieJarInterface extends \Countable, \IteratorAggregate
|
interface CookieJarInterface extends \Countable, \IteratorAggregate
|
||||||
@@ -61,7 +62,7 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate
|
|||||||
* @param string|null $path Clears cookies matching a domain and path
|
* @param string|null $path Clears cookies matching a domain and path
|
||||||
* @param string|null $name Clears cookies matching a domain, path, and name
|
* @param string|null $name Clears cookies matching a domain, path, and name
|
||||||
*/
|
*/
|
||||||
public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void;
|
public function clear(string $domain = null, string $path = null, string $name = null): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discard all sessions cookies.
|
* Discard all sessions cookies.
|
||||||
|
|||||||
@@ -420,7 +420,7 @@ class SetCookie
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove the leading '.' as per spec in RFC 6265.
|
// Remove the leading '.' as per spec in RFC 6265.
|
||||||
// https://tools.ietf.org/html/rfc6265#section-5.2.3
|
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3
|
||||||
$cookieDomain = \ltrim(\strtolower($cookieDomain), '.');
|
$cookieDomain = \ltrim(\strtolower($cookieDomain), '.');
|
||||||
|
|
||||||
$domain = \strtolower($domain);
|
$domain = \strtolower($domain);
|
||||||
@@ -431,7 +431,7 @@ class SetCookie
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Matching the subdomain according to RFC 6265.
|
// Matching the subdomain according to RFC 6265.
|
||||||
// https://tools.ietf.org/html/rfc6265#section-5.1.3
|
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3
|
||||||
if (\filter_var($domain, \FILTER_VALIDATE_IP)) {
|
if (\filter_var($domain, \FILTER_VALIDATE_IP)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ class CurlFactory implements CurlFactoryInterface
|
|||||||
|
|
||||||
$method = $easy->request->getMethod();
|
$method = $easy->request->getMethod();
|
||||||
if ($method === 'PUT' || $method === 'POST') {
|
if ($method === 'PUT' || $method === 'POST') {
|
||||||
// See https://tools.ietf.org/html/rfc7230#section-3.3.2
|
// See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
|
||||||
if (!$easy->request->hasHeader('Content-Length')) {
|
if (!$easy->request->hasHeader('Content-Length')) {
|
||||||
$conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
|
$conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
|
||||||
}
|
}
|
||||||
@@ -367,11 +367,11 @@ class CurlFactory implements CurlFactoryInterface
|
|||||||
// If it's a directory or a link to a directory use CURLOPT_CAPATH.
|
// If it's a directory or a link to a directory use CURLOPT_CAPATH.
|
||||||
// If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
|
// If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
|
||||||
if (
|
if (
|
||||||
\is_dir($options['verify']) ||
|
\is_dir($options['verify'])
|
||||||
(
|
|| (
|
||||||
\is_link($options['verify']) === true &&
|
\is_link($options['verify']) === true
|
||||||
($verifyLink = \readlink($options['verify'])) !== false &&
|
&& ($verifyLink = \readlink($options['verify'])) !== false
|
||||||
\is_dir($verifyLink)
|
&& \is_dir($verifyLink)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
$conf[\CURLOPT_CAPATH] = $options['verify'];
|
$conf[\CURLOPT_CAPATH] = $options['verify'];
|
||||||
@@ -627,4 +627,12 @@ class CurlFactory implements CurlFactoryInterface
|
|||||||
return \strlen($h);
|
return \strlen($h);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
foreach ($this->handles as $id => $handle) {
|
||||||
|
\curl_close($handle);
|
||||||
|
unset($this->handles[$id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,8 @@ use Psr\Http\Message\RequestInterface;
|
|||||||
* associative array of curl option constants mapping to values in the
|
* associative array of curl option constants mapping to values in the
|
||||||
* **curl** key of the provided request options.
|
* **curl** key of the provided request options.
|
||||||
*
|
*
|
||||||
* @property resource|\CurlMultiHandle $_mh Internal use only. Lazy loaded multi-handle.
|
|
||||||
*
|
|
||||||
* @final
|
* @final
|
||||||
*/
|
*/
|
||||||
#[\AllowDynamicProperties]
|
|
||||||
class CurlMultiHandler
|
class CurlMultiHandler
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -56,6 +53,9 @@ class CurlMultiHandler
|
|||||||
*/
|
*/
|
||||||
private $options = [];
|
private $options = [];
|
||||||
|
|
||||||
|
/** @var resource|\CurlMultiHandle */
|
||||||
|
private $_mh;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handler accepts the following options:
|
* This handler accepts the following options:
|
||||||
*
|
*
|
||||||
@@ -79,6 +79,10 @@ class CurlMultiHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->options = $options['options'] ?? [];
|
$this->options = $options['options'] ?? [];
|
||||||
|
|
||||||
|
// unsetting the property forces the first access to go through
|
||||||
|
// __get().
|
||||||
|
unset($this->_mh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class HandlerStack
|
|||||||
* handler is provided, the best handler for your
|
* handler is provided, the best handler for your
|
||||||
* system will be utilized.
|
* system will be utilized.
|
||||||
*/
|
*/
|
||||||
public static function create(?callable $handler = null): self
|
public static function create(callable $handler = null): self
|
||||||
{
|
{
|
||||||
$stack = new self($handler ?: Utils::chooseHandler());
|
$stack = new self($handler ?: Utils::chooseHandler());
|
||||||
$stack->push(Middleware::httpErrors(), 'http_errors');
|
$stack->push(Middleware::httpErrors(), 'http_errors');
|
||||||
@@ -131,7 +131,7 @@ class HandlerStack
|
|||||||
* @param callable(callable): callable $middleware Middleware function
|
* @param callable(callable): callable $middleware Middleware function
|
||||||
* @param string $name Name to register for this middleware.
|
* @param string $name Name to register for this middleware.
|
||||||
*/
|
*/
|
||||||
public function unshift(callable $middleware, ?string $name = null): void
|
public function unshift(callable $middleware, string $name = null): void
|
||||||
{
|
{
|
||||||
\array_unshift($this->stack, [$middleware, $name]);
|
\array_unshift($this->stack, [$middleware, $name]);
|
||||||
$this->cached = null;
|
$this->cached = null;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class MessageFormatter implements MessageFormatterInterface
|
|||||||
* @param ResponseInterface|null $response Response that was received
|
* @param ResponseInterface|null $response Response that was received
|
||||||
* @param \Throwable|null $error Exception that was received
|
* @param \Throwable|null $error Exception that was received
|
||||||
*/
|
*/
|
||||||
public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string
|
public function format(RequestInterface $request, ResponseInterface $response = null, \Throwable $error = null): string
|
||||||
{
|
{
|
||||||
$cache = [];
|
$cache = [];
|
||||||
|
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ interface MessageFormatterInterface
|
|||||||
* @param ResponseInterface|null $response Response that was received
|
* @param ResponseInterface|null $response Response that was received
|
||||||
* @param \Throwable|null $error Exception that was received
|
* @param \Throwable|null $error Exception that was received
|
||||||
*/
|
*/
|
||||||
public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string;
|
public function format(RequestInterface $request, ResponseInterface $response = null, \Throwable $error = null): string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,8 +166,8 @@ class RedirectMiddleware
|
|||||||
// not forcing RFC compliance, but rather emulating what all browsers
|
// not forcing RFC compliance, but rather emulating what all browsers
|
||||||
// would do.
|
// would do.
|
||||||
$statusCode = $response->getStatusCode();
|
$statusCode = $response->getStatusCode();
|
||||||
if ($statusCode == 303 ||
|
if ($statusCode == 303
|
||||||
($statusCode <= 302 && !$options['allow_redirects']['strict'])
|
|| ($statusCode <= 302 && !$options['allow_redirects']['strict'])
|
||||||
) {
|
) {
|
||||||
$safeMethods = ['GET', 'HEAD', 'OPTIONS'];
|
$safeMethods = ['GET', 'HEAD', 'OPTIONS'];
|
||||||
$requestMethod = $request->getMethod();
|
$requestMethod = $request->getMethod();
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ namespace GuzzleHttp;
|
|||||||
/**
|
/**
|
||||||
* This class contains a list of built-in Guzzle request options.
|
* This class contains a list of built-in Guzzle request options.
|
||||||
*
|
*
|
||||||
* More documentation for each option can be found at http://guzzlephp.org/.
|
* @see https://docs.guzzlephp.org/en/latest/request-options.html
|
||||||
*
|
|
||||||
* @see http://docs.guzzlephp.org/en/v6/request-options.html
|
|
||||||
*/
|
*/
|
||||||
final class RequestOptions
|
final class RequestOptions
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ final class TransferStats
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
RequestInterface $request,
|
RequestInterface $request,
|
||||||
?ResponseInterface $response = null,
|
ResponseInterface $response = null,
|
||||||
?float $transferTime = null,
|
float $transferTime = null,
|
||||||
$handlerErrorData = null,
|
$handlerErrorData = null,
|
||||||
array $handlerStats = []
|
array $handlerStats = []
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -176,14 +176,13 @@ No system CA bundle could be found in any of the the common system locations.
|
|||||||
PHP versions earlier than 5.6 are not properly configured to use the system's
|
PHP versions earlier than 5.6 are not properly configured to use the system's
|
||||||
CA bundle by default. In order to verify peer certificates, you will need to
|
CA bundle by default. In order to verify peer certificates, you will need to
|
||||||
supply the path on disk to a certificate bundle to the 'verify' request
|
supply the path on disk to a certificate bundle to the 'verify' request
|
||||||
option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not
|
option: https://docs.guzzlephp.org/en/latest/request-options.html#verify. If
|
||||||
need a specific certificate bundle, then Mozilla provides a commonly used CA
|
you do not need a specific certificate bundle, then Mozilla provides a commonly
|
||||||
bundle which can be downloaded here (provided by the maintainer of cURL):
|
used CA bundle which can be downloaded here (provided by the maintainer of
|
||||||
https://curl.haxx.se/ca/cacert.pem. Once
|
cURL): https://curl.haxx.se/ca/cacert.pem. Once you have a CA bundle available
|
||||||
you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP
|
on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path
|
||||||
ini setting to point to the path to the file, allowing you to omit the 'verify'
|
to the file, allowing you to omit the 'verify' request option. See
|
||||||
request option. See https://curl.haxx.se/docs/sslcerts.html for more
|
https://curl.haxx.se/docs/sslcerts.html for more information.
|
||||||
information.
|
|
||||||
EOT
|
EOT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,21 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
|
||||||
## 2.0.0 - TBC
|
## 2.0.2 - 2023-12-03
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Replaced `call_user_func*` with native calls
|
||||||
|
|
||||||
|
|
||||||
|
## 2.0.1 - 2023-08-03
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- PHP 8.3 support
|
||||||
|
|
||||||
|
|
||||||
|
## 2.0.0 - 2023-05-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ composer require guzzlehttp/promises
|
|||||||
| Version | Status | PHP Version |
|
| Version | Status | PHP Version |
|
||||||
|---------|------------------------|--------------|
|
|---------|------------------------|--------------|
|
||||||
| 1.x | Bug and security fixes | >=5.5,<8.3 |
|
| 1.x | Bug and security fixes | >=5.5,<8.3 |
|
||||||
| 2.x | Latest | >=7.2.5,<8.3 |
|
| 2.x | Latest | >=7.2.5,<8.4 |
|
||||||
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
"php": "^7.2.5 || ^8.0"
|
"php": "^7.2.5 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
|
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ final class Each
|
|||||||
* index, and the aggregate promise. The callback can invoke any necessary
|
* index, and the aggregate promise. The callback can invoke any necessary
|
||||||
* side effects and choose to resolve or reject the aggregate if needed.
|
* side effects and choose to resolve or reject the aggregate if needed.
|
||||||
*
|
*
|
||||||
* @param mixed $iterable Iterator or array to iterate over.
|
* @param mixed $iterable Iterator or array to iterate over.
|
||||||
* @param callable $onFulfilled
|
|
||||||
* @param callable $onRejected
|
|
||||||
*/
|
*/
|
||||||
public static function of(
|
public static function of(
|
||||||
$iterable,
|
$iterable,
|
||||||
@@ -44,8 +42,6 @@ final class Each
|
|||||||
*
|
*
|
||||||
* @param mixed $iterable
|
* @param mixed $iterable
|
||||||
* @param int|callable $concurrency
|
* @param int|callable $concurrency
|
||||||
* @param callable $onFulfilled
|
|
||||||
* @param callable $onRejected
|
|
||||||
*/
|
*/
|
||||||
public static function ofLimit(
|
public static function ofLimit(
|
||||||
$iterable,
|
$iterable,
|
||||||
@@ -67,7 +63,6 @@ final class Each
|
|||||||
*
|
*
|
||||||
* @param mixed $iterable
|
* @param mixed $iterable
|
||||||
* @param int|callable $concurrency
|
* @param int|callable $concurrency
|
||||||
* @param callable $onFulfilled
|
|
||||||
*/
|
*/
|
||||||
public static function ofLimitAll(
|
public static function ofLimitAll(
|
||||||
$iterable,
|
$iterable,
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class EachPromise implements PromisorInterface
|
|||||||
|
|
||||||
// Add only up to N pending promises.
|
// Add only up to N pending promises.
|
||||||
$concurrency = is_callable($this->concurrency)
|
$concurrency = is_callable($this->concurrency)
|
||||||
? call_user_func($this->concurrency, count($this->pending))
|
? ($this->concurrency)(count($this->pending))
|
||||||
: $this->concurrency;
|
: $this->concurrency;
|
||||||
$concurrency = max($concurrency - count($this->pending), 0);
|
$concurrency = max($concurrency - count($this->pending), 0);
|
||||||
// Concurrency may be set to 0 to disallow new promises.
|
// Concurrency may be set to 0 to disallow new promises.
|
||||||
@@ -170,8 +170,7 @@ class EachPromise implements PromisorInterface
|
|||||||
$this->pending[$idx] = $promise->then(
|
$this->pending[$idx] = $promise->then(
|
||||||
function ($value) use ($idx, $key): void {
|
function ($value) use ($idx, $key): void {
|
||||||
if ($this->onFulfilled) {
|
if ($this->onFulfilled) {
|
||||||
call_user_func(
|
($this->onFulfilled)(
|
||||||
$this->onFulfilled,
|
|
||||||
$value,
|
$value,
|
||||||
$key,
|
$key,
|
||||||
$this->aggregate
|
$this->aggregate
|
||||||
@@ -181,8 +180,7 @@ class EachPromise implements PromisorInterface
|
|||||||
},
|
},
|
||||||
function ($reason) use ($idx, $key): void {
|
function ($reason) use ($idx, $key): void {
|
||||||
if ($this->onRejected) {
|
if ($this->onRejected) {
|
||||||
call_user_func(
|
($this->onRejected)(
|
||||||
$this->onRejected,
|
|
||||||
$reason,
|
$reason,
|
||||||
$key,
|
$key,
|
||||||
$this->aggregate
|
$this->aggregate
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class RejectionException extends \RuntimeException
|
|||||||
* @param mixed $reason Rejection reason.
|
* @param mixed $reason Rejection reason.
|
||||||
* @param string|null $description Optional description.
|
* @param string|null $description Optional description.
|
||||||
*/
|
*/
|
||||||
public function __construct($reason, $description = null)
|
public function __construct($reason, string $description = null)
|
||||||
{
|
{
|
||||||
$this->reason = $reason;
|
$this->reason = $reason;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"require": {
|
|
||||||
"php": "^7.4 || ^8.0",
|
|
||||||
"friendsofphp/php-cs-fixer": "3.16.0"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"preferred-install": "dist"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"require": {
|
|
||||||
"php": "^7.4 || ^8.0",
|
|
||||||
"phpstan/phpstan": "1.10.11",
|
|
||||||
"phpstan/phpstan-deprecation-rules": "1.1.3"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"preferred-install": "dist"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"require": {
|
|
||||||
"php": "^7.4 || ^8.0",
|
|
||||||
"psalm/phar": "5.9.0"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"preferred-install": "dist"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,39 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## Unreleased
|
## 2.6.2 - 2023-12-03
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed another issue with the fact that PHP transforms numeric strings in array keys to ints
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Updated links in docs to their canonical versions
|
||||||
|
- Replaced `call_user_func*` with native calls
|
||||||
|
|
||||||
|
## 2.6.1 - 2023-08-27
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Properly handle the fact that PHP transforms numeric strings in array keys to ints
|
||||||
|
|
||||||
|
## 2.6.0 - 2023-08-03
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Updated the mime type map to add some new entries, fix a couple of invalid entries, and remove an invalid entry
|
||||||
|
- Fallback to `application/octet-stream` if we are unable to guess the content type for a multipart file upload
|
||||||
|
|
||||||
|
## 2.5.1 - 2023-08-03
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Corrected mime type for `.acc` files to `audio/aac`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- PHP 8.3 support
|
||||||
|
|
||||||
## 2.5.0 - 2023-04-17
|
## 2.5.0 - 2023-04-17
|
||||||
|
|
||||||
|
|||||||
@@ -8,16 +8,24 @@ functionality like query string parsing.
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
# Installation
|
## Features
|
||||||
|
|
||||||
|
This package comes with a number of stream implementations and stream
|
||||||
|
decorators.
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
composer require guzzlehttp/psr7
|
composer require guzzlehttp/psr7
|
||||||
```
|
```
|
||||||
|
|
||||||
# Stream implementation
|
## Version Guidance
|
||||||
|
|
||||||
This package comes with a number of stream implementations and stream
|
| Version | Status | PHP Version |
|
||||||
decorators.
|
|---------|---------------------|--------------|
|
||||||
|
| 1.x | Security fixes only | >=5.4,<8.1 |
|
||||||
|
| 2.x | Latest | >=7.2.5,<8.4 |
|
||||||
|
|
||||||
|
|
||||||
## AppendStream
|
## AppendStream
|
||||||
@@ -265,7 +273,7 @@ class EofCallbackStream implements StreamInterface
|
|||||||
|
|
||||||
// Invoke the callback when EOF is hit.
|
// Invoke the callback when EOF is hit.
|
||||||
if ($this->eof()) {
|
if ($this->eof()) {
|
||||||
call_user_func($this->callback);
|
($this->callback)();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@@ -629,7 +637,7 @@ this library also provides additional functionality when working with URIs as st
|
|||||||
An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference.
|
An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference.
|
||||||
An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI,
|
An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI,
|
||||||
the base URI. Relative references can be divided into several forms according to
|
the base URI. Relative references can be divided into several forms according to
|
||||||
[RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2):
|
[RFC 3986 Section 4.2](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2):
|
||||||
|
|
||||||
- network-path references, e.g. `//example.com/path`
|
- network-path references, e.g. `//example.com/path`
|
||||||
- absolute-path references, e.g. `/path`
|
- absolute-path references, e.g. `/path`
|
||||||
@@ -688,8 +696,8 @@ or the standard port. This method can be used independently of the implementatio
|
|||||||
`public static function composeComponents($scheme, $authority, $path, $query, $fragment): string`
|
`public static function composeComponents($scheme, $authority, $path, $query, $fragment): string`
|
||||||
|
|
||||||
Composes a URI reference string from its various components according to
|
Composes a URI reference string from its various components according to
|
||||||
[RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called
|
[RFC 3986 Section 5.3](https://datatracker.ietf.org/doc/html/rfc3986#section-5.3). Usually this method does not need
|
||||||
manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`.
|
to be called manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`.
|
||||||
|
|
||||||
### `GuzzleHttp\Psr7\Uri::fromParts`
|
### `GuzzleHttp\Psr7\Uri::fromParts`
|
||||||
|
|
||||||
@@ -733,8 +741,8 @@ Determines if a modified URL should be considered cross-origin with respect to a
|
|||||||
## Reference Resolution
|
## Reference Resolution
|
||||||
|
|
||||||
`GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
|
`GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
|
||||||
to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers
|
to [RFC 3986 Section 5](https://datatracker.ietf.org/doc/html/rfc3986#section-5). This is for example also what web
|
||||||
do when resolving a link in a website based on the current request URI.
|
browsers do when resolving a link in a website based on the current request URI.
|
||||||
|
|
||||||
### `GuzzleHttp\Psr7\UriResolver::resolve`
|
### `GuzzleHttp\Psr7\UriResolver::resolve`
|
||||||
|
|
||||||
@@ -747,7 +755,7 @@ Converts the relative URI into a new URI that is resolved against the base URI.
|
|||||||
`public static function removeDotSegments(string $path): string`
|
`public static function removeDotSegments(string $path): string`
|
||||||
|
|
||||||
Removes dot segments from a path and returns the new path according to
|
Removes dot segments from a path and returns the new path according to
|
||||||
[RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4).
|
[RFC 3986 Section 5.2.4](https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4).
|
||||||
|
|
||||||
### `GuzzleHttp\Psr7\UriResolver::relativize`
|
### `GuzzleHttp\Psr7\UriResolver::relativize`
|
||||||
|
|
||||||
@@ -773,7 +781,7 @@ echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // pr
|
|||||||
## Normalization and Comparison
|
## Normalization and Comparison
|
||||||
|
|
||||||
`GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to
|
`GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to
|
||||||
[RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6).
|
[RFC 3986 Section 6](https://datatracker.ietf.org/doc/html/rfc3986#section-6).
|
||||||
|
|
||||||
### `GuzzleHttp\Psr7\UriNormalizer::normalize`
|
### `GuzzleHttp\Psr7\UriNormalizer::normalize`
|
||||||
|
|
||||||
@@ -855,14 +863,6 @@ This of course assumes they will be resolved against the same base URI. If this
|
|||||||
equivalence or difference of relative references does not mean anything.
|
equivalence or difference of relative references does not mean anything.
|
||||||
|
|
||||||
|
|
||||||
## Version Guidance
|
|
||||||
|
|
||||||
| Version | Status | PHP Version |
|
|
||||||
|---------|----------------|------------------|
|
|
||||||
| 1.x | Security fixes | >=5.4,<8.1 |
|
|
||||||
| 2.x | Latest | ^7.2.5 \|\| ^8.0 |
|
|
||||||
|
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/psr7/security/policy) for more information.
|
If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/psr7/security/policy) for more information.
|
||||||
|
|||||||
@@ -60,9 +60,9 @@
|
|||||||
"psr/http-message-implementation": "1.0"
|
"psr/http-message-implementation": "1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"http-interop/http-factory-tests": "^0.9",
|
"http-interop/http-factory-tests": "^0.9",
|
||||||
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
|
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
||||||
|
|||||||
@@ -40,12 +40,14 @@ final class AppendStream implements StreamInterface
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->rewind();
|
$this->rewind();
|
||||||
|
|
||||||
return $this->getContents();
|
return $this->getContents();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
if (\PHP_VERSION_ID >= 70400) {
|
if (\PHP_VERSION_ID >= 70400) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,9 +140,9 @@ final class AppendStream implements StreamInterface
|
|||||||
|
|
||||||
public function eof(): bool
|
public function eof(): bool
|
||||||
{
|
{
|
||||||
return !$this->streams ||
|
return !$this->streams
|
||||||
($this->current >= count($this->streams) - 1 &&
|
|| ($this->current >= count($this->streams) - 1
|
||||||
$this->streams[$this->current]->eof());
|
&& $this->streams[$this->current]->eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rewind(): void
|
public function rewind(): void
|
||||||
@@ -167,7 +169,7 @@ final class AppendStream implements StreamInterface
|
|||||||
$stream->rewind();
|
$stream->rewind();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw new \RuntimeException('Unable to seek stream '
|
throw new \RuntimeException('Unable to seek stream '
|
||||||
. $i . ' of the AppendStream', 0, $e);
|
.$i.' of the AppendStream', 0, $e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +199,7 @@ final class AppendStream implements StreamInterface
|
|||||||
if ($this->current === $total) {
|
if ($this->current === $total) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$this->current++;
|
++$this->current;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->streams[$this->current]->read($remaining);
|
$result = $this->streams[$this->current]->read($remaining);
|
||||||
@@ -237,8 +239,6 @@ final class AppendStream implements StreamInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null)
|
public function getMetadata($key = null)
|
||||||
|
|||||||
@@ -134,8 +134,6 @@ final class BufferStream implements StreamInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null)
|
public function getMetadata($key = null)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ final class FnStream implements StreamInterface
|
|||||||
private const SLOTS = [
|
private const SLOTS = [
|
||||||
'__toString', 'close', 'detach', 'rewind',
|
'__toString', 'close', 'detach', 'rewind',
|
||||||
'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
|
'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
|
||||||
'isReadable', 'read', 'getContents', 'getMetadata'
|
'isReadable', 'read', 'getContents', 'getMetadata',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var array<string, callable> */
|
/** @var array<string, callable> */
|
||||||
@@ -33,7 +33,7 @@ final class FnStream implements StreamInterface
|
|||||||
|
|
||||||
// Create the functions on the class
|
// Create the functions on the class
|
||||||
foreach ($methods as $name => $fn) {
|
foreach ($methods as $name => $fn) {
|
||||||
$this->{'_fn_' . $name} = $fn;
|
$this->{'_fn_'.$name} = $fn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ final class FnStream implements StreamInterface
|
|||||||
public function __get(string $name): void
|
public function __get(string $name): void
|
||||||
{
|
{
|
||||||
throw new \BadMethodCallException(str_replace('_fn_', '', $name)
|
throw new \BadMethodCallException(str_replace('_fn_', '', $name)
|
||||||
. '() is not implemented in the FnStream');
|
.'() is not implemented in the FnStream');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,7 +54,7 @@ final class FnStream implements StreamInterface
|
|||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if (isset($this->_fn_close)) {
|
if (isset($this->_fn_close)) {
|
||||||
call_user_func($this->_fn_close);
|
($this->_fn_close)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,88 +93,88 @@ final class FnStream implements StreamInterface
|
|||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return call_user_func($this->_fn___toString);
|
/** @var string */
|
||||||
|
return ($this->_fn___toString)();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
if (\PHP_VERSION_ID >= 70400) {
|
if (\PHP_VERSION_ID >= 70400) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void
|
public function close(): void
|
||||||
{
|
{
|
||||||
call_user_func($this->_fn_close);
|
($this->_fn_close)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function detach()
|
public function detach()
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_detach);
|
return ($this->_fn_detach)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSize(): ?int
|
public function getSize(): ?int
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_getSize);
|
return ($this->_fn_getSize)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tell(): int
|
public function tell(): int
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_tell);
|
return ($this->_fn_tell)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function eof(): bool
|
public function eof(): bool
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_eof);
|
return ($this->_fn_eof)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isSeekable(): bool
|
public function isSeekable(): bool
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_isSeekable);
|
return ($this->_fn_isSeekable)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rewind(): void
|
public function rewind(): void
|
||||||
{
|
{
|
||||||
call_user_func($this->_fn_rewind);
|
($this->_fn_rewind)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function seek($offset, $whence = SEEK_SET): void
|
public function seek($offset, $whence = SEEK_SET): void
|
||||||
{
|
{
|
||||||
call_user_func($this->_fn_seek, $offset, $whence);
|
($this->_fn_seek)($offset, $whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isWritable(): bool
|
public function isWritable(): bool
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_isWritable);
|
return ($this->_fn_isWritable)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function write($string): int
|
public function write($string): int
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_write, $string);
|
return ($this->_fn_write)($string);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isReadable(): bool
|
public function isReadable(): bool
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_isReadable);
|
return ($this->_fn_isReadable)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function read($length): string
|
public function read($length): string
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_read, $length);
|
return ($this->_fn_read)($length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getContents(): string
|
public function getContents(): string
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_getContents);
|
return ($this->_fn_getContents)();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null)
|
public function getMetadata($key = null)
|
||||||
{
|
{
|
||||||
return call_user_func($this->_fn_getMetadata, $key);
|
return ($this->_fn_getMetadata)($key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ final class Header
|
|||||||
foreach ((array) $header as $value) {
|
foreach ((array) $header as $value) {
|
||||||
foreach (self::splitList($value) as $val) {
|
foreach (self::splitList($value) as $val) {
|
||||||
$part = [];
|
$part = [];
|
||||||
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
|
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) ?: [] as $kvp) {
|
||||||
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
|
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
|
||||||
$m = $matches[0];
|
$m = $matches[0];
|
||||||
if (isset($m[1])) {
|
if (isset($m[1])) {
|
||||||
@@ -89,7 +89,7 @@ final class Header
|
|||||||
$v = '';
|
$v = '';
|
||||||
$isQuoted = false;
|
$isQuoted = false;
|
||||||
$isEscaped = false;
|
$isEscaped = false;
|
||||||
for ($i = 0, $max = \strlen($value); $i < $max; $i++) {
|
for ($i = 0, $max = \strlen($value); $i < $max; ++$i) {
|
||||||
if ($isEscaped) {
|
if ($isEscaped) {
|
||||||
$v .= $value[$i];
|
$v .= $value[$i];
|
||||||
$isEscaped = false;
|
$isEscaped = false;
|
||||||
|
|||||||
@@ -23,13 +23,7 @@ use Psr\Http\Message\UriInterface;
|
|||||||
* Note: in consuming code it is recommended to require the implemented interfaces
|
* Note: in consuming code it is recommended to require the implemented interfaces
|
||||||
* and inject the instance of this class multiple times.
|
* and inject the instance of this class multiple times.
|
||||||
*/
|
*/
|
||||||
final class HttpFactory implements
|
final class HttpFactory implements RequestFactoryInterface, ResponseFactoryInterface, ServerRequestFactoryInterface, StreamFactoryInterface, UploadedFileFactoryInterface, UriFactoryInterface
|
||||||
RequestFactoryInterface,
|
|
||||||
ResponseFactoryInterface,
|
|
||||||
ServerRequestFactoryInterface,
|
|
||||||
StreamFactoryInterface,
|
|
||||||
UploadedFileFactoryInterface,
|
|
||||||
UriFactoryInterface
|
|
||||||
{
|
{
|
||||||
public function createUploadedFile(
|
public function createUploadedFile(
|
||||||
StreamInterface $stream,
|
StreamInterface $stream,
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ use Psr\Http\Message\StreamInterface;
|
|||||||
* then appends the zlib.inflate filter. The stream is then converted back
|
* then appends the zlib.inflate filter. The stream is then converted back
|
||||||
* to a Guzzle stream resource to be used as a Guzzle stream.
|
* to a Guzzle stream resource to be used as a Guzzle stream.
|
||||||
*
|
*
|
||||||
* @link http://tools.ietf.org/html/rfc1950
|
* @see https://datatracker.ietf.org/doc/html/rfc1950
|
||||||
* @link http://tools.ietf.org/html/rfc1952
|
* @see https://datatracker.ietf.org/doc/html/rfc1952
|
||||||
* @link http://php.net/manual/en/filters.compression.php
|
* @see https://www.php.net/manual/en/filters.compression.php
|
||||||
*/
|
*/
|
||||||
final class InflateStream implements StreamInterface
|
final class InflateStream implements StreamInterface
|
||||||
{
|
{
|
||||||
@@ -28,7 +28,7 @@ final class InflateStream implements StreamInterface
|
|||||||
{
|
{
|
||||||
$resource = StreamWrapper::getResource($stream);
|
$resource = StreamWrapper::getResource($stream);
|
||||||
// Specify window=15+32, so zlib will use header detection to both gzip (with header) and zlib data
|
// Specify window=15+32, so zlib will use header detection to both gzip (with header) and zlib data
|
||||||
// See http://www.zlib.net/manual.html#Advanced definition of inflateInit2
|
// See https://www.zlib.net/manual.html#Advanced definition of inflateInit2
|
||||||
// "Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection"
|
// "Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection"
|
||||||
// Default window size is 15.
|
// Default window size is 15.
|
||||||
stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ, ['window' => 15 + 32]);
|
stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ, ['window' => 15 + 32]);
|
||||||
|
|||||||
@@ -18,31 +18,31 @@ final class Message
|
|||||||
public static function toString(MessageInterface $message): string
|
public static function toString(MessageInterface $message): string
|
||||||
{
|
{
|
||||||
if ($message instanceof RequestInterface) {
|
if ($message instanceof RequestInterface) {
|
||||||
$msg = trim($message->getMethod() . ' '
|
$msg = trim($message->getMethod().' '
|
||||||
. $message->getRequestTarget())
|
.$message->getRequestTarget())
|
||||||
. ' HTTP/' . $message->getProtocolVersion();
|
.' HTTP/'.$message->getProtocolVersion();
|
||||||
if (!$message->hasHeader('host')) {
|
if (!$message->hasHeader('host')) {
|
||||||
$msg .= "\r\nHost: " . $message->getUri()->getHost();
|
$msg .= "\r\nHost: ".$message->getUri()->getHost();
|
||||||
}
|
}
|
||||||
} elseif ($message instanceof ResponseInterface) {
|
} elseif ($message instanceof ResponseInterface) {
|
||||||
$msg = 'HTTP/' . $message->getProtocolVersion() . ' '
|
$msg = 'HTTP/'.$message->getProtocolVersion().' '
|
||||||
. $message->getStatusCode() . ' '
|
.$message->getStatusCode().' '
|
||||||
. $message->getReasonPhrase();
|
.$message->getReasonPhrase();
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException('Unknown message type');
|
throw new \InvalidArgumentException('Unknown message type');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($message->getHeaders() as $name => $values) {
|
foreach ($message->getHeaders() as $name => $values) {
|
||||||
if (strtolower($name) === 'set-cookie') {
|
if (is_string($name) && strtolower($name) === 'set-cookie') {
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$msg .= "\r\n{$name}: " . $value;
|
$msg .= "\r\n{$name}: ".$value;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$msg .= "\r\n{$name}: " . implode(', ', $values);
|
$msg .= "\r\n{$name}: ".implode(', ', $values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "{$msg}\r\n\r\n" . $message->getBody();
|
return "{$msg}\r\n\r\n".$message->getBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -146,7 +146,7 @@ final class Message
|
|||||||
|
|
||||||
// If these aren't the same, then one line didn't match and there's an invalid header.
|
// If these aren't the same, then one line didn't match and there's an invalid header.
|
||||||
if ($count !== substr_count($rawHeaders, "\n")) {
|
if ($count !== substr_count($rawHeaders, "\n")) {
|
||||||
// Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
|
// Folding is deprecated, see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4
|
||||||
if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
|
if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
|
||||||
throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
|
throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
|
||||||
}
|
}
|
||||||
@@ -190,7 +190,7 @@ final class Message
|
|||||||
$host = $headers[reset($hostKey)][0];
|
$host = $headers[reset($hostKey)][0];
|
||||||
$scheme = substr($host, -4) === ':443' ? 'https' : 'http';
|
$scheme = substr($host, -4) === ':443' ? 'https' : 'http';
|
||||||
|
|
||||||
return $scheme . '://' . $host . '/' . ltrim($path, '/');
|
return $scheme.'://'.$host.'/'.ltrim($path, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,11 +227,11 @@ final class Message
|
|||||||
public static function parseResponse(string $message): ResponseInterface
|
public static function parseResponse(string $message): ResponseInterface
|
||||||
{
|
{
|
||||||
$data = self::parseMessage($message);
|
$data = self::parseMessage($message);
|
||||||
// According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
|
// According to https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2
|
||||||
// between status-code and reason-phrase is required. But browsers accept
|
// the space between status-code and reason-phrase is required. But
|
||||||
// responses without space and reason as well.
|
// browsers accept responses without space and reason as well.
|
||||||
if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
|
if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
|
||||||
throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
|
throw new \InvalidArgumentException('Invalid response string: '.$data['start-line']);
|
||||||
}
|
}
|
||||||
$parts = explode(' ', $data['start-line'], 3);
|
$parts = explode(' ', $data['start-line'], 3);
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ use Psr\Http\Message\StreamInterface;
|
|||||||
*/
|
*/
|
||||||
trait MessageTrait
|
trait MessageTrait
|
||||||
{
|
{
|
||||||
/** @var array<string, string[]> Map of all registered headers, as original name => array of values */
|
/** @var string[][] Map of all registered headers, as original name => array of values */
|
||||||
private $headers = [];
|
private $headers = [];
|
||||||
|
|
||||||
/** @var array<string, string> Map of lowercase header name => original name at registration */
|
/** @var string[] Map of lowercase header name => original name at registration */
|
||||||
private $headerNames = [];
|
private $headerNames = [];
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $protocol = '1.1';
|
private $protocol = '1.1';
|
||||||
@@ -37,6 +37,7 @@ trait MessageTrait
|
|||||||
|
|
||||||
$new = clone $this;
|
$new = clone $this;
|
||||||
$new->protocol = $version;
|
$new->protocol = $version;
|
||||||
|
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,11 +136,12 @@ trait MessageTrait
|
|||||||
|
|
||||||
$new = clone $this;
|
$new = clone $this;
|
||||||
$new->stream = $body;
|
$new->stream = $body;
|
||||||
|
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string|int, string|string[]> $headers
|
* @param (string|string[])[] $headers
|
||||||
*/
|
*/
|
||||||
private function setHeaders(array $headers): void
|
private function setHeaders(array $headers): void
|
||||||
{
|
{
|
||||||
@@ -191,7 +193,7 @@ trait MessageTrait
|
|||||||
*
|
*
|
||||||
* @return string[] Trimmed header values
|
* @return string[] Trimmed header values
|
||||||
*
|
*
|
||||||
* @see https://tools.ietf.org/html/rfc7230#section-3.2.4
|
* @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4
|
||||||
*/
|
*/
|
||||||
private function trimAndValidateHeaderValues(array $values): array
|
private function trimAndValidateHeaderValues(array $values): array
|
||||||
{
|
{
|
||||||
@@ -211,7 +213,7 @@ trait MessageTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://tools.ietf.org/html/rfc7230#section-3.2
|
* @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
|
||||||
*
|
*
|
||||||
* @param mixed $header
|
* @param mixed $header
|
||||||
*/
|
*/
|
||||||
@@ -224,7 +226,7 @@ trait MessageTrait
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) {
|
if (!preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) {
|
||||||
throw new \InvalidArgumentException(
|
throw new \InvalidArgumentException(
|
||||||
sprintf('"%s" is not valid header name.', $header)
|
sprintf('"%s" is not valid header name.', $header)
|
||||||
);
|
);
|
||||||
@@ -232,7 +234,7 @@ trait MessageTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://tools.ietf.org/html/rfc7230#section-3.2
|
* @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
|
||||||
*
|
*
|
||||||
* field-value = *( field-content / obs-fold )
|
* field-value = *( field-content / obs-fold )
|
||||||
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
||||||
@@ -254,7 +256,7 @@ trait MessageTrait
|
|||||||
// Clients must not send a request with line folding and a server sending folded headers is
|
// Clients must not send a request with line folding and a server sending folded headers is
|
||||||
// likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
|
// likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
|
||||||
// folding is not likely to break any legitimate use case.
|
// folding is not likely to break any legitimate use case.
|
||||||
if (! preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value)) {
|
if (!preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value)) {
|
||||||
throw new \InvalidArgumentException(
|
throw new \InvalidArgumentException(
|
||||||
sprintf('"%s" is not valid header value.', $value)
|
sprintf('"%s" is not valid header value.', $value)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ final class MimeType
|
|||||||
'7zip' => 'application/x-7z-compressed',
|
'7zip' => 'application/x-7z-compressed',
|
||||||
'123' => 'application/vnd.lotus-1-2-3',
|
'123' => 'application/vnd.lotus-1-2-3',
|
||||||
'aab' => 'application/x-authorware-bin',
|
'aab' => 'application/x-authorware-bin',
|
||||||
'aac' => 'audio/x-acc',
|
'aac' => 'audio/aac',
|
||||||
'aam' => 'application/x-authorware-map',
|
'aam' => 'application/x-authorware-map',
|
||||||
'aas' => 'application/x-authorware-seg',
|
'aas' => 'application/x-authorware-seg',
|
||||||
'abw' => 'application/x-abiword',
|
'abw' => 'application/x-abiword',
|
||||||
@@ -29,6 +29,7 @@ final class MimeType
|
|||||||
'acu' => 'application/vnd.acucobol',
|
'acu' => 'application/vnd.acucobol',
|
||||||
'acutc' => 'application/vnd.acucorp',
|
'acutc' => 'application/vnd.acucorp',
|
||||||
'adp' => 'audio/adpcm',
|
'adp' => 'audio/adpcm',
|
||||||
|
'adts' => 'audio/aac',
|
||||||
'aep' => 'application/vnd.audiograph',
|
'aep' => 'application/vnd.audiograph',
|
||||||
'afm' => 'application/x-font-type1',
|
'afm' => 'application/x-font-type1',
|
||||||
'afp' => 'application/vnd.ibm.modcap',
|
'afp' => 'application/vnd.ibm.modcap',
|
||||||
@@ -41,11 +42,16 @@ final class MimeType
|
|||||||
'air' => 'application/vnd.adobe.air-application-installer-package+zip',
|
'air' => 'application/vnd.adobe.air-application-installer-package+zip',
|
||||||
'ait' => 'application/vnd.dvb.ait',
|
'ait' => 'application/vnd.dvb.ait',
|
||||||
'ami' => 'application/vnd.amiga.ami',
|
'ami' => 'application/vnd.amiga.ami',
|
||||||
|
'aml' => 'application/automationml-aml+xml',
|
||||||
|
'amlx' => 'application/automationml-amlx+zip',
|
||||||
'amr' => 'audio/amr',
|
'amr' => 'audio/amr',
|
||||||
'apk' => 'application/vnd.android.package-archive',
|
'apk' => 'application/vnd.android.package-archive',
|
||||||
'apng' => 'image/apng',
|
'apng' => 'image/apng',
|
||||||
'appcache' => 'text/cache-manifest',
|
'appcache' => 'text/cache-manifest',
|
||||||
|
'appinstaller' => 'application/appinstaller',
|
||||||
'application' => 'application/x-ms-application',
|
'application' => 'application/x-ms-application',
|
||||||
|
'appx' => 'application/appx',
|
||||||
|
'appxbundle' => 'application/appxbundle',
|
||||||
'apr' => 'application/vnd.lotus-approach',
|
'apr' => 'application/vnd.lotus-approach',
|
||||||
'arc' => 'application/x-freearc',
|
'arc' => 'application/x-freearc',
|
||||||
'arj' => 'application/x-arj',
|
'arj' => 'application/x-arj',
|
||||||
@@ -90,6 +96,7 @@ final class MimeType
|
|||||||
'bpk' => 'application/octet-stream',
|
'bpk' => 'application/octet-stream',
|
||||||
'bpmn' => 'application/octet-stream',
|
'bpmn' => 'application/octet-stream',
|
||||||
'bsp' => 'model/vnd.valve.source.compiled-map',
|
'bsp' => 'model/vnd.valve.source.compiled-map',
|
||||||
|
'btf' => 'image/prs.btif',
|
||||||
'btif' => 'image/prs.btif',
|
'btif' => 'image/prs.btif',
|
||||||
'buffer' => 'application/octet-stream',
|
'buffer' => 'application/octet-stream',
|
||||||
'bz' => 'application/x-bzip',
|
'bz' => 'application/x-bzip',
|
||||||
@@ -141,6 +148,7 @@ final class MimeType
|
|||||||
'cjs' => 'application/node',
|
'cjs' => 'application/node',
|
||||||
'cla' => 'application/vnd.claymore',
|
'cla' => 'application/vnd.claymore',
|
||||||
'class' => 'application/octet-stream',
|
'class' => 'application/octet-stream',
|
||||||
|
'cld' => 'model/vnd.cld',
|
||||||
'clkk' => 'application/vnd.crick.clicker.keyboard',
|
'clkk' => 'application/vnd.crick.clicker.keyboard',
|
||||||
'clkp' => 'application/vnd.crick.clicker.palette',
|
'clkp' => 'application/vnd.crick.clicker.palette',
|
||||||
'clkt' => 'application/vnd.crick.clicker.template',
|
'clkt' => 'application/vnd.crick.clicker.template',
|
||||||
@@ -175,6 +183,7 @@ final class MimeType
|
|||||||
'csv' => 'text/csv',
|
'csv' => 'text/csv',
|
||||||
'cu' => 'application/cu-seeme',
|
'cu' => 'application/cu-seeme',
|
||||||
'curl' => 'text/vnd.curl',
|
'curl' => 'text/vnd.curl',
|
||||||
|
'cwl' => 'application/cwl',
|
||||||
'cww' => 'application/prs.cww',
|
'cww' => 'application/prs.cww',
|
||||||
'cxt' => 'application/x-director',
|
'cxt' => 'application/x-director',
|
||||||
'cxx' => 'text/x-c',
|
'cxx' => 'text/x-c',
|
||||||
@@ -197,6 +206,7 @@ final class MimeType
|
|||||||
'der' => 'application/x-x509-ca-cert',
|
'der' => 'application/x-x509-ca-cert',
|
||||||
'dfac' => 'application/vnd.dreamfactory',
|
'dfac' => 'application/vnd.dreamfactory',
|
||||||
'dgc' => 'application/x-dgc-compressed',
|
'dgc' => 'application/x-dgc-compressed',
|
||||||
|
'dib' => 'image/bmp',
|
||||||
'dic' => 'text/x-c',
|
'dic' => 'text/x-c',
|
||||||
'dir' => 'application/x-director',
|
'dir' => 'application/x-director',
|
||||||
'dis' => 'application/vnd.mobius.dis',
|
'dis' => 'application/vnd.mobius.dis',
|
||||||
@@ -219,6 +229,7 @@ final class MimeType
|
|||||||
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||||
'dp' => 'application/vnd.osgi.dp',
|
'dp' => 'application/vnd.osgi.dp',
|
||||||
'dpg' => 'application/vnd.dpgraph',
|
'dpg' => 'application/vnd.dpgraph',
|
||||||
|
'dpx' => 'image/dpx',
|
||||||
'dra' => 'audio/vnd.dra',
|
'dra' => 'audio/vnd.dra',
|
||||||
'drle' => 'image/dicom-rle',
|
'drle' => 'image/dicom-rle',
|
||||||
'dsc' => 'text/prs.lines.tag',
|
'dsc' => 'text/prs.lines.tag',
|
||||||
@@ -255,7 +266,6 @@ final class MimeType
|
|||||||
'eot' => 'application/vnd.ms-fontobject',
|
'eot' => 'application/vnd.ms-fontobject',
|
||||||
'eps' => 'application/postscript',
|
'eps' => 'application/postscript',
|
||||||
'epub' => 'application/epub+zip',
|
'epub' => 'application/epub+zip',
|
||||||
'es' => 'application/ecmascript',
|
|
||||||
'es3' => 'application/vnd.eszigno3+xml',
|
'es3' => 'application/vnd.eszigno3+xml',
|
||||||
'esa' => 'application/vnd.osgi.subsystem',
|
'esa' => 'application/vnd.osgi.subsystem',
|
||||||
'esf' => 'application/vnd.epson.esf',
|
'esf' => 'application/vnd.epson.esf',
|
||||||
@@ -448,6 +458,7 @@ final class MimeType
|
|||||||
'jsonld' => 'application/ld+json',
|
'jsonld' => 'application/ld+json',
|
||||||
'jsonml' => 'application/jsonml+json',
|
'jsonml' => 'application/jsonml+json',
|
||||||
'jsx' => 'text/jsx',
|
'jsx' => 'text/jsx',
|
||||||
|
'jt' => 'model/jt',
|
||||||
'jxr' => 'image/jxr',
|
'jxr' => 'image/jxr',
|
||||||
'jxra' => 'image/jxra',
|
'jxra' => 'image/jxra',
|
||||||
'jxrs' => 'image/jxrs',
|
'jxrs' => 'image/jxrs',
|
||||||
@@ -552,7 +563,7 @@ final class MimeType
|
|||||||
'mime' => 'message/rfc822',
|
'mime' => 'message/rfc822',
|
||||||
'mj2' => 'video/mj2',
|
'mj2' => 'video/mj2',
|
||||||
'mjp2' => 'video/mj2',
|
'mjp2' => 'video/mj2',
|
||||||
'mjs' => 'application/javascript',
|
'mjs' => 'text/javascript',
|
||||||
'mk3d' => 'video/x-matroska',
|
'mk3d' => 'video/x-matroska',
|
||||||
'mka' => 'audio/x-matroska',
|
'mka' => 'audio/x-matroska',
|
||||||
'mkd' => 'text/x-markdown',
|
'mkd' => 'text/x-markdown',
|
||||||
@@ -602,6 +613,8 @@ final class MimeType
|
|||||||
'msg' => 'application/vnd.ms-outlook',
|
'msg' => 'application/vnd.ms-outlook',
|
||||||
'msh' => 'model/mesh',
|
'msh' => 'model/mesh',
|
||||||
'msi' => 'application/x-msdownload',
|
'msi' => 'application/x-msdownload',
|
||||||
|
'msix' => 'application/msix',
|
||||||
|
'msixbundle' => 'application/msixbundle',
|
||||||
'msl' => 'application/vnd.mobius.msl',
|
'msl' => 'application/vnd.mobius.msl',
|
||||||
'msm' => 'application/octet-stream',
|
'msm' => 'application/octet-stream',
|
||||||
'msp' => 'application/octet-stream',
|
'msp' => 'application/octet-stream',
|
||||||
@@ -775,6 +788,8 @@ final class MimeType
|
|||||||
'pvb' => 'application/vnd.3gpp.pic-bw-var',
|
'pvb' => 'application/vnd.3gpp.pic-bw-var',
|
||||||
'pwn' => 'application/vnd.3m.post-it-notes',
|
'pwn' => 'application/vnd.3m.post-it-notes',
|
||||||
'pya' => 'audio/vnd.ms-playready.media.pya',
|
'pya' => 'audio/vnd.ms-playready.media.pya',
|
||||||
|
'pyo' => 'model/vnd.pytha.pyox',
|
||||||
|
'pyox' => 'model/vnd.pytha.pyox',
|
||||||
'pyv' => 'video/vnd.ms-playready.media.pyv',
|
'pyv' => 'video/vnd.ms-playready.media.pyv',
|
||||||
'qam' => 'application/vnd.epson.quickanime',
|
'qam' => 'application/vnd.epson.quickanime',
|
||||||
'qbo' => 'application/vnd.intu.qbo',
|
'qbo' => 'application/vnd.intu.qbo',
|
||||||
@@ -923,10 +938,12 @@ final class MimeType
|
|||||||
'st' => 'application/vnd.sailingtracker.track',
|
'st' => 'application/vnd.sailingtracker.track',
|
||||||
'stc' => 'application/vnd.sun.xml.calc.template',
|
'stc' => 'application/vnd.sun.xml.calc.template',
|
||||||
'std' => 'application/vnd.sun.xml.draw.template',
|
'std' => 'application/vnd.sun.xml.draw.template',
|
||||||
|
'step' => 'application/STEP',
|
||||||
'stf' => 'application/vnd.wt.stf',
|
'stf' => 'application/vnd.wt.stf',
|
||||||
'sti' => 'application/vnd.sun.xml.impress.template',
|
'sti' => 'application/vnd.sun.xml.impress.template',
|
||||||
'stk' => 'application/hyperstudio',
|
'stk' => 'application/hyperstudio',
|
||||||
'stl' => 'model/stl',
|
'stl' => 'model/stl',
|
||||||
|
'stp' => 'application/STEP',
|
||||||
'stpx' => 'model/step+xml',
|
'stpx' => 'model/step+xml',
|
||||||
'stpxz' => 'model/step-xml+zip',
|
'stpxz' => 'model/step-xml+zip',
|
||||||
'stpz' => 'model/step+zip',
|
'stpz' => 'model/step+zip',
|
||||||
@@ -1013,10 +1030,12 @@ final class MimeType
|
|||||||
'ulx' => 'application/x-glulx',
|
'ulx' => 'application/x-glulx',
|
||||||
'umj' => 'application/vnd.umajin',
|
'umj' => 'application/vnd.umajin',
|
||||||
'unityweb' => 'application/vnd.unity',
|
'unityweb' => 'application/vnd.unity',
|
||||||
|
'uo' => 'application/vnd.uoml+xml',
|
||||||
'uoml' => 'application/vnd.uoml+xml',
|
'uoml' => 'application/vnd.uoml+xml',
|
||||||
'uri' => 'text/uri-list',
|
'uri' => 'text/uri-list',
|
||||||
'uris' => 'text/uri-list',
|
'uris' => 'text/uri-list',
|
||||||
'urls' => 'text/uri-list',
|
'urls' => 'text/uri-list',
|
||||||
|
'usda' => 'model/vnd.usda',
|
||||||
'usdz' => 'model/vnd.usdz+zip',
|
'usdz' => 'model/vnd.usdz+zip',
|
||||||
'ustar' => 'application/x-ustar',
|
'ustar' => 'application/x-ustar',
|
||||||
'utz' => 'application/vnd.uiq.theme',
|
'utz' => 'application/vnd.uiq.theme',
|
||||||
@@ -1096,6 +1115,7 @@ final class MimeType
|
|||||||
'webmanifest' => 'application/manifest+json',
|
'webmanifest' => 'application/manifest+json',
|
||||||
'webp' => 'image/webp',
|
'webp' => 'image/webp',
|
||||||
'wg' => 'application/vnd.pmi.widget',
|
'wg' => 'application/vnd.pmi.widget',
|
||||||
|
'wgsl' => 'text/wgsl',
|
||||||
'wgt' => 'application/widget',
|
'wgt' => 'application/widget',
|
||||||
'wif' => 'application/watcherinfo+xml',
|
'wif' => 'application/watcherinfo+xml',
|
||||||
'wks' => 'application/vnd.ms-works',
|
'wks' => 'application/vnd.ms-works',
|
||||||
@@ -1150,9 +1170,10 @@ final class MimeType
|
|||||||
'xel' => 'application/xcap-el+xml',
|
'xel' => 'application/xcap-el+xml',
|
||||||
'xenc' => 'application/xenc+xml',
|
'xenc' => 'application/xenc+xml',
|
||||||
'xer' => 'application/patch-ops-error+xml',
|
'xer' => 'application/patch-ops-error+xml',
|
||||||
'xfdf' => 'application/vnd.adobe.xfdf',
|
'xfdf' => 'application/xfdf',
|
||||||
'xfdl' => 'application/vnd.xfdl',
|
'xfdl' => 'application/vnd.xfdl',
|
||||||
'xht' => 'application/xhtml+xml',
|
'xht' => 'application/xhtml+xml',
|
||||||
|
'xhtm' => 'application/vnd.pwg-xhtml-print+xml',
|
||||||
'xhtml' => 'application/xhtml+xml',
|
'xhtml' => 'application/xhtml+xml',
|
||||||
'xhvml' => 'application/xv+xml',
|
'xhvml' => 'application/xv+xml',
|
||||||
'xif' => 'image/vnd.xiff',
|
'xif' => 'image/vnd.xiff',
|
||||||
@@ -1183,6 +1204,7 @@ final class MimeType
|
|||||||
'xpw' => 'application/vnd.intercon.formnet',
|
'xpw' => 'application/vnd.intercon.formnet',
|
||||||
'xpx' => 'application/vnd.intercon.formnet',
|
'xpx' => 'application/vnd.intercon.formnet',
|
||||||
'xsd' => 'application/xml',
|
'xsd' => 'application/xml',
|
||||||
|
'xsf' => 'application/prs.xsf+xml',
|
||||||
'xsl' => 'application/xml',
|
'xsl' => 'application/xml',
|
||||||
'xslt' => 'application/xslt+xml',
|
'xslt' => 'application/xslt+xml',
|
||||||
'xsm' => 'application/vnd.syncml+xml',
|
'xsm' => 'application/vnd.syncml+xml',
|
||||||
@@ -1218,7 +1240,7 @@ final class MimeType
|
|||||||
/**
|
/**
|
||||||
* Determines the mimetype of a file by looking at its extension.
|
* Determines the mimetype of a file by looking at its extension.
|
||||||
*
|
*
|
||||||
* @link https://raw.githubusercontent.com/jshttp/mime-db/master/db.json
|
* @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json
|
||||||
*/
|
*/
|
||||||
public static function fromFilename(string $filename): ?string
|
public static function fromFilename(string $filename): ?string
|
||||||
{
|
{
|
||||||
@@ -1228,7 +1250,7 @@ final class MimeType
|
|||||||
/**
|
/**
|
||||||
* Maps a file extensions to a mimetype.
|
* Maps a file extensions to a mimetype.
|
||||||
*
|
*
|
||||||
* @link https://raw.githubusercontent.com/jshttp/mime-db/master/db.json
|
* @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json
|
||||||
*/
|
*/
|
||||||
public static function fromExtension(string $extension): ?string
|
public static function fromExtension(string $extension): ?string
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ final class MultipartStream implements StreamInterface
|
|||||||
/**
|
/**
|
||||||
* Get the headers needed before transferring the content of a POST file
|
* Get the headers needed before transferring the content of a POST file
|
||||||
*
|
*
|
||||||
* @param array<string, string> $headers
|
* @param string[] $headers
|
||||||
*/
|
*/
|
||||||
private function getHeaders(array $headers): string
|
private function getHeaders(array $headers): string
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,7 @@ final class MultipartStream implements StreamInterface
|
|||||||
$str .= "{$key}: {$value}\r\n";
|
$str .= "{$key}: {$value}\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n";
|
return "--{$this->boundary}\r\n".trim($str)."\r\n\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,7 +72,7 @@ final class MultipartStream implements StreamInterface
|
|||||||
|
|
||||||
foreach ($elements as $element) {
|
foreach ($elements as $element) {
|
||||||
if (!is_array($element)) {
|
if (!is_array($element)) {
|
||||||
throw new \UnexpectedValueException("An array is expected");
|
throw new \UnexpectedValueException('An array is expected');
|
||||||
}
|
}
|
||||||
$this->addElement($stream, $element);
|
$this->addElement($stream, $element);
|
||||||
}
|
}
|
||||||
@@ -112,10 +112,15 @@ final class MultipartStream implements StreamInterface
|
|||||||
$stream->addStream(Utils::streamFor("\r\n"));
|
$stream->addStream(Utils::streamFor("\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $headers
|
||||||
|
*
|
||||||
|
* @return array{0: StreamInterface, 1: string[]}
|
||||||
|
*/
|
||||||
private function createElement(string $name, StreamInterface $stream, ?string $filename, array $headers): array
|
private function createElement(string $name, StreamInterface $stream, ?string $filename, array $headers): array
|
||||||
{
|
{
|
||||||
// Set a default content-disposition header if one was no provided
|
// Set a default content-disposition header if one was no provided
|
||||||
$disposition = $this->getHeader($headers, 'content-disposition');
|
$disposition = self::getHeader($headers, 'content-disposition');
|
||||||
if (!$disposition) {
|
if (!$disposition) {
|
||||||
$headers['Content-Disposition'] = ($filename === '0' || $filename)
|
$headers['Content-Disposition'] = ($filename === '0' || $filename)
|
||||||
? sprintf(
|
? sprintf(
|
||||||
@@ -127,7 +132,7 @@ final class MultipartStream implements StreamInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set a default content-length header if one was no provided
|
// Set a default content-length header if one was no provided
|
||||||
$length = $this->getHeader($headers, 'content-length');
|
$length = self::getHeader($headers, 'content-length');
|
||||||
if (!$length) {
|
if (!$length) {
|
||||||
if ($length = $stream->getSize()) {
|
if ($length = $stream->getSize()) {
|
||||||
$headers['Content-Length'] = (string) $length;
|
$headers['Content-Length'] = (string) $length;
|
||||||
@@ -135,21 +140,22 @@ final class MultipartStream implements StreamInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set a default Content-Type if one was not supplied
|
// Set a default Content-Type if one was not supplied
|
||||||
$type = $this->getHeader($headers, 'content-type');
|
$type = self::getHeader($headers, 'content-type');
|
||||||
if (!$type && ($filename === '0' || $filename)) {
|
if (!$type && ($filename === '0' || $filename)) {
|
||||||
if ($type = MimeType::fromFilename($filename)) {
|
$headers['Content-Type'] = MimeType::fromFilename($filename) ?? 'application/octet-stream';
|
||||||
$headers['Content-Type'] = $type;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$stream, $headers];
|
return [$stream, $headers];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getHeader(array $headers, string $key)
|
/**
|
||||||
|
* @param string[] $headers
|
||||||
|
*/
|
||||||
|
private static function getHeader(array $headers, string $key): ?string
|
||||||
{
|
{
|
||||||
$lowercaseHeader = strtolower($key);
|
$lowercaseHeader = strtolower($key);
|
||||||
foreach ($headers as $k => $v) {
|
foreach ($headers as $k => $v) {
|
||||||
if (strtolower($k) === $lowercaseHeader) {
|
if (strtolower((string) $k) === $lowercaseHeader) {
|
||||||
return $v;
|
return $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use Psr\Http\Message\StreamInterface;
|
|||||||
*/
|
*/
|
||||||
final class PumpStream implements StreamInterface
|
final class PumpStream implements StreamInterface
|
||||||
{
|
{
|
||||||
/** @var callable|null */
|
/** @var callable(int): (string|false|null)|null */
|
||||||
private $source;
|
private $source;
|
||||||
|
|
||||||
/** @var int|null */
|
/** @var int|null */
|
||||||
@@ -34,7 +34,7 @@ final class PumpStream implements StreamInterface
|
|||||||
private $buffer;
|
private $buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callable(int): (string|null|false) $source Source of the stream data. The callable MAY
|
* @param callable(int): (string|false|null) $source Source of the stream data. The callable MAY
|
||||||
* accept an integer argument used to control the
|
* accept an integer argument used to control the
|
||||||
* amount of data to return. The callable MUST
|
* amount of data to return. The callable MUST
|
||||||
* return a string when called, or false|null on error
|
* return a string when called, or false|null on error
|
||||||
@@ -60,6 +60,7 @@ final class PumpStream implements StreamInterface
|
|||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,8 +150,6 @@ final class PumpStream implements StreamInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null)
|
public function getMetadata($key = null)
|
||||||
@@ -164,11 +163,12 @@ final class PumpStream implements StreamInterface
|
|||||||
|
|
||||||
private function pump(int $length): void
|
private function pump(int $length): void
|
||||||
{
|
{
|
||||||
if ($this->source) {
|
if ($this->source !== null) {
|
||||||
do {
|
do {
|
||||||
$data = call_user_func($this->source, $length);
|
$data = ($this->source)($length);
|
||||||
if ($data === false || $data === null) {
|
if ($data === false || $data === null) {
|
||||||
$this->source = null;
|
$this->source = null;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->buffer->write($data);
|
$this->buffer->write($data);
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ final class Query
|
|||||||
$qs .= $k;
|
$qs .= $k;
|
||||||
$v = is_bool($v) ? (int) $v : $v;
|
$v = is_bool($v) ? (int) $v : $v;
|
||||||
if ($v !== null) {
|
if ($v !== null) {
|
||||||
$qs .= '=' . $encoder((string) $v);
|
$qs .= '='.$encoder((string) $v);
|
||||||
}
|
}
|
||||||
$qs .= '&';
|
$qs .= '&';
|
||||||
} else {
|
} else {
|
||||||
@@ -101,7 +101,7 @@ final class Query
|
|||||||
$qs .= $k;
|
$qs .= $k;
|
||||||
$vv = is_bool($vv) ? (int) $vv : $vv;
|
$vv = is_bool($vv) ? (int) $vv : $vv;
|
||||||
if ($vv !== null) {
|
if ($vv !== null) {
|
||||||
$qs .= '=' . $encoder((string) $vv);
|
$qs .= '='.$encoder((string) $vv);
|
||||||
}
|
}
|
||||||
$qs .= '&';
|
$qs .= '&';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Request implements RequestInterface
|
|||||||
/**
|
/**
|
||||||
* @param string $method HTTP method
|
* @param string $method HTTP method
|
||||||
* @param string|UriInterface $uri URI
|
* @param string|UriInterface $uri URI
|
||||||
* @param array<string, string|string[]> $headers Request headers
|
* @param (string|string[])[] $headers Request headers
|
||||||
* @param string|resource|StreamInterface|null $body Request body
|
* @param string|resource|StreamInterface|null $body Request body
|
||||||
* @param string $version Protocol version
|
* @param string $version Protocol version
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +69,7 @@ class Request implements RequestInterface
|
|||||||
$target = '/';
|
$target = '/';
|
||||||
}
|
}
|
||||||
if ($this->uri->getQuery() != '') {
|
if ($this->uri->getQuery() != '') {
|
||||||
$target .= '?' . $this->uri->getQuery();
|
$target .= '?'.$this->uri->getQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $target;
|
return $target;
|
||||||
@@ -85,6 +85,7 @@ class Request implements RequestInterface
|
|||||||
|
|
||||||
$new = clone $this;
|
$new = clone $this;
|
||||||
$new->requestTarget = $requestTarget;
|
$new->requestTarget = $requestTarget;
|
||||||
|
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ class Request implements RequestInterface
|
|||||||
$this->assertMethod($method);
|
$this->assertMethod($method);
|
||||||
$new = clone $this;
|
$new = clone $this;
|
||||||
$new->method = strtoupper($method);
|
$new->method = strtoupper($method);
|
||||||
|
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ class Request implements RequestInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (($port = $this->uri->getPort()) !== null) {
|
if (($port = $this->uri->getPort()) !== null) {
|
||||||
$host .= ':' . $port;
|
$host .= ':'.$port;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->headerNames['host'])) {
|
if (isset($this->headerNames['host'])) {
|
||||||
@@ -141,7 +143,7 @@ class Request implements RequestInterface
|
|||||||
$this->headerNames['host'] = 'Host';
|
$this->headerNames['host'] = 'Host';
|
||||||
}
|
}
|
||||||
// Ensure Host is the first header.
|
// Ensure Host is the first header.
|
||||||
// See: http://tools.ietf.org/html/rfc7230#section-5.4
|
// See: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
|
||||||
$this->headers = [$header => [$host]] + $this->headers;
|
$this->headers = [$header => [$host]] + $this->headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class Response implements ResponseInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $status Status code
|
* @param int $status Status code
|
||||||
* @param array<string, string|string[]> $headers Response headers
|
* @param (string|string[])[] $headers Response headers
|
||||||
* @param string|resource|StreamInterface|null $body Response body
|
* @param string|resource|StreamInterface|null $body Response body
|
||||||
* @param string $version Protocol version
|
* @param string $version Protocol version
|
||||||
* @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
|
* @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
|
||||||
@@ -138,6 +138,7 @@ class Response implements ResponseInterface
|
|||||||
$reasonPhrase = self::PHRASES[$new->statusCode];
|
$reasonPhrase = self::PHRASES[$new->statusCode];
|
||||||
}
|
}
|
||||||
$new->reasonPhrase = (string) $reasonPhrase;
|
$new->reasonPhrase = (string) $reasonPhrase;
|
||||||
|
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ final class Rfc7230
|
|||||||
*
|
*
|
||||||
* Note: header delimiter (\r\n) is modified to \r?\n to accept line feed only delimiters for BC reasons.
|
* Note: header delimiter (\r\n) is modified to \r?\n to accept line feed only delimiters for BC reasons.
|
||||||
*
|
*
|
||||||
* @link https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15
|
* @see https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15
|
||||||
*
|
*
|
||||||
* @license https://github.com/amphp/http/blob/v1.0.1/LICENSE
|
* @license https://github.com/amphp/http/blob/v1.0.1/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class ServerRequest extends Request implements ServerRequestInterface
|
|||||||
/**
|
/**
|
||||||
* @param string $method HTTP method
|
* @param string $method HTTP method
|
||||||
* @param string|UriInterface $uri URI
|
* @param string|UriInterface $uri URI
|
||||||
* @param array<string, string|string[]> $headers Request headers
|
* @param (string|string[])[] $headers Request headers
|
||||||
* @param string|resource|StreamInterface|null $body Request body
|
* @param string|resource|StreamInterface|null $body Request body
|
||||||
* @param string $version Protocol version
|
* @param string $version Protocol version
|
||||||
* @param array $serverParams Typically the $_SERVER superglobal
|
* @param array $serverParams Typically the $_SERVER superglobal
|
||||||
@@ -144,10 +144,10 @@ class ServerRequest extends Request implements ServerRequestInterface
|
|||||||
foreach (array_keys($files['tmp_name']) as $key) {
|
foreach (array_keys($files['tmp_name']) as $key) {
|
||||||
$spec = [
|
$spec = [
|
||||||
'tmp_name' => $files['tmp_name'][$key],
|
'tmp_name' => $files['tmp_name'][$key],
|
||||||
'size' => $files['size'][$key] ?? null,
|
'size' => $files['size'][$key] ?? null,
|
||||||
'error' => $files['error'][$key] ?? null,
|
'error' => $files['error'][$key] ?? null,
|
||||||
'name' => $files['name'][$key] ?? null,
|
'name' => $files['name'][$key] ?? null,
|
||||||
'type' => $files['type'][$key] ?? null,
|
'type' => $files['type'][$key] ?? null,
|
||||||
];
|
];
|
||||||
$normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
|
$normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ class ServerRequest extends Request implements ServerRequestInterface
|
|||||||
|
|
||||||
private static function extractHostAndPortFromAuthority(string $authority): array
|
private static function extractHostAndPortFromAuthority(string $authority): array
|
||||||
{
|
{
|
||||||
$uri = 'http://' . $authority;
|
$uri = 'http://'.$authority;
|
||||||
$parts = parse_url($uri);
|
$parts = parse_url($uri);
|
||||||
if (false === $parts) {
|
if (false === $parts) {
|
||||||
return [null, null];
|
return [null, null];
|
||||||
@@ -286,8 +286,6 @@ class ServerRequest extends Request implements ServerRequestInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return array|object|null
|
* @return array|object|null
|
||||||
*/
|
*/
|
||||||
public function getParsedBody()
|
public function getParsedBody()
|
||||||
@@ -309,8 +307,6 @@ class ServerRequest extends Request implements ServerRequestInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getAttribute($attribute, $default = null)
|
public function getAttribute($attribute, $default = null)
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ use Psr\Http\Message\StreamInterface;
|
|||||||
class Stream implements StreamInterface
|
class Stream implements StreamInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @see http://php.net/manual/function.fopen.php
|
* @see https://www.php.net/manual/en/function.fopen.php
|
||||||
* @see http://php.net/manual/en/function.gzopen.php
|
* @see https://www.php.net/manual/en/function.gzopen.php
|
||||||
*/
|
*/
|
||||||
private const READABLE_MODES = '/r|a\+|ab\+|w\+|wb\+|x\+|xb\+|c\+|cb\+/';
|
private const READABLE_MODES = '/r|a\+|ab\+|w\+|wb\+|x\+|xb\+|c\+|cb\+/';
|
||||||
private const WRITABLE_MODES = '/a|w|r\+|rb\+|rw|x|c/';
|
private const WRITABLE_MODES = '/a|w|r\+|rb\+|rw|x|c/';
|
||||||
@@ -61,8 +61,8 @@ class Stream implements StreamInterface
|
|||||||
$this->stream = $stream;
|
$this->stream = $stream;
|
||||||
$meta = stream_get_meta_data($this->stream);
|
$meta = stream_get_meta_data($this->stream);
|
||||||
$this->seekable = $meta['seekable'];
|
$this->seekable = $meta['seekable'];
|
||||||
$this->readable = (bool)preg_match(self::READABLE_MODES, $meta['mode']);
|
$this->readable = (bool) preg_match(self::READABLE_MODES, $meta['mode']);
|
||||||
$this->writable = (bool)preg_match(self::WRITABLE_MODES, $meta['mode']);
|
$this->writable = (bool) preg_match(self::WRITABLE_MODES, $meta['mode']);
|
||||||
$this->uri = $this->getMetadata('uri');
|
$this->uri = $this->getMetadata('uri');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,12 +80,14 @@ class Stream implements StreamInterface
|
|||||||
if ($this->isSeekable()) {
|
if ($this->isSeekable()) {
|
||||||
$this->seek(0);
|
$this->seek(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getContents();
|
return $this->getContents();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
if (\PHP_VERSION_ID >= 70400) {
|
if (\PHP_VERSION_ID >= 70400) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,6 +147,7 @@ class Stream implements StreamInterface
|
|||||||
$stats = fstat($this->stream);
|
$stats = fstat($this->stream);
|
||||||
if (is_array($stats) && isset($stats['size'])) {
|
if (is_array($stats) && isset($stats['size'])) {
|
||||||
$this->size = $stats['size'];
|
$this->size = $stats['size'];
|
||||||
|
|
||||||
return $this->size;
|
return $this->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +210,7 @@ class Stream implements StreamInterface
|
|||||||
}
|
}
|
||||||
if (fseek($this->stream, $offset, $whence) === -1) {
|
if (fseek($this->stream, $offset, $whence) === -1) {
|
||||||
throw new \RuntimeException('Unable to seek to stream position '
|
throw new \RuntimeException('Unable to seek to stream position '
|
||||||
. $offset . ' with whence ' . var_export($whence, true));
|
.$offset.' with whence '.var_export($whence, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,8 +264,6 @@ class Stream implements StreamInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null)
|
public function getMetadata($key = null)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ trait StreamDecoratorTrait
|
|||||||
{
|
{
|
||||||
if ($name === 'stream') {
|
if ($name === 'stream') {
|
||||||
$this->stream = $this->createStream();
|
$this->stream = $this->createStream();
|
||||||
|
|
||||||
return $this->stream;
|
return $this->stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,12 +44,14 @@ trait StreamDecoratorTrait
|
|||||||
if ($this->isSeekable()) {
|
if ($this->isSeekable()) {
|
||||||
$this->seek(0);
|
$this->seek(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getContents();
|
return $this->getContents();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
if (\PHP_VERSION_ID >= 70400) {
|
if (\PHP_VERSION_ID >= 70400) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +70,7 @@ trait StreamDecoratorTrait
|
|||||||
{
|
{
|
||||||
/** @var callable $callable */
|
/** @var callable $callable */
|
||||||
$callable = [$this->stream, $method];
|
$callable = [$this->stream, $method];
|
||||||
$result = call_user_func_array($callable, $args);
|
$result = ($callable)(...$args);
|
||||||
|
|
||||||
// Always return the wrapped object if the result is a return $this
|
// Always return the wrapped object if the result is a return $this
|
||||||
return $result === $this->stream ? $this : $result;
|
return $result === $this->stream ? $this : $result;
|
||||||
@@ -79,8 +82,6 @@ trait StreamDecoratorTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
|
||||||
*
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null)
|
public function getMetadata($key = null)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ final class StreamWrapper
|
|||||||
$mode = 'w';
|
$mode = 'w';
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException('The stream must be readable, '
|
throw new \InvalidArgumentException('The stream must be readable, '
|
||||||
. 'writable, or both.');
|
.'writable, or both.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return fopen('guzzle://stream', $mode, false, self::createStreamContext($stream));
|
return fopen('guzzle://stream', $mode, false, self::createStreamContext($stream));
|
||||||
@@ -55,7 +55,7 @@ final class StreamWrapper
|
|||||||
public static function createStreamContext(StreamInterface $stream)
|
public static function createStreamContext(StreamInterface $stream)
|
||||||
{
|
{
|
||||||
return stream_context_create([
|
return stream_context_create([
|
||||||
'guzzle' => ['stream' => $stream]
|
'guzzle' => ['stream' => $stream],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,61 +115,89 @@ final class StreamWrapper
|
|||||||
*/
|
*/
|
||||||
public function stream_cast(int $cast_as)
|
public function stream_cast(int $cast_as)
|
||||||
{
|
{
|
||||||
$stream = clone($this->stream);
|
$stream = clone $this->stream;
|
||||||
$resource = $stream->detach();
|
$resource = $stream->detach();
|
||||||
|
|
||||||
return $resource ?? false;
|
return $resource ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<int|string, int>
|
* @return array{
|
||||||
|
* dev: int,
|
||||||
|
* ino: int,
|
||||||
|
* mode: int,
|
||||||
|
* nlink: int,
|
||||||
|
* uid: int,
|
||||||
|
* gid: int,
|
||||||
|
* rdev: int,
|
||||||
|
* size: int,
|
||||||
|
* atime: int,
|
||||||
|
* mtime: int,
|
||||||
|
* ctime: int,
|
||||||
|
* blksize: int,
|
||||||
|
* blocks: int
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
public function stream_stat(): array
|
public function stream_stat(): array
|
||||||
{
|
{
|
||||||
static $modeMap = [
|
static $modeMap = [
|
||||||
'r' => 33060,
|
'r' => 33060,
|
||||||
'rb' => 33060,
|
'rb' => 33060,
|
||||||
'r+' => 33206,
|
'r+' => 33206,
|
||||||
'w' => 33188,
|
'w' => 33188,
|
||||||
'wb' => 33188
|
'wb' => 33188,
|
||||||
];
|
];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'dev' => 0,
|
'dev' => 0,
|
||||||
'ino' => 0,
|
'ino' => 0,
|
||||||
'mode' => $modeMap[$this->mode],
|
'mode' => $modeMap[$this->mode],
|
||||||
'nlink' => 0,
|
'nlink' => 0,
|
||||||
'uid' => 0,
|
'uid' => 0,
|
||||||
'gid' => 0,
|
'gid' => 0,
|
||||||
'rdev' => 0,
|
'rdev' => 0,
|
||||||
'size' => $this->stream->getSize() ?: 0,
|
'size' => $this->stream->getSize() ?: 0,
|
||||||
'atime' => 0,
|
'atime' => 0,
|
||||||
'mtime' => 0,
|
'mtime' => 0,
|
||||||
'ctime' => 0,
|
'ctime' => 0,
|
||||||
'blksize' => 0,
|
'blksize' => 0,
|
||||||
'blocks' => 0
|
'blocks' => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<int|string, int>
|
* @return array{
|
||||||
|
* dev: int,
|
||||||
|
* ino: int,
|
||||||
|
* mode: int,
|
||||||
|
* nlink: int,
|
||||||
|
* uid: int,
|
||||||
|
* gid: int,
|
||||||
|
* rdev: int,
|
||||||
|
* size: int,
|
||||||
|
* atime: int,
|
||||||
|
* mtime: int,
|
||||||
|
* ctime: int,
|
||||||
|
* blksize: int,
|
||||||
|
* blocks: int
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
public function url_stat(string $path, int $flags): array
|
public function url_stat(string $path, int $flags): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'dev' => 0,
|
'dev' => 0,
|
||||||
'ino' => 0,
|
'ino' => 0,
|
||||||
'mode' => 0,
|
'mode' => 0,
|
||||||
'nlink' => 0,
|
'nlink' => 0,
|
||||||
'uid' => 0,
|
'uid' => 0,
|
||||||
'gid' => 0,
|
'gid' => 0,
|
||||||
'rdev' => 0,
|
'rdev' => 0,
|
||||||
'size' => 0,
|
'size' => 0,
|
||||||
'atime' => 0,
|
'atime' => 0,
|
||||||
'mtime' => 0,
|
'mtime' => 0,
|
||||||
'ctime' => 0,
|
'ctime' => 0,
|
||||||
'blksize' => 0,
|
'blksize' => 0,
|
||||||
'blocks' => 0
|
'blocks' => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class UploadedFile implements UploadedFileInterface
|
|||||||
$this->error = $error;
|
$this->error = $error;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isStringNotEmpty($param): bool
|
private static function isStringNotEmpty($param): bool
|
||||||
{
|
{
|
||||||
return is_string($param) && false === empty($param);
|
return is_string($param) && false === empty($param);
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ class UploadedFile implements UploadedFileInterface
|
|||||||
{
|
{
|
||||||
$this->validateActive();
|
$this->validateActive();
|
||||||
|
|
||||||
if (false === $this->isStringNotEmpty($targetPath)) {
|
if (false === self::isStringNotEmpty($targetPath)) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
'Invalid path provided for move operation; must be a non-empty string'
|
'Invalid path provided for move operation; must be a non-empty string'
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
private const HTTP_DEFAULT_HOST = 'localhost';
|
private const HTTP_DEFAULT_HOST = 'localhost';
|
||||||
|
|
||||||
private const DEFAULT_PORTS = [
|
private const DEFAULT_PORTS = [
|
||||||
'http' => 80,
|
'http' => 80,
|
||||||
'https' => 443,
|
'https' => 443,
|
||||||
'ftp' => 21,
|
'ftp' => 21,
|
||||||
'gopher' => 70,
|
'gopher' => 70,
|
||||||
@@ -41,14 +41,14 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* Unreserved characters for use in a regex.
|
* Unreserved characters for use in a regex.
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-2.3
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.3
|
||||||
*/
|
*/
|
||||||
private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
|
private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sub-delims for use in a regex.
|
* Sub-delims for use in a regex.
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-2.2
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.2
|
||||||
*/
|
*/
|
||||||
private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
|
private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
|
||||||
private const QUERY_SEPARATORS_REPLACEMENT = ['=' => '%3D', '&' => '%26'];
|
private const QUERY_SEPARATORS_REPLACEMENT = ['=' => '%3D', '&' => '%26'];
|
||||||
@@ -87,6 +87,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
$this->applyParts($parts);
|
$this->applyParts($parts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UTF-8 aware \parse_url() replacement.
|
* UTF-8 aware \parse_url() replacement.
|
||||||
*
|
*
|
||||||
@@ -121,7 +122,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
$url
|
$url
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = parse_url($prefix . $encodedUrl);
|
$result = parse_url($prefix.$encodedUrl);
|
||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
return false;
|
return false;
|
||||||
@@ -161,7 +162,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
* `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
|
* `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
|
||||||
* that format).
|
* that format).
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-5.3
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.3
|
||||||
*/
|
*/
|
||||||
public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment): string
|
public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment): string
|
||||||
{
|
{
|
||||||
@@ -169,25 +170,25 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
|
|
||||||
// weak type checks to also accept null until we can add scalar type hints
|
// weak type checks to also accept null until we can add scalar type hints
|
||||||
if ($scheme != '') {
|
if ($scheme != '') {
|
||||||
$uri .= $scheme . ':';
|
$uri .= $scheme.':';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($authority != '' || $scheme === 'file') {
|
if ($authority != '' || $scheme === 'file') {
|
||||||
$uri .= '//' . $authority;
|
$uri .= '//'.$authority;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($authority != '' && $path != '' && $path[0] != '/') {
|
if ($authority != '' && $path != '' && $path[0] != '/') {
|
||||||
$path = '/' . $path;
|
$path = '/'.$path;
|
||||||
}
|
}
|
||||||
|
|
||||||
$uri .= $path;
|
$uri .= $path;
|
||||||
|
|
||||||
if ($query != '') {
|
if ($query != '') {
|
||||||
$uri .= '?' . $query;
|
$uri .= '?'.$query;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($fragment != '') {
|
if ($fragment != '') {
|
||||||
$uri .= '#' . $fragment;
|
$uri .= '#'.$fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $uri;
|
return $uri;
|
||||||
@@ -218,7 +219,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
* @see Uri::isNetworkPathReference
|
* @see Uri::isNetworkPathReference
|
||||||
* @see Uri::isAbsolutePathReference
|
* @see Uri::isAbsolutePathReference
|
||||||
* @see Uri::isRelativePathReference
|
* @see Uri::isRelativePathReference
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-4
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4
|
||||||
*/
|
*/
|
||||||
public static function isAbsolute(UriInterface $uri): bool
|
public static function isAbsolute(UriInterface $uri): bool
|
||||||
{
|
{
|
||||||
@@ -230,7 +231,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
*
|
*
|
||||||
* A relative reference that begins with two slash characters is termed an network-path reference.
|
* A relative reference that begins with two slash characters is termed an network-path reference.
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-4.2
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
|
||||||
*/
|
*/
|
||||||
public static function isNetworkPathReference(UriInterface $uri): bool
|
public static function isNetworkPathReference(UriInterface $uri): bool
|
||||||
{
|
{
|
||||||
@@ -242,7 +243,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
*
|
*
|
||||||
* A relative reference that begins with a single slash character is termed an absolute-path reference.
|
* A relative reference that begins with a single slash character is termed an absolute-path reference.
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-4.2
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
|
||||||
*/
|
*/
|
||||||
public static function isAbsolutePathReference(UriInterface $uri): bool
|
public static function isAbsolutePathReference(UriInterface $uri): bool
|
||||||
{
|
{
|
||||||
@@ -257,7 +258,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
*
|
*
|
||||||
* A relative reference that does not begin with a slash character is termed a relative-path reference.
|
* A relative reference that does not begin with a slash character is termed a relative-path reference.
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-4.2
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
|
||||||
*/
|
*/
|
||||||
public static function isRelativePathReference(UriInterface $uri): bool
|
public static function isRelativePathReference(UriInterface $uri): bool
|
||||||
{
|
{
|
||||||
@@ -276,7 +277,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
* @param UriInterface $uri The URI to check
|
* @param UriInterface $uri The URI to check
|
||||||
* @param UriInterface|null $base An optional base URI to compare against
|
* @param UriInterface|null $base An optional base URI to compare against
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-4.4
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4
|
||||||
*/
|
*/
|
||||||
public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool
|
public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool
|
||||||
{
|
{
|
||||||
@@ -335,8 +336,8 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
*
|
*
|
||||||
* It has the same behavior as withQueryValue() but for an associative array of key => value.
|
* It has the same behavior as withQueryValue() but for an associative array of key => value.
|
||||||
*
|
*
|
||||||
* @param UriInterface $uri URI to use as a base.
|
* @param UriInterface $uri URI to use as a base.
|
||||||
* @param array<string, string|null> $keyValueArray Associative array of key and values
|
* @param (string|null)[] $keyValueArray Associative array of key and values
|
||||||
*/
|
*/
|
||||||
public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface
|
public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface
|
||||||
{
|
{
|
||||||
@@ -352,7 +353,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* Creates a URI from a hash of `parse_url` components.
|
* Creates a URI from a hash of `parse_url` components.
|
||||||
*
|
*
|
||||||
* @link http://php.net/manual/en/function.parse-url.php
|
* @see https://www.php.net/manual/en/function.parse-url.php
|
||||||
*
|
*
|
||||||
* @throws MalformedUriException If the components do not form a valid URI.
|
* @throws MalformedUriException If the components do not form a valid URI.
|
||||||
*/
|
*/
|
||||||
@@ -374,11 +375,11 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
{
|
{
|
||||||
$authority = $this->host;
|
$authority = $this->host;
|
||||||
if ($this->userInfo !== '') {
|
if ($this->userInfo !== '') {
|
||||||
$authority = $this->userInfo . '@' . $authority;
|
$authority = $this->userInfo.'@'.$authority;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->port !== null) {
|
if ($this->port !== null) {
|
||||||
$authority .= ':' . $this->port;
|
$authority .= ':'.$this->port;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $authority;
|
return $authority;
|
||||||
@@ -435,7 +436,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
{
|
{
|
||||||
$info = $this->filterUserInfoComponent($user);
|
$info = $this->filterUserInfoComponent($user);
|
||||||
if ($password !== null) {
|
if ($password !== null) {
|
||||||
$info .= ':' . $this->filterUserInfoComponent($password);
|
$info .= ':'.$this->filterUserInfoComponent($password);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->userInfo === $info) {
|
if ($this->userInfo === $info) {
|
||||||
@@ -563,7 +564,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
? $this->filterQueryAndFragment($parts['fragment'])
|
? $this->filterQueryAndFragment($parts['fragment'])
|
||||||
: '';
|
: '';
|
||||||
if (isset($parts['pass'])) {
|
if (isset($parts['pass'])) {
|
||||||
$this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']);
|
$this->userInfo .= ':'.$this->filterUserInfoComponent($parts['pass']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->removeDefaultPort();
|
$this->removeDefaultPort();
|
||||||
@@ -595,7 +596,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
return preg_replace_callback(
|
return preg_replace_callback(
|
||||||
'/(?:[^%' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ']+|%(?![A-Fa-f0-9]{2}))/',
|
'/(?:[^%'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.']+|%(?![A-Fa-f0-9]{2}))/',
|
||||||
[$this, 'rawurlencodeMatchZero'],
|
[$this, 'rawurlencodeMatchZero'],
|
||||||
$component
|
$component
|
||||||
);
|
);
|
||||||
@@ -627,7 +628,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
$port = (int) $port;
|
$port = (int) $port;
|
||||||
if (0 > $port || 0xffff < $port) {
|
if (0 > $port || 0xFFFF < $port) {
|
||||||
throw new \InvalidArgumentException(
|
throw new \InvalidArgumentException(
|
||||||
sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
|
sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
|
||||||
);
|
);
|
||||||
@@ -637,7 +638,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $keys
|
* @param (string|int)[] $keys
|
||||||
*
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
@@ -649,7 +650,9 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$decodedKeys = array_map('rawurldecode', $keys);
|
$decodedKeys = array_map(function ($k): string {
|
||||||
|
return rawurldecode((string) $k);
|
||||||
|
}, $keys);
|
||||||
|
|
||||||
return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
|
return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
|
||||||
return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true);
|
return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true);
|
||||||
@@ -664,7 +667,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
$queryString = strtr($key, self::QUERY_SEPARATORS_REPLACEMENT);
|
$queryString = strtr($key, self::QUERY_SEPARATORS_REPLACEMENT);
|
||||||
|
|
||||||
if ($value !== null) {
|
if ($value !== null) {
|
||||||
$queryString .= '=' . strtr($value, self::QUERY_SEPARATORS_REPLACEMENT);
|
$queryString .= '='.strtr($value, self::QUERY_SEPARATORS_REPLACEMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $queryString;
|
return $queryString;
|
||||||
@@ -691,7 +694,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
return preg_replace_callback(
|
return preg_replace_callback(
|
||||||
'/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
|
'/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
|
||||||
[$this, 'rawurlencodeMatchZero'],
|
[$this, 'rawurlencodeMatchZero'],
|
||||||
$path
|
$path
|
||||||
);
|
);
|
||||||
@@ -711,7 +714,7 @@ class Uri implements UriInterface, \JsonSerializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
return preg_replace_callback(
|
return preg_replace_callback(
|
||||||
'/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
|
'/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
|
||||||
[$this, 'rawurlencodeMatchZero'],
|
[$this, 'rawurlencodeMatchZero'],
|
||||||
$str
|
$str
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use Psr\Http\Message\UriInterface;
|
|||||||
*
|
*
|
||||||
* @author Tobias Schultze
|
* @author Tobias Schultze
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-6
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-6
|
||||||
*/
|
*/
|
||||||
final class UriNormalizer
|
final class UriNormalizer
|
||||||
{
|
{
|
||||||
@@ -119,7 +119,7 @@ final class UriNormalizer
|
|||||||
* @param UriInterface $uri The URI to normalize
|
* @param UriInterface $uri The URI to normalize
|
||||||
* @param int $flags A bitmask of normalizations to apply, see constants
|
* @param int $flags A bitmask of normalizations to apply, see constants
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-6.2
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-6.2
|
||||||
*/
|
*/
|
||||||
public static function normalize(UriInterface $uri, int $flags = self::PRESERVING_NORMALIZATIONS): UriInterface
|
public static function normalize(UriInterface $uri, int $flags = self::PRESERVING_NORMALIZATIONS): UriInterface
|
||||||
{
|
{
|
||||||
@@ -131,8 +131,8 @@ final class UriNormalizer
|
|||||||
$uri = self::decodeUnreservedCharacters($uri);
|
$uri = self::decodeUnreservedCharacters($uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === '' &&
|
if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === ''
|
||||||
($uri->getScheme() === 'http' || $uri->getScheme() === 'https')
|
&& ($uri->getScheme() === 'http' || $uri->getScheme() === 'https')
|
||||||
) {
|
) {
|
||||||
$uri = $uri->withPath('/');
|
$uri = $uri->withPath('/');
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ final class UriNormalizer
|
|||||||
* @param UriInterface $uri2 An URI to compare
|
* @param UriInterface $uri2 An URI to compare
|
||||||
* @param int $normalizations A bitmask of normalizations to apply, see constants
|
* @param int $normalizations A bitmask of normalizations to apply, see constants
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-6.1
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-6.1
|
||||||
*/
|
*/
|
||||||
public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, int $normalizations = self::PRESERVING_NORMALIZATIONS): bool
|
public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, int $normalizations = self::PRESERVING_NORMALIZATIONS): bool
|
||||||
{
|
{
|
||||||
@@ -185,7 +185,7 @@ final class UriNormalizer
|
|||||||
{
|
{
|
||||||
$regex = '/(?:%[A-Fa-f0-9]{2})++/';
|
$regex = '/(?:%[A-Fa-f0-9]{2})++/';
|
||||||
|
|
||||||
$callback = function (array $match) {
|
$callback = function (array $match): string {
|
||||||
return strtoupper($match[0]);
|
return strtoupper($match[0]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ final class UriNormalizer
|
|||||||
{
|
{
|
||||||
$regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';
|
$regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';
|
||||||
|
|
||||||
$callback = function (array $match) {
|
$callback = function (array $match): string {
|
||||||
return rawurldecode($match[0]);
|
return rawurldecode($match[0]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ use Psr\Http\Message\UriInterface;
|
|||||||
*
|
*
|
||||||
* @author Tobias Schultze
|
* @author Tobias Schultze
|
||||||
*
|
*
|
||||||
* @link https://tools.ietf.org/html/rfc3986#section-5
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-5
|
||||||
*/
|
*/
|
||||||
final class UriResolver
|
final class UriResolver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Removes dot segments from a path and returns the new path.
|
* Removes dot segments from a path and returns the new path.
|
||||||
*
|
*
|
||||||
* @link http://tools.ietf.org/html/rfc3986#section-5.2.4
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4
|
||||||
*/
|
*/
|
||||||
public static function removeDotSegments(string $path): string
|
public static function removeDotSegments(string $path): string
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@ final class UriResolver
|
|||||||
|
|
||||||
if ($path[0] === '/' && (!isset($newPath[0]) || $newPath[0] !== '/')) {
|
if ($path[0] === '/' && (!isset($newPath[0]) || $newPath[0] !== '/')) {
|
||||||
// Re-add the leading slash if necessary for cases like "/.."
|
// Re-add the leading slash if necessary for cases like "/.."
|
||||||
$newPath = '/' . $newPath;
|
$newPath = '/'.$newPath;
|
||||||
} elseif ($newPath !== '' && ($segment === '.' || $segment === '..')) {
|
} elseif ($newPath !== '' && ($segment === '.' || $segment === '..')) {
|
||||||
// Add the trailing slash if necessary
|
// Add the trailing slash if necessary
|
||||||
// If newPath is not empty, then $segment must be set and is the last segment from the foreach
|
// If newPath is not empty, then $segment must be set and is the last segment from the foreach
|
||||||
@@ -53,7 +53,7 @@ final class UriResolver
|
|||||||
/**
|
/**
|
||||||
* Converts the relative URI into a new URI that is resolved against the base URI.
|
* Converts the relative URI into a new URI that is resolved against the base URI.
|
||||||
*
|
*
|
||||||
* @link http://tools.ietf.org/html/rfc3986#section-5.2
|
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.2
|
||||||
*/
|
*/
|
||||||
public static function resolve(UriInterface $base, UriInterface $rel): UriInterface
|
public static function resolve(UriInterface $base, UriInterface $rel): UriInterface
|
||||||
{
|
{
|
||||||
@@ -80,13 +80,13 @@ final class UriResolver
|
|||||||
$targetPath = $rel->getPath();
|
$targetPath = $rel->getPath();
|
||||||
} else {
|
} else {
|
||||||
if ($targetAuthority != '' && $base->getPath() === '') {
|
if ($targetAuthority != '' && $base->getPath() === '') {
|
||||||
$targetPath = '/' . $rel->getPath();
|
$targetPath = '/'.$rel->getPath();
|
||||||
} else {
|
} else {
|
||||||
$lastSlashPos = strrpos($base->getPath(), '/');
|
$lastSlashPos = strrpos($base->getPath(), '/');
|
||||||
if ($lastSlashPos === false) {
|
if ($lastSlashPos === false) {
|
||||||
$targetPath = $rel->getPath();
|
$targetPath = $rel->getPath();
|
||||||
} else {
|
} else {
|
||||||
$targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath();
|
$targetPath = substr($base->getPath(), 0, $lastSlashPos + 1).$rel->getPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,8 +127,8 @@ final class UriResolver
|
|||||||
*/
|
*/
|
||||||
public static function relativize(UriInterface $base, UriInterface $target): UriInterface
|
public static function relativize(UriInterface $base, UriInterface $target): UriInterface
|
||||||
{
|
{
|
||||||
if ($target->getScheme() !== '' &&
|
if ($target->getScheme() !== ''
|
||||||
($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')
|
&& ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')
|
||||||
) {
|
) {
|
||||||
return $target;
|
return $target;
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ final class UriResolver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$targetSegments[] = $targetLastSegment;
|
$targetSegments[] = $targetLastSegment;
|
||||||
$relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments);
|
$relativePath = str_repeat('../', count($sourceSegments)).implode('/', $targetSegments);
|
||||||
|
|
||||||
// A reference to am empty last segment or an empty first sub-segment must be prefixed with "./".
|
// A reference to am empty last segment or an empty first sub-segment must be prefixed with "./".
|
||||||
// This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
|
// This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
|
||||||
|
|||||||
@@ -14,18 +14,18 @@ final class Utils
|
|||||||
/**
|
/**
|
||||||
* Remove the items given by the keys, case insensitively from the data.
|
* Remove the items given by the keys, case insensitively from the data.
|
||||||
*
|
*
|
||||||
* @param string[] $keys
|
* @param (string|int)[] $keys
|
||||||
*/
|
*/
|
||||||
public static function caselessRemove(array $keys, array $data): array
|
public static function caselessRemove(array $keys, array $data): array
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
foreach ($keys as &$key) {
|
foreach ($keys as &$key) {
|
||||||
$key = strtolower($key);
|
$key = strtolower((string) $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($data as $k => $v) {
|
foreach ($data as $k => $v) {
|
||||||
if (!is_string($k) || !in_array(strtolower($k), $keys)) {
|
if (!in_array(strtolower((string) $k), $keys)) {
|
||||||
$result[$k] = $v;
|
$result[$k] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,6 +90,7 @@ final class Utils
|
|||||||
}
|
}
|
||||||
$buffer .= $buf;
|
$buffer .= $buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $buffer;
|
return $buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +175,7 @@ final class Utils
|
|||||||
$standardPorts = ['http' => 80, 'https' => 443];
|
$standardPorts = ['http' => 80, 'https' => 443];
|
||||||
$scheme = $changes['uri']->getScheme();
|
$scheme = $changes['uri']->getScheme();
|
||||||
if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
|
if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
|
||||||
$changes['set_headers']['Host'] .= ':' . $port;
|
$changes['set_headers']['Host'] .= ':'.$port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +231,7 @@ final class Utils
|
|||||||
* @param StreamInterface $stream Stream to read from
|
* @param StreamInterface $stream Stream to read from
|
||||||
* @param int|null $maxLength Maximum buffer length
|
* @param int|null $maxLength Maximum buffer length
|
||||||
*/
|
*/
|
||||||
public static function readLine(StreamInterface $stream, ?int $maxLength = null): string
|
public static function readLine(StreamInterface $stream, int $maxLength = null): string
|
||||||
{
|
{
|
||||||
$buffer = '';
|
$buffer = '';
|
||||||
$size = 0;
|
$size = 0;
|
||||||
@@ -291,6 +292,7 @@ final class Utils
|
|||||||
fwrite($stream, (string) $resource);
|
fwrite($stream, (string) $resource);
|
||||||
fseek($stream, 0);
|
fseek($stream, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Stream($stream, $options);
|
return new Stream($stream, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,6 +310,7 @@ final class Utils
|
|||||||
fseek($stream, 0);
|
fseek($stream, 0);
|
||||||
$resource = $stream;
|
$resource = $stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Stream($resource, $options);
|
return new Stream($resource, $options);
|
||||||
case 'object':
|
case 'object':
|
||||||
/** @var object $resource */
|
/** @var object $resource */
|
||||||
@@ -320,6 +323,7 @@ final class Utils
|
|||||||
}
|
}
|
||||||
$result = $resource->current();
|
$result = $resource->current();
|
||||||
$resource->next();
|
$resource->next();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}, $options);
|
}, $options);
|
||||||
} elseif (method_exists($resource, '__toString')) {
|
} elseif (method_exists($resource, '__toString')) {
|
||||||
@@ -334,7 +338,7 @@ final class Utils
|
|||||||
return new PumpStream($resource, $options);
|
return new PumpStream($resource, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
|
throw new \InvalidArgumentException('Invalid resource type: '.gettype($resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"ignore_php_platform_requirements": {
|
|
||||||
"8.1": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,22 @@
|
|||||||
# laminas-loader
|
# laminas-loader
|
||||||
|
|
||||||
|
> ## 🇷🇺 Русским гражданам
|
||||||
|
>
|
||||||
|
> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм.
|
||||||
|
>
|
||||||
|
> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую.
|
||||||
|
>
|
||||||
|
> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!"
|
||||||
|
>
|
||||||
|
> ## 🇺🇸 To Citizens of Russia
|
||||||
|
>
|
||||||
|
> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism.
|
||||||
|
>
|
||||||
|
> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences.
|
||||||
|
>
|
||||||
|
> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"
|
||||||
|
|
||||||
|
|
||||||
> This package is considered feature-complete, and is now in **security-only** maintenance mode, following a [decision by the Technical Steering Committee](https://github.com/laminas/technical-steering-committee/blob/2b55453e172a1b8c9c4c212be7cf7e7a58b9352c/meetings/minutes/2020-08-03-TSC-Minutes.md#vote-on-components-to-mark-as-security-only).
|
> This package is considered feature-complete, and is now in **security-only** maintenance mode, following a [decision by the Technical Steering Committee](https://github.com/laminas/technical-steering-committee/blob/2b55453e172a1b8c9c4c212be7cf7e7a58b9352c/meetings/minutes/2020-08-03-TSC-Minutes.md#vote-on-components-to-mark-as-security-only).
|
||||||
> If you have a security issue, please [follow our security reporting guidelines](https://getlaminas.org/security/).
|
> If you have a security issue, please [follow our security reporting guidelines](https://getlaminas.org/security/).
|
||||||
> If you wish to take on the role of maintainer, please [nominate yourself](https://github.com/laminas/technical-steering-committee/issues/new?assignees=&labels=Nomination&template=Maintainer_Nomination.md&title=%5BNOMINATION%5D%5BMAINTAINER%5D%3A+%7Bname+of+person+being+nominated%7D)
|
> If you wish to take on the role of maintainer, please [nominate yourself](https://github.com/laminas/technical-steering-committee/issues/new?assignees=&labels=Nomination&template=Maintainer_Nomination.md&title=%5BNOMINATION%5D%5BMAINTAINER%5D%3A+%7Bname+of+person+being+nominated%7D)
|
||||||
|
|||||||
@@ -16,14 +16,17 @@
|
|||||||
"forum": "https://discourse.laminas.dev"
|
"forum": "https://discourse.laminas.dev"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"sort-packages": true
|
"sort-packages": true,
|
||||||
|
"allow-plugins": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.3 || ~8.0.0 || ~8.1.0"
|
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"laminas/laminas-coding-standard": "~2.2.1",
|
"laminas/laminas-coding-standard": "~2.4.0",
|
||||||
"phpunit/phpunit": "^9.3"
|
"phpunit/phpunit": "~9.5.25"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|||||||
714
lib/laminas/laminas-loader/composer.lock
generated
714
lib/laminas/laminas-loader/composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<ruleset
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:noNamespaceSchemaLocation="./vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
|
||||||
|
|
||||||
<arg name="basepath" value="."/>
|
|
||||||
<arg name="cache" value=".phpcs-cache"/>
|
|
||||||
<arg name="colors"/>
|
|
||||||
<arg name="extensions" value="php"/>
|
|
||||||
<arg name="parallel" value="80"/>
|
|
||||||
|
|
||||||
<!-- Show progress -->
|
|
||||||
<arg value="p"/>
|
|
||||||
|
|
||||||
<!-- Paths to check -->
|
|
||||||
<file>src</file>
|
|
||||||
<file>test</file>
|
|
||||||
<exclude-pattern>*/TestAsset/*</exclude-pattern>
|
|
||||||
<exclude-pattern>*/_files/*</exclude-pattern>
|
|
||||||
|
|
||||||
<!-- Include all rules from Laminas Coding Standard -->
|
|
||||||
<rule ref="LaminasCodingStandard"/>
|
|
||||||
|
|
||||||
<rule ref="PSR1.Files.SideEffects">
|
|
||||||
<exclude-pattern>/src/Exception/*</exclude-pattern>
|
|
||||||
<exclude-pattern>/src/SplAutoloader.php</exclude-pattern>
|
|
||||||
<exclude-pattern>/src/AutoloaderFactory.php</exclude-pattern>
|
|
||||||
<exclude-pattern>/src/ClassMapAutoloader.php</exclude-pattern>
|
|
||||||
<exclude-pattern>/src/ModuleAutoloader.php</exclude-pattern>
|
|
||||||
<exclude-pattern>/src/StandardAutoloader.php</exclude-pattern>
|
|
||||||
</rule>
|
|
||||||
</ruleset>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"ignore_php_platform_requirements": {
|
|
||||||
"8.1": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
INTL_EXTENSION=$(php -r 'echo sprintf("php%s.%s-intl",PHP_MAJOR_VERSION,PHP_MINOR_VERSION);')
|
|
||||||
|
|
||||||
echo -e "Removing $INTL_EXTENSION extension:\n"
|
|
||||||
sudo apt remove "$INTL_EXTENSION" -y
|
|
||||||
|
|
||||||
echo -e "Cleaning up:\n"
|
|
||||||
sudo apt autoclean && sudo apt autoremove
|
|
||||||
|
|
||||||
echo -e "Installed extensions:\n"
|
|
||||||
/usr/local/bin/php-extensions-with-version.php
|
|
||||||
@@ -2,6 +2,22 @@
|
|||||||
|
|
||||||
[](https://github.com/laminas/laminas-mail/actions?query=workflow%3A"Continuous+Integration")
|
[](https://github.com/laminas/laminas-mail/actions?query=workflow%3A"Continuous+Integration")
|
||||||
|
|
||||||
|
> ## 🇷🇺 Русским гражданам
|
||||||
|
>
|
||||||
|
> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм.
|
||||||
|
>
|
||||||
|
> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую.
|
||||||
|
>
|
||||||
|
> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!"
|
||||||
|
>
|
||||||
|
> ## 🇺🇸 To Citizens of Russia
|
||||||
|
>
|
||||||
|
> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism.
|
||||||
|
>
|
||||||
|
> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences.
|
||||||
|
>
|
||||||
|
> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"
|
||||||
|
|
||||||
`Laminas\Mail` provides generalized functionality to compose and send both text and
|
`Laminas\Mail` provides generalized functionality to compose and send both text and
|
||||||
MIME-compliant multipart email messages. Mail can be sent with `Laminas\Mail` via
|
MIME-compliant multipart email messages. Mail can be sent with `Laminas\Mail` via
|
||||||
the `Mail\Transport\Sendmail`, `Mail\Transport\Smtp` or the `Mail\Transport\File`
|
the `Mail\Transport\Sendmail`, `Mail\Transport\Smtp` or the `Mail\Transport\File`
|
||||||
|
|||||||
@@ -8,40 +8,38 @@
|
|||||||
"homepage": "https://laminas.dev",
|
"homepage": "https://laminas.dev",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.3 || ~8.0.0 || ~8.1.0",
|
"php": "~8.0.0 || ~8.1.0 || ~8.2.0",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"laminas/laminas-loader": "^2.8",
|
"laminas/laminas-loader": "^2.8.0",
|
||||||
"laminas/laminas-mime": "^2.9.1",
|
"laminas/laminas-mime": "^2.10.0",
|
||||||
"laminas/laminas-stdlib": "^3.6",
|
"laminas/laminas-stdlib": "^3.11.0",
|
||||||
"laminas/laminas-validator": "^2.15",
|
"laminas/laminas-validator": "^2.23.0",
|
||||||
"symfony/polyfill-mbstring": "^1.12.0",
|
"symfony/polyfill-mbstring": "^1.16.0",
|
||||||
"webmozart/assert": "^1.10",
|
"webmozart/assert": "^1.11.0",
|
||||||
"symfony/polyfill-intl-idn": "^1.24.0"
|
"symfony/polyfill-intl-idn": "^1.26.0"
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"zendframework/zend-mail": "*"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"laminas/laminas-coding-standard": "~1.0.0",
|
"laminas/laminas-coding-standard": "~2.5.0",
|
||||||
"laminas/laminas-crypt": "^2.6 || ^3.4",
|
"laminas/laminas-crypt": "^3.9.0",
|
||||||
"laminas/laminas-db": "^2.13.3",
|
"laminas/laminas-db": "^2.16",
|
||||||
"laminas/laminas-servicemanager": "^3.7",
|
"laminas/laminas-servicemanager": "^3.20",
|
||||||
"phpunit/phpunit": "^9.5.5",
|
"phpunit/phpunit": "^9.5.26",
|
||||||
"psalm/plugin-phpunit": "^0.15.1",
|
"psalm/plugin-phpunit": "^0.18.4",
|
||||||
"symfony/process": "^5.3.7",
|
"symfony/process": "^6.0.11",
|
||||||
"vimeo/psalm": "^4.7"
|
"vimeo/psalm": "^5.1"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"laminas/laminas-crypt": "Crammd5 support in SMTP Auth",
|
"laminas/laminas-crypt": "^3.8 Crammd5 support in SMTP Auth",
|
||||||
"laminas/laminas-servicemanager": "^2.7.10 || ^3.3.1 when using SMTP to deliver messages"
|
"laminas/laminas-servicemanager": "^3.16 when using SMTP to deliver messages"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"sort-packages": true,
|
"sort-packages": true,
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
"composer/package-versions-deprecated": true
|
"composer/package-versions-deprecated": true,
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||||
},
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "7.3.99"
|
"php": "8.0.99"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
|
|||||||
1783
lib/laminas/laminas-mail/composer.lock
generated
1783
lib/laminas/laminas-mail/composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -5,10 +5,19 @@ namespace Laminas\Mail;
|
|||||||
use Laminas\Validator\EmailAddress as EmailAddressValidator;
|
use Laminas\Validator\EmailAddress as EmailAddressValidator;
|
||||||
use Laminas\Validator\Hostname;
|
use Laminas\Validator\Hostname;
|
||||||
|
|
||||||
|
use function array_shift;
|
||||||
|
use function is_string;
|
||||||
|
use function preg_match;
|
||||||
|
use function sprintf;
|
||||||
|
use function trim;
|
||||||
|
|
||||||
class Address implements Address\AddressInterface
|
class Address implements Address\AddressInterface
|
||||||
{
|
{
|
||||||
|
/** @var null|string */
|
||||||
protected $comment;
|
protected $comment;
|
||||||
|
/** @var string */
|
||||||
protected $email;
|
protected $email;
|
||||||
|
/** @var null|string */
|
||||||
protected $name;
|
protected $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -149,7 +158,7 @@ class Address implements Address\AddressInterface
|
|||||||
*/
|
*/
|
||||||
private function constructName()
|
private function constructName()
|
||||||
{
|
{
|
||||||
$name = $this->getName();
|
$name = $this->getName();
|
||||||
$comment = $this->getComment();
|
$comment = $this->getComment();
|
||||||
|
|
||||||
if ($comment === null || $comment === '') {
|
if ($comment === null || $comment === '') {
|
||||||
|
|||||||
@@ -4,24 +4,43 @@ namespace Laminas\Mail;
|
|||||||
|
|
||||||
use Countable;
|
use Countable;
|
||||||
use Iterator;
|
use Iterator;
|
||||||
|
use Laminas\Mail\Address\AddressInterface;
|
||||||
use ReturnTypeWillChange;
|
use ReturnTypeWillChange;
|
||||||
|
|
||||||
|
use function count;
|
||||||
|
use function current;
|
||||||
|
use function gettype;
|
||||||
|
use function is_int;
|
||||||
|
use function is_numeric;
|
||||||
|
use function is_object;
|
||||||
|
use function is_string;
|
||||||
|
use function key;
|
||||||
|
use function next;
|
||||||
|
use function reset;
|
||||||
|
use function sprintf;
|
||||||
|
use function strtolower;
|
||||||
|
use function var_export;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implements Iterator<string, AddressInterface>
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
class AddressList implements Countable, Iterator
|
class AddressList implements Countable, Iterator
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* List of Address objects we're managing
|
* List of Address objects we're managing
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<string, AddressInterface>
|
||||||
*/
|
*/
|
||||||
protected $addresses = [];
|
protected $addresses = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an address to the list
|
* Add an address to the list
|
||||||
*
|
*
|
||||||
* @param string|Address\AddressInterface $emailOrAddress
|
* @param string|AddressInterface $emailOrAddress
|
||||||
* @param null|string $name
|
* @param null|string $name
|
||||||
* @throws Exception\InvalidArgumentException
|
* @throws Exception\InvalidArgumentException
|
||||||
* @return AddressList
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function add($emailOrAddress, $name = null)
|
public function add($emailOrAddress, $name = null)
|
||||||
{
|
{
|
||||||
@@ -29,12 +48,12 @@ class AddressList implements Countable, Iterator
|
|||||||
$emailOrAddress = $this->createAddress($emailOrAddress, $name);
|
$emailOrAddress = $this->createAddress($emailOrAddress, $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $emailOrAddress instanceof Address\AddressInterface) {
|
if (! $emailOrAddress instanceof AddressInterface) {
|
||||||
throw new Exception\InvalidArgumentException(sprintf(
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
'%s expects an email address or %s\Address object as its first argument; received "%s"',
|
'%s expects an email address or %s\Address object as its first argument; received "%s"',
|
||||||
__METHOD__,
|
__METHOD__,
|
||||||
__NAMESPACE__,
|
__NAMESPACE__,
|
||||||
(is_object($emailOrAddress) ? get_class($emailOrAddress) : gettype($emailOrAddress))
|
is_object($emailOrAddress) ? $emailOrAddress::class : gettype($emailOrAddress)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +75,7 @@ class AddressList implements Countable, Iterator
|
|||||||
*
|
*
|
||||||
* @param array $addresses
|
* @param array $addresses
|
||||||
* @throws Exception\RuntimeException
|
* @throws Exception\RuntimeException
|
||||||
* @return AddressList
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addMany(array $addresses)
|
public function addMany(array $addresses)
|
||||||
{
|
{
|
||||||
@@ -69,7 +88,7 @@ class AddressList implements Countable, Iterator
|
|||||||
if (! is_string($key)) {
|
if (! is_string($key)) {
|
||||||
throw new Exception\RuntimeException(sprintf(
|
throw new Exception\RuntimeException(sprintf(
|
||||||
'Invalid key type in provided addresses array ("%s")',
|
'Invalid key type in provided addresses array ("%s")',
|
||||||
(is_object($key) ? get_class($key) : var_export($key, 1))
|
is_object($key) ? $key::class : var_export($key, true)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +105,7 @@ class AddressList implements Countable, Iterator
|
|||||||
* @param string $address
|
* @param string $address
|
||||||
* @param null|string $comment Comment associated with the address, if any.
|
* @param null|string $comment Comment associated with the address, if any.
|
||||||
* @throws Exception\InvalidArgumentException
|
* @throws Exception\InvalidArgumentException
|
||||||
* @return AddressList
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addFromString($address, $comment = null)
|
public function addFromString($address, $comment = null)
|
||||||
{
|
{
|
||||||
@@ -97,8 +116,7 @@ class AddressList implements Countable, Iterator
|
|||||||
/**
|
/**
|
||||||
* Merge another address list into this one
|
* Merge another address list into this one
|
||||||
*
|
*
|
||||||
* @param AddressList $addressList
|
* @return $this
|
||||||
* @return AddressList
|
|
||||||
*/
|
*/
|
||||||
public function merge(self $addressList)
|
public function merge(self $addressList)
|
||||||
{
|
{
|
||||||
@@ -124,7 +142,7 @@ class AddressList implements Countable, Iterator
|
|||||||
* Get an address by email
|
* Get an address by email
|
||||||
*
|
*
|
||||||
* @param string $email
|
* @param string $email
|
||||||
* @return bool|Address\AddressInterface
|
* @return false|AddressInterface
|
||||||
*/
|
*/
|
||||||
public function get($email)
|
public function get($email)
|
||||||
{
|
{
|
||||||
@@ -167,9 +185,10 @@ class AddressList implements Countable, Iterator
|
|||||||
/**
|
/**
|
||||||
* Rewind iterator
|
* Rewind iterator
|
||||||
*
|
*
|
||||||
* @return mixed the value of the first addresses element, or false if the addresses is
|
|
||||||
* empty.
|
|
||||||
* @see addresses
|
* @see addresses
|
||||||
|
*
|
||||||
|
* @return false|AddressInterface the value of the first addresses element, or false if the addresses is
|
||||||
|
* empty.
|
||||||
*/
|
*/
|
||||||
#[ReturnTypeWillChange]
|
#[ReturnTypeWillChange]
|
||||||
public function rewind()
|
public function rewind()
|
||||||
@@ -180,7 +199,7 @@ class AddressList implements Countable, Iterator
|
|||||||
/**
|
/**
|
||||||
* Return current item in iteration
|
* Return current item in iteration
|
||||||
*
|
*
|
||||||
* @return Address
|
* @return AddressInterface
|
||||||
*/
|
*/
|
||||||
#[ReturnTypeWillChange]
|
#[ReturnTypeWillChange]
|
||||||
public function current()
|
public function current()
|
||||||
@@ -202,9 +221,10 @@ class AddressList implements Countable, Iterator
|
|||||||
/**
|
/**
|
||||||
* Move to next item
|
* Move to next item
|
||||||
*
|
*
|
||||||
* @return mixed the addresses value in the next place that's pointed to by the
|
|
||||||
* internal array pointer, or false if there are no more elements.
|
|
||||||
* @see addresses
|
* @see addresses
|
||||||
|
*
|
||||||
|
* @return false|AddressInterface the addresses value in the next place that's pointed to by the
|
||||||
|
* internal array pointer, or false if there are no more elements.
|
||||||
*/
|
*/
|
||||||
#[ReturnTypeWillChange]
|
#[ReturnTypeWillChange]
|
||||||
public function next()
|
public function next()
|
||||||
@@ -221,7 +241,7 @@ class AddressList implements Countable, Iterator
|
|||||||
public function valid()
|
public function valid()
|
||||||
{
|
{
|
||||||
$key = key($this->addresses);
|
$key = key($this->addresses);
|
||||||
return ($key !== null && $key !== false);
|
return $key !== null && $key !== false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ class ConfigProvider
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
// Legacy Zend Framework aliases
|
// Legacy Zend Framework aliases
|
||||||
'aliases' => [
|
'aliases' => [
|
||||||
\Zend\Mail\Protocol\SmtpPluginManager::class => Protocol\SmtpPluginManager::class,
|
'Zend\Mail\Protocol\SmtpPluginManager' => Protocol\SmtpPluginManager::class,
|
||||||
],
|
],
|
||||||
'factories' => [
|
'factories' => [
|
||||||
Protocol\SmtpPluginManager::class => Protocol\SmtpPluginManagerFactory::class,
|
Protocol\SmtpPluginManager::class => Protocol\SmtpPluginManagerFactory::class,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace Laminas\Mail\Exception;
|
namespace Laminas\Mail\Exception;
|
||||||
|
|
||||||
interface ExceptionInterface
|
use Throwable;
|
||||||
|
|
||||||
|
interface ExceptionInterface extends Throwable
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,39 @@ use Laminas\Mail\Address;
|
|||||||
use Laminas\Mail\AddressList;
|
use Laminas\Mail\AddressList;
|
||||||
use Laminas\Mail\Headers;
|
use Laminas\Mail\Headers;
|
||||||
use Laminas\Mail\Storage\Exception\RuntimeException;
|
use Laminas\Mail\Storage\Exception\RuntimeException;
|
||||||
use Throwable;
|
|
||||||
|
use function array_filter;
|
||||||
|
use function array_map;
|
||||||
|
use function assert;
|
||||||
|
use function idn_to_ascii;
|
||||||
|
use function implode;
|
||||||
|
use function in_array;
|
||||||
|
use function is_array;
|
||||||
|
use function is_string;
|
||||||
|
use function preg_match;
|
||||||
|
use function preg_match_all;
|
||||||
|
use function preg_replace;
|
||||||
|
use function sprintf;
|
||||||
|
use function str_contains;
|
||||||
|
use function str_replace;
|
||||||
|
use function strtolower;
|
||||||
|
use function trim;
|
||||||
|
|
||||||
|
use const IDNA_DEFAULT;
|
||||||
|
use const IDNA_ERROR_BIDI;
|
||||||
|
use const IDNA_ERROR_CONTEXTJ;
|
||||||
|
use const IDNA_ERROR_DISALLOWED;
|
||||||
|
use const IDNA_ERROR_DOMAIN_NAME_TOO_LONG;
|
||||||
|
use const IDNA_ERROR_EMPTY_LABEL;
|
||||||
|
use const IDNA_ERROR_HYPHEN_3_4;
|
||||||
|
use const IDNA_ERROR_INVALID_ACE_LABEL;
|
||||||
|
use const IDNA_ERROR_LABEL_HAS_DOT;
|
||||||
|
use const IDNA_ERROR_LABEL_TOO_LONG;
|
||||||
|
use const IDNA_ERROR_LEADING_COMBINING_MARK;
|
||||||
|
use const IDNA_ERROR_LEADING_HYPHEN;
|
||||||
|
use const IDNA_ERROR_PUNYCODE;
|
||||||
|
use const IDNA_ERROR_TRAILING_HYPHEN;
|
||||||
|
use const INTL_IDNA_VARIANT_UTS46;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for headers composing address lists (to, from, cc, bcc, reply-to)
|
* Base class for headers composing address lists (to, from, cc, bcc, reply-to)
|
||||||
@@ -14,29 +46,25 @@ use Throwable;
|
|||||||
abstract class AbstractAddressList implements HeaderInterface
|
abstract class AbstractAddressList implements HeaderInterface
|
||||||
{
|
{
|
||||||
private const IDNA_ERROR_MAP = [
|
private const IDNA_ERROR_MAP = [
|
||||||
IDNA_ERROR_EMPTY_LABEL => 'empty label',
|
IDNA_ERROR_EMPTY_LABEL => 'empty label',
|
||||||
IDNA_ERROR_LABEL_TOO_LONG => 'label too long',
|
IDNA_ERROR_LABEL_TOO_LONG => 'label too long',
|
||||||
IDNA_ERROR_DOMAIN_NAME_TOO_LONG => 'domain name too long',
|
IDNA_ERROR_DOMAIN_NAME_TOO_LONG => 'domain name too long',
|
||||||
IDNA_ERROR_LEADING_HYPHEN => 'leading hyphen',
|
IDNA_ERROR_LEADING_HYPHEN => 'leading hyphen',
|
||||||
IDNA_ERROR_TRAILING_HYPHEN => 'trailing hyphen',
|
IDNA_ERROR_TRAILING_HYPHEN => 'trailing hyphen',
|
||||||
IDNA_ERROR_HYPHEN_3_4 => 'consecutive hyphens',
|
IDNA_ERROR_HYPHEN_3_4 => 'consecutive hyphens',
|
||||||
IDNA_ERROR_LEADING_COMBINING_MARK => 'leading combining mark',
|
IDNA_ERROR_LEADING_COMBINING_MARK => 'leading combining mark',
|
||||||
IDNA_ERROR_DISALLOWED => 'disallowed',
|
IDNA_ERROR_DISALLOWED => 'disallowed',
|
||||||
IDNA_ERROR_PUNYCODE => 'invalid punycode encoding',
|
IDNA_ERROR_PUNYCODE => 'invalid punycode encoding',
|
||||||
IDNA_ERROR_LABEL_HAS_DOT => 'has dot',
|
IDNA_ERROR_LABEL_HAS_DOT => 'has dot',
|
||||||
IDNA_ERROR_INVALID_ACE_LABEL => 'label not in ASCII encoding',
|
IDNA_ERROR_INVALID_ACE_LABEL => 'label not in ASCII encoding',
|
||||||
IDNA_ERROR_BIDI => 'fails bidirectional criteria',
|
IDNA_ERROR_BIDI => 'fails bidirectional criteria',
|
||||||
IDNA_ERROR_CONTEXTJ => 'one or more characters fail CONTEXTJ rule',
|
IDNA_ERROR_CONTEXTJ => 'one or more characters fail CONTEXTJ rule',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/** @var AddressList */
|
||||||
* @var AddressList
|
|
||||||
*/
|
|
||||||
protected $addressList;
|
protected $addressList;
|
||||||
|
|
||||||
/**
|
/** @var string Normalized field name */
|
||||||
* @var string Normalized field name
|
|
||||||
*/
|
|
||||||
protected $fieldName;
|
protected $fieldName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,40 +74,42 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
*/
|
*/
|
||||||
protected $encoding = 'ASCII';
|
protected $encoding = 'ASCII';
|
||||||
|
|
||||||
/**
|
/** @var string lower case field name */
|
||||||
* @var string lower case field name
|
|
||||||
*/
|
|
||||||
protected static $type;
|
protected static $type;
|
||||||
|
|
||||||
|
/** @var string[] lower case aliases for the field name */
|
||||||
|
protected static $typeAliases = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $headerLine
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
public static function fromString($headerLine)
|
public static function fromString($headerLine)
|
||||||
{
|
{
|
||||||
list($fieldName, $fieldValue) = GenericHeader::splitHeaderLine($headerLine);
|
[$fieldName, $fieldValue] = GenericHeader::splitHeaderLine($headerLine);
|
||||||
if (strtolower($fieldName) !== static::$type) {
|
if ((strtolower($fieldName) !== static::$type) && ! in_array(strtolower($fieldName), static::$typeAliases)) {
|
||||||
throw new Exception\InvalidArgumentException(sprintf(
|
throw new Exception\InvalidArgumentException(sprintf(
|
||||||
'Invalid header line for "%s" string',
|
'Invalid header line for "%s" string',
|
||||||
__CLASS__
|
self::class
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// split value on ","
|
// split value on ","
|
||||||
$fieldValue = str_replace(Headers::FOLDING, ' ', $fieldValue);
|
$fieldValue = str_replace(Headers::FOLDING, ' ', $fieldValue);
|
||||||
$fieldValue = preg_replace('/[^:]+:([^;]*);/', '$1,', $fieldValue);
|
$fieldValue = preg_replace('/[^:]+:([^;]*);/', '$1,', $fieldValue);
|
||||||
$values = ListParser::parse($fieldValue);
|
$values = ListParser::parse($fieldValue);
|
||||||
|
|
||||||
$wasEncoded = false;
|
$wasEncoded = false;
|
||||||
$addresses = array_map(
|
$addresses = array_map(
|
||||||
function ($value) use (&$wasEncoded) {
|
static function ($value) use (&$wasEncoded): ?Address {
|
||||||
$decodedValue = HeaderWrap::mimeDecodeValue($value);
|
$decodedValue = HeaderWrap::mimeDecodeValue($value);
|
||||||
$wasEncoded = $wasEncoded || ($decodedValue !== $value);
|
$wasEncoded = $wasEncoded || ($decodedValue !== $value);
|
||||||
|
$value = trim($decodedValue);
|
||||||
$value = trim($decodedValue);
|
$comments = self::getComments($value);
|
||||||
|
$value = self::stripComments($value);
|
||||||
$comments = self::getComments($value);
|
$value = preg_replace(
|
||||||
$value = self::stripComments($value);
|
|
||||||
|
|
||||||
$value = preg_replace(
|
|
||||||
[
|
[
|
||||||
'#(?<!\\\)"(.*)(?<!\\\)"#', // quoted-text
|
'#(?<!\\\)"(.*)(?<!\\\)"#', // quoted-text
|
||||||
'#\\\([\x01-\x09\x0b\x0c\x0e-\x7f])#', // quoted-pair
|
'#\\\([\x01-\x09\x0b\x0c\x0e-\x7f])#', // quoted-pair
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -88,12 +118,11 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
],
|
],
|
||||||
$value
|
$value
|
||||||
);
|
);
|
||||||
|
|
||||||
return empty($value) ? null : Address::fromString($value, $comments);
|
return empty($value) ? null : Address::fromString($value, $comments);
|
||||||
},
|
},
|
||||||
$values
|
$values
|
||||||
);
|
);
|
||||||
$addresses = array_filter($addresses);
|
$addresses = array_filter($addresses);
|
||||||
|
|
||||||
$header = new static();
|
$header = new static();
|
||||||
if ($wasEncoded) {
|
if ($wasEncoded) {
|
||||||
@@ -109,6 +138,9 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
return $header;
|
return $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getFieldName()
|
public function getFieldName()
|
||||||
{
|
{
|
||||||
return $this->fieldName;
|
return $this->fieldName;
|
||||||
@@ -116,18 +148,21 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely convert UTF-8 encoded domain name to ASCII
|
* Safely convert UTF-8 encoded domain name to ASCII
|
||||||
|
*
|
||||||
* @param string $domainName the UTF-8 encoded email
|
* @param string $domainName the UTF-8 encoded email
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function idnToAscii($domainName): string
|
protected function idnToAscii($domainName): string
|
||||||
{
|
{
|
||||||
|
/** @psalm-var string|false $ascii */
|
||||||
$ascii = idn_to_ascii($domainName, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $conversionInfo);
|
$ascii = idn_to_ascii($domainName, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $conversionInfo);
|
||||||
if (false !== $ascii) {
|
if (is_string($ascii)) {
|
||||||
return $ascii;
|
return $ascii;
|
||||||
}
|
}
|
||||||
|
|
||||||
$messages = [];
|
$messages = [];
|
||||||
$errors = (int) $conversionInfo['errors'];
|
assert(is_array($conversionInfo));
|
||||||
|
/* @psalm-var array{errors: numeric-string} $conversionInfo */
|
||||||
|
$errors = (int) $conversionInfo['errors'];
|
||||||
|
|
||||||
foreach (self::IDNA_ERROR_MAP as $flag => $message) {
|
foreach (self::IDNA_ERROR_MAP as $flag => $message) {
|
||||||
if (($flag & $errors) === $flag) {
|
if (($flag & $errors) === $flag) {
|
||||||
@@ -141,6 +176,9 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
public function getFieldValue($format = HeaderInterface::FORMAT_RAW)
|
public function getFieldValue($format = HeaderInterface::FORMAT_RAW)
|
||||||
{
|
{
|
||||||
$emails = [];
|
$emails = [];
|
||||||
@@ -151,12 +189,13 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
$name = $address->getName();
|
$name = $address->getName();
|
||||||
|
|
||||||
// quote $name if value requires so
|
// quote $name if value requires so
|
||||||
if (! empty($name) && (false !== strpos($name, ',') || false !== strpos($name, ';'))) {
|
if (! empty($name) && (str_contains($name, ',') || str_contains($name, ';'))) {
|
||||||
// FIXME: what if name contains double quote?
|
// FIXME: what if name contains double quote?
|
||||||
$name = sprintf('"%s"', $name);
|
$name = sprintf('"%s"', $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($format === HeaderInterface::FORMAT_ENCODED
|
if (
|
||||||
|
$format === HeaderInterface::FORMAT_ENCODED
|
||||||
&& 'ASCII' !== $encoding
|
&& 'ASCII' !== $encoding
|
||||||
) {
|
) {
|
||||||
if (! empty($name)) {
|
if (! empty($name)) {
|
||||||
@@ -166,7 +205,7 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
if (preg_match('/^(.+)@([^@]+)$/', $email, $matches)) {
|
if (preg_match('/^(.+)@([^@]+)$/', $email, $matches)) {
|
||||||
$localPart = $matches[1];
|
$localPart = $matches[1];
|
||||||
$hostname = $this->idnToAscii($matches[2]);
|
$hostname = $this->idnToAscii($matches[2]);
|
||||||
$email = sprintf('%s@%s', $localPart, $hostname);
|
$email = sprintf('%s@%s', $localPart, $hostname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,12 +226,19 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
return implode(',' . Headers::FOLDING, $emails);
|
return implode(',' . Headers::FOLDING, $emails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $encoding
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
public function setEncoding($encoding)
|
public function setEncoding($encoding)
|
||||||
{
|
{
|
||||||
$this->encoding = $encoding;
|
$this->encoding = $encoding;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getEncoding()
|
public function getEncoding()
|
||||||
{
|
{
|
||||||
return $this->encoding;
|
return $this->encoding;
|
||||||
@@ -200,8 +246,6 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set address list for this header
|
* Set address list for this header
|
||||||
*
|
|
||||||
* @param AddressList $addressList
|
|
||||||
*/
|
*/
|
||||||
public function setAddressList(AddressList $addressList)
|
public function setAddressList(AddressList $addressList)
|
||||||
{
|
{
|
||||||
@@ -221,11 +265,14 @@ abstract class AbstractAddressList implements HeaderInterface
|
|||||||
return $this->addressList;
|
return $this->addressList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function toString()
|
public function toString()
|
||||||
{
|
{
|
||||||
$name = $this->getFieldName();
|
$name = $this->getFieldName();
|
||||||
$value = $this->getFieldValue(HeaderInterface::FORMAT_ENCODED);
|
$value = $this->getFieldValue(HeaderInterface::FORMAT_ENCODED);
|
||||||
return (empty($value)) ? '' : sprintf('%s: %s', $name, $value);
|
return empty($value) ? '' : sprintf('%s: %s', $name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user