更新细节
This commit is contained in:
parent
2e9f0d17dd
commit
b452fc4ffe
|
@ -50,7 +50,7 @@ class JwtTokenService
|
|||
'avatar' => $userinfo['avatar'],
|
||||
'nickname' => $userinfo['nickname']
|
||||
];
|
||||
$token = JWT::encode($params, env('app.app_key', '123456'), 'HS256');
|
||||
$token = JWT::encode($params, env('app.app_key', ''), 'HS256');
|
||||
$tokenInfo = [
|
||||
'uid' => $id,
|
||||
'phone' => $userinfo['phone'],
|
||||
|
@ -74,9 +74,9 @@ class JwtTokenService
|
|||
{
|
||||
try {
|
||||
JWT::$leeway = 10; //当前时间减去10秒,时间留点余地
|
||||
$decoded = JWT::decode($token, new Key(env('app.app_key', '123456'), 'HS256'));
|
||||
$decoded = JWT::decode($token, new Key(env('app.app_key', ''), 'HS256'));
|
||||
$decodedArray = json_decode(json_encode($decoded), true);
|
||||
$jwtData = $decodedArray['data'];
|
||||
$jwtData = $decodedArray['data'] ?? [];
|
||||
return $jwtData;
|
||||
} catch(\Firebase\JWT\SignatureInvalidException $e) {
|
||||
throw new \think\Exception('签名错误');
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,119 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../mtdowling/jmespath.php/bin/jp.php)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
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()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
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_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||
) {
|
||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php');
|
||||
}
|
||||
}
|
||||
|
||||
return include __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php';
|
|
@ -0,0 +1,5 @@
|
|||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/jp.php
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
|
@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir);
|
|||
|
||||
return array(
|
||||
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
|
||||
'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
|
||||
|
@ -14,7 +15,7 @@ return array(
|
|||
'QcloudApi' => $vendorDir . '/tencentcloud/tencentcloud-sdk-php/src/QcloudApi/QcloudApi.php',
|
||||
'Requests' => $vendorDir . '/rmccue/requests/library/Requests.php',
|
||||
'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
|
||||
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'Stringable' => $vendorDir . '/myclabs/php-enum/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
);
|
||||
|
|
|
@ -8,7 +8,6 @@ $baseDir = dirname($vendorDir);
|
|||
return array(
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
|
||||
|
|
|
@ -9,7 +9,6 @@ class ComposerStaticInitd2a74ba94e266cc4f45a64c54a292d7e
|
|||
public static $files = array (
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
|
||||
|
@ -409,6 +408,7 @@ class ComposerStaticInitd2a74ba94e266cc4f45a64c54a292d7e
|
|||
|
||||
public static $classMap = array (
|
||||
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
|
||||
'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
|
||||
|
@ -416,7 +416,7 @@ class ComposerStaticInitd2a74ba94e266cc4f45a64c54a292d7e
|
|||
'QcloudApi' => __DIR__ . '/..' . '/tencentcloud/tencentcloud-sdk-php/src/QcloudApi/QcloudApi.php',
|
||||
'Requests' => __DIR__ . '/..' . '/rmccue/requests/library/Requests.php',
|
||||
'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
|
||||
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'Stringable' => __DIR__ . '/..' . '/myclabs/php-enum/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@
|
|||
'name' => 'topthink/think',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '14a0416c03cfb5a8966b68410f8b6170e2bc4e30',
|
||||
'reference' => '2e9f0d17ddf52d7c842e0ad6b537cf66ae919fa3',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
@ -47,9 +47,9 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'dragonmantank/cron-expression' => array(
|
||||
'pretty_version' => 'v3.3.1',
|
||||
'version' => '3.3.1.0',
|
||||
'reference' => 'be85b3f05b46c39bbc0d95f6c071ddff669510fa',
|
||||
'pretty_version' => 'v3.3.3',
|
||||
'version' => '3.3.3.0',
|
||||
'reference' => 'adfb1f505deb6384dc8b39804c5065dd3c8c8c0a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../dragonmantank/cron-expression',
|
||||
'aliases' => array(),
|
||||
|
@ -74,54 +74,54 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/command' => array(
|
||||
'pretty_version' => '1.2.3',
|
||||
'version' => '1.2.3.0',
|
||||
'reference' => '3c9383aaf2e39fa8d39375ae37b95b55964aaef4',
|
||||
'pretty_version' => '1.3.0',
|
||||
'version' => '1.3.0.0',
|
||||
'reference' => '3372bcfd79d4b357b6871665bf06155515e8d844',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/command',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/guzzle' => array(
|
||||
'pretty_version' => '7.6.1',
|
||||
'version' => '7.6.1.0',
|
||||
'reference' => '8444a2bacf1960bc6a2b62ed86b8e72e11eebe51',
|
||||
'pretty_version' => '7.8.0',
|
||||
'version' => '7.8.0.0',
|
||||
'reference' => '1110f66a6530a40fe7aea0378fe608ee2b2248f9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/guzzle-services' => array(
|
||||
'pretty_version' => '1.3.2',
|
||||
'version' => '1.3.2.0',
|
||||
'reference' => '4989d902dd4e0411b320e851c46f3c94d652d891',
|
||||
'pretty_version' => '1.4.0',
|
||||
'version' => '1.4.0.0',
|
||||
'reference' => 'f4bb1c205152a56741624b88753732e01a60565c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/guzzle-services',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/promises' => array(
|
||||
'pretty_version' => '1.5.2',
|
||||
'version' => '1.5.2.0',
|
||||
'reference' => 'b94b2807d85443f9719887892882d0329d1e2598',
|
||||
'pretty_version' => '2.0.1',
|
||||
'version' => '2.0.1.0',
|
||||
'reference' => '111166291a0f8130081195ac4556a5587d7f1b5d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/promises',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/psr7' => array(
|
||||
'pretty_version' => '2.5.0',
|
||||
'version' => '2.5.0.0',
|
||||
'reference' => 'b635f279edd83fc275f822a1188157ffea568ff6',
|
||||
'pretty_version' => '2.6.1',
|
||||
'version' => '2.6.1.0',
|
||||
'reference' => 'be45764272e8873c72dbe3d2edcfdfcc3bc9f727',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/uri-template' => array(
|
||||
'pretty_version' => 'v1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => 'b945d74a55a25a949158444f09ec0d3c120d69e2',
|
||||
'pretty_version' => 'v1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => '61bf437fc2197f587f6857d3ff903a24f1731b5d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/uri-template',
|
||||
'aliases' => array(),
|
||||
|
@ -155,9 +155,9 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'monolog/monolog' => array(
|
||||
'pretty_version' => '2.9.0',
|
||||
'version' => '2.9.0.0',
|
||||
'reference' => 'e1c0ae1528ce313a450e5e1ad782765c4a8dd3cb',
|
||||
'pretty_version' => '2.9.2',
|
||||
'version' => '2.9.2.0',
|
||||
'reference' => '437cb3628f4cf6042cc10ae97fc2b8472e48ca1f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../monolog/monolog',
|
||||
'aliases' => array(),
|
||||
|
@ -170,45 +170,45 @@
|
|||
),
|
||||
),
|
||||
'mtdowling/jmespath.php' => array(
|
||||
'pretty_version' => '2.6.1',
|
||||
'version' => '2.6.1.0',
|
||||
'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb',
|
||||
'pretty_version' => '2.7.0',
|
||||
'version' => '2.7.0.0',
|
||||
'reference' => 'bbb69a935c2cbb0c03d7f481a238027430f6440b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../mtdowling/jmespath.php',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'myclabs/php-enum' => array(
|
||||
'pretty_version' => '1.8.3',
|
||||
'version' => '1.8.3.0',
|
||||
'reference' => 'b942d263c641ddb5190929ff840c68f78713e937',
|
||||
'pretty_version' => '1.8.4',
|
||||
'version' => '1.8.4.0',
|
||||
'reference' => 'a867478eae49c9f59ece437ae7f9506bfaa27483',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../myclabs/php-enum',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nyholm/psr7' => array(
|
||||
'pretty_version' => '1.8.0',
|
||||
'version' => '1.8.0.0',
|
||||
'reference' => '3cb4d163b58589e47b35103e8e5e6a6a475b47be',
|
||||
'pretty_version' => '1.8.1',
|
||||
'version' => '1.8.1.0',
|
||||
'reference' => 'aa5fc277a4f5508013d571341ade0c3886d4d00e',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nyholm/psr7',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nyholm/psr7-server' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => 'b846a689844cef114e8079d8c80f0afd96745ae3',
|
||||
'pretty_version' => '1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => '4335801d851f554ca43fa6e7d2602141538854dc',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nyholm/psr7-server',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'overtrue/socialite' => array(
|
||||
'pretty_version' => '4.8.0',
|
||||
'version' => '4.8.0.0',
|
||||
'reference' => 'e55fdf50f8003be8f03a85a7e5a5b7c5716f4c9a',
|
||||
'pretty_version' => '4.9.0',
|
||||
'version' => '4.9.0.0',
|
||||
'reference' => 'dcbb1eed948fe036e6de8cdf0b125f5af1bc73fb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../overtrue/socialite',
|
||||
'aliases' => array(),
|
||||
|
@ -233,9 +233,9 @@
|
|||
),
|
||||
),
|
||||
'phpoffice/phpspreadsheet' => array(
|
||||
'pretty_version' => '1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '6e81cf39bbd93ebc3a4e8150444c41e8aa9b769a',
|
||||
'pretty_version' => '1.29.0',
|
||||
'version' => '1.29.0.0',
|
||||
'reference' => 'fde2ccf55eaef7e86021ff1acce26479160a0fa0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
|
||||
'aliases' => array(),
|
||||
|
@ -266,9 +266,9 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-client' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
|
||||
'pretty_version' => '1.0.3',
|
||||
'version' => '1.0.3.0',
|
||||
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-client',
|
||||
'aliases' => array(),
|
||||
|
@ -341,9 +341,9 @@
|
|||
),
|
||||
),
|
||||
'qcloud/cos-sdk-v5' => array(
|
||||
'pretty_version' => 'v2.6.2',
|
||||
'version' => '2.6.2.0',
|
||||
'reference' => '92a1ee62b85ed4e7bf6836a684df5d7e3158d0ed',
|
||||
'pretty_version' => 'v2.6.8',
|
||||
'version' => '2.6.8.0',
|
||||
'reference' => '6bbce32516a4932aca3e7b8cdcc734eb2b1ec5d4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../qcloud/cos-sdk-v5',
|
||||
'aliases' => array(),
|
||||
|
@ -368,18 +368,18 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'rmccue/requests' => array(
|
||||
'pretty_version' => 'v2.0.5',
|
||||
'version' => '2.0.5.0',
|
||||
'reference' => 'b717f1d2f4ef7992ec0c127747ed8b7e170c2f49',
|
||||
'pretty_version' => 'v2.0.8',
|
||||
'version' => '2.0.8.0',
|
||||
'reference' => 'fae75bcb83d9d00d0e31ee86a472a036f9f91519',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../rmccue/requests',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/cache' => array(
|
||||
'pretty_version' => 'v5.4.23',
|
||||
'version' => '5.4.23.0',
|
||||
'reference' => '983c79ff28612cdfd66d8e44e1a06e5afc87e107',
|
||||
'pretty_version' => 'v5.4.31',
|
||||
'version' => '5.4.31.0',
|
||||
'reference' => '9c0a3a5d0718e51ff81e0605be38fe1acbee9eeb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/cache',
|
||||
'aliases' => array(),
|
||||
|
@ -452,81 +452,81 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-ctype' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-idn' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '639084e360537a19f9ee352433b84ce831f3d2da',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => 'ecaafce9f77234a6a449d29e49267ba10499116d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-normalizer' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '19bd1e4fcd5b91116f14d8533c57831ed00571b6',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '42292d99c55abe617799667f454222c54c60e229',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php72' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '70f4aebd92afca2f865444d30a4d2151c13c3179',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php73' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '9e8ecb5f92152187c4799efd3c96b78ccab18ff9',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => 'fe2f306d1d9d346a7fee353d0d5012e401e984b5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php73',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php81' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '707403074c8ea6e2edaf8794b0157a0bfa52157a',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '7581cd600fa9fd681b797d00b02f068e2f13263b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php81',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/psr-http-message-bridge' => array(
|
||||
'pretty_version' => 'v2.2.0',
|
||||
'version' => '2.2.0.0',
|
||||
'reference' => '28a732c05bbad801304ad5a5c674cf2970508993',
|
||||
'pretty_version' => 'v2.3.1',
|
||||
'version' => '2.3.1.0',
|
||||
'reference' => '581ca6067eb62640de5ff08ee1ba6850a0ee472e',
|
||||
'type' => 'symfony-bridge',
|
||||
'install_path' => __DIR__ . '/../symfony/psr-http-message-bridge',
|
||||
'aliases' => array(),
|
||||
|
@ -569,9 +569,9 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'tencentcloud/tencentcloud-sdk-php' => array(
|
||||
'pretty_version' => '3.0.883',
|
||||
'version' => '3.0.883.0',
|
||||
'reference' => '883c1da92aac9c8a06fe03aff8ae0384217f4938',
|
||||
'pretty_version' => '3.0.1025',
|
||||
'version' => '3.0.1025.0',
|
||||
'reference' => 'eded47c5168cf17d740abe9eeb6ce042adf9cf24',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../tencentcloud/tencentcloud-sdk-php',
|
||||
'aliases' => array(),
|
||||
|
@ -587,9 +587,9 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'topthink/framework' => array(
|
||||
'pretty_version' => 'v6.1.2',
|
||||
'version' => '6.1.2.0',
|
||||
'reference' => '67235be5b919aaaf1de5aed9839f65d8e766aca3',
|
||||
'pretty_version' => 'v6.1.4',
|
||||
'version' => '6.1.4.0',
|
||||
'reference' => '66eb9cf4d627df12911344cd328faf9bb596bf2c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../topthink/framework',
|
||||
'aliases' => array(),
|
||||
|
@ -598,7 +598,7 @@
|
|||
'topthink/think' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '14a0416c03cfb5a8966b68410f8b6170e2bc4e30',
|
||||
'reference' => '2e9f0d17ddf52d7c842e0ad6b537cf66ae919fa3',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
@ -614,9 +614,9 @@
|
|||
'dev_requirement' => false,
|
||||
),
|
||||
'topthink/think-multi-app' => array(
|
||||
'pretty_version' => 'v1.0.16',
|
||||
'version' => '1.0.16.0',
|
||||
'reference' => '07b9183855150455e1f76f8cbe9d77d6d1bc399f',
|
||||
'pretty_version' => 'v1.0.17',
|
||||
'version' => '1.0.17.0',
|
||||
'reference' => '4055a6187296ac16c0bc7bbab4ed5d92f82f791c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../topthink/think-multi-app',
|
||||
'aliases' => array(),
|
||||
|
|
|
@ -1,5 +1,28 @@
|
|||
# Change Log
|
||||
|
||||
## [3.3.3] - 2024-08-10
|
||||
|
||||
### Added
|
||||
- N/A
|
||||
|
||||
### Changed
|
||||
- N/A
|
||||
|
||||
### Fixed
|
||||
- Added fixes for making sure `?` is not passed for both DOM and DOW (#148, thank you https://github.com/LeoVie)
|
||||
- Fixed bug in Next Execution Time by sorting minutes properly (#160, thank you https://github.com/imyip)
|
||||
|
||||
## [3.3.2] - 2022-09-19
|
||||
|
||||
### Added
|
||||
- N/A
|
||||
|
||||
### Changed
|
||||
- Skip some daylight savings time tests for PHP 8.1 daylight savings time weirdness (#146)
|
||||
|
||||
### Fixed
|
||||
- Changed string interpolations to work better with PHP 8.2 (#142)
|
||||
|
||||
## [3.3.1] - 2022-01-18
|
||||
|
||||
### Added
|
||||
|
|
|
@ -84,4 +84,4 @@ Projects that Use cron-expression
|
|||
=================================
|
||||
* Part of the [Laravel Framework](https://github.com/laravel/framework/)
|
||||
* Available as a [Symfony Bundle - setono/cron-expression-bundle](https://github.com/Setono/CronExpressionBundle)
|
||||
* Framework agnostic, PHP-based job scheduler - [Crunz](https://github.com/lavary/crunz)
|
||||
* Framework agnostic, PHP-based job scheduler - [Crunz](https://github.com/crunzphp/crunz)
|
||||
|
|
|
@ -37,5 +37,11 @@
|
|||
"scripts": {
|
||||
"phpstan": "./vendor/bin/phpstan analyze",
|
||||
"test": "phpunit"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"ocramius/package-versions": true,
|
||||
"phpstan/extension-installer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
parameters:
|
||||
checkMissingIterableValueType: false
|
||||
|
||||
ignoreErrors:
|
||||
- '#Call to an undefined method DateTimeInterface::add\(\)#'
|
||||
- '#Call to an undefined method DateTimeInterface::modify\(\)#'
|
||||
- '#Call to an undefined method DateTimeInterface::setDate\(\)#'
|
||||
- '#Call to an undefined method DateTimeInterface::setTime\(\)#'
|
||||
- '#Call to an undefined method DateTimeInterface::setTimezone\(\)#'
|
||||
- '#Call to an undefined method DateTimeInterface::sub\(\)#'
|
||||
|
||||
level: max
|
||||
|
||||
paths:
|
||||
- src/
|
|
@ -177,6 +177,7 @@ class CronExpression
|
|||
*
|
||||
* @param string $expression CRON expression (e.g. '8 * * * *')
|
||||
* @param null|FieldFactoryInterface $fieldFactory Factory to create cron fields
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $expression, FieldFactoryInterface $fieldFactory = null)
|
||||
{
|
||||
|
@ -201,13 +202,22 @@ class CronExpression
|
|||
$split = preg_split('/\s/', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
Assert::isArray($split);
|
||||
|
||||
$this->cronParts = $split;
|
||||
if (\count($this->cronParts) < 5) {
|
||||
$notEnoughParts = \count($split) < 5;
|
||||
|
||||
$questionMarkInInvalidPart = array_key_exists(0, $split) && $split[0] === '?'
|
||||
|| array_key_exists(1, $split) && $split[1] === '?'
|
||||
|| array_key_exists(3, $split) && $split[3] === '?';
|
||||
|
||||
$tooManyQuestionMarks = array_key_exists(2, $split) && $split[2] === '?'
|
||||
&& array_key_exists(4, $split) && $split[4] === '?';
|
||||
|
||||
if ($notEnoughParts || $questionMarkInInvalidPart || $tooManyQuestionMarks) {
|
||||
throw new InvalidArgumentException(
|
||||
$value . ' is not a valid CRON expression'
|
||||
);
|
||||
}
|
||||
|
||||
$this->cronParts = $split;
|
||||
foreach ($this->cronParts as $position => $part) {
|
||||
$this->setPart($position, $part);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class DayOfMonthField extends AbstractField
|
|||
private static function getNearestWeekday(int $currentYear, int $currentMonth, int $targetDay): ?DateTime
|
||||
{
|
||||
$tday = str_pad((string) $targetDay, 2, '0', STR_PAD_LEFT);
|
||||
$target = DateTime::createFromFormat('Y-m-d', "${currentYear}-${currentMonth}-${tday}");
|
||||
$target = DateTime::createFromFormat('Y-m-d', "{$currentYear}-{$currentMonth}-{$tday}");
|
||||
|
||||
if ($target === false) {
|
||||
return null;
|
||||
|
@ -94,9 +94,9 @@ class DayOfMonthField extends AbstractField
|
|||
}
|
||||
|
||||
// Check to see if this is the nearest weekday to a particular value
|
||||
if (strpos($value, 'W')) {
|
||||
if ($wPosition = strpos($value, 'W')) {
|
||||
// Parse the target day
|
||||
$targetDay = (int) substr($value, 0, strpos($value, 'W'));
|
||||
$targetDay = (int) substr($value, 0, $wPosition);
|
||||
// Find out if the current day is the nearest day of the week
|
||||
$nearest = self::getNearestWeekday(
|
||||
(int) $date->format('Y'),
|
||||
|
|
|
@ -68,8 +68,8 @@ class DayOfWeekField extends AbstractField
|
|||
$lastDayOfMonth = (int) $date->format('t');
|
||||
|
||||
// Find out if this is the last specific weekday of the month
|
||||
if (strpos($value, 'L')) {
|
||||
$weekday = $this->convertLiterals(substr($value, 0, strpos($value, 'L')));
|
||||
if ($lPosition = strpos($value, 'L')) {
|
||||
$weekday = $this->convertLiterals(substr($value, 0, $lPosition));
|
||||
$weekday %= 7;
|
||||
|
||||
$daysInMonth = (int) $date->format('t');
|
||||
|
|
|
@ -25,7 +25,7 @@ class HoursField extends AbstractField
|
|||
/**
|
||||
* @var array|null Transitions returned by DateTimeZone::getTransitions()
|
||||
*/
|
||||
protected $transitions = null;
|
||||
protected $transitions = [];
|
||||
|
||||
/**
|
||||
* @var int|null Timestamp of the start of the transitions range
|
||||
|
@ -92,7 +92,7 @@ class HoursField extends AbstractField
|
|||
$dtLimitStart->getTimestamp(),
|
||||
$dtLimitEnd->getTimestamp()
|
||||
);
|
||||
if ($this->transitions === false) {
|
||||
if (empty($this->transitions)) {
|
||||
return null;
|
||||
}
|
||||
$this->transitionsStart = $dtLimitStart->getTimestamp();
|
||||
|
|
|
@ -49,6 +49,7 @@ class MinutesField extends AbstractField
|
|||
$current_minute = (int) $date->format('i');
|
||||
|
||||
$parts = false !== strpos($parts, ',') ? explode(',', $parts) : [$parts];
|
||||
sort($parts);
|
||||
$minutes = [];
|
||||
foreach ($parts as $part) {
|
||||
$minutes = array_merge($minutes, $this->getRangeForExpression($part, 59));
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
$config = (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PHP71Migration:risky' => true,
|
||||
'@PHPUnit75Migration:risky' => true,
|
||||
'@Symfony' => true,
|
||||
'declare_strict_types' => false,
|
||||
'global_namespace_import' => false,
|
||||
'phpdoc_annotation_without_dot' => false,
|
||||
'phpdoc_summary' => false,
|
||||
'phpdoc_to_comment' => false,
|
||||
'single_line_throw' => false,
|
||||
'void_return' => false,
|
||||
'yoda_style' => false,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__.'/src')
|
||||
->in(__DIR__.'/tests')
|
||||
->name('*.php')
|
||||
)
|
||||
;
|
||||
|
||||
return $config;
|
|
@ -27,19 +27,29 @@
|
|||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"guzzlehttp/guzzle": "^7.5.1",
|
||||
"guzzlehttp/promises": "^1.5.2",
|
||||
"guzzlehttp/promises": "^1.5.3 || ^2.0",
|
||||
"guzzlehttp/psr7": "^1.9.1 || ^2.4.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.19"
|
||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
||||
"phpunit/phpunit": "^8.5.19 || ^9.5.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Command\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"bamarni/composer-bin-plugin": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command;
|
||||
|
||||
use GuzzleHttp\HandlerStack;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command;
|
||||
|
||||
use GuzzleHttp\HandlerStack;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Exception;
|
||||
|
||||
/**
|
||||
* Exception encountered when a 4xx level response is received for a request
|
||||
*/
|
||||
class CommandClientException extends CommandException {}
|
||||
class CommandClientException extends CommandException
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Exception;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
@ -22,8 +23,6 @@ class CommandException extends \RuntimeException implements GuzzleException
|
|||
private $response;
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param \Exception $prev
|
||||
* @return CommandException
|
||||
*/
|
||||
public static function fromPrevious(CommandInterface $command, \Exception $prev)
|
||||
|
@ -50,18 +49,17 @@ class CommandException extends \RuntimeException implements GuzzleException
|
|||
}
|
||||
|
||||
// Prepare the message.
|
||||
$message = 'There was an error executing the ' . $command->getName()
|
||||
. ' command: ' . $prev->getMessage();
|
||||
$message = 'There was an error executing the '.$command->getName()
|
||||
.' command: '.$prev->getMessage();
|
||||
|
||||
// Create the exception.
|
||||
return new $class($message, $command, $prev, $request, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message Exception message
|
||||
* @param CommandInterface $command
|
||||
* @param \Exception $previous Previous exception (if any)
|
||||
* @param RequestInterface $request
|
||||
* @param string $message Exception message
|
||||
* @param \Exception $previous Previous exception (if any)
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Exception;
|
||||
|
||||
/**
|
||||
* Exception encountered when a 5xx level response is received for a request
|
||||
*/
|
||||
class CommandServerException extends CommandException {}
|
||||
class CommandServerException extends CommandException
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command;
|
||||
|
||||
/**
|
||||
|
@ -8,9 +9,6 @@ class Result implements ResultInterface
|
|||
{
|
||||
use HasDataTrait;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
$this->data = $data;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command;
|
||||
|
||||
use GuzzleHttp\ClientInterface as HttpClient;
|
||||
|
@ -20,7 +21,7 @@ class ServiceClient implements ServiceClientInterface
|
|||
|
||||
/** @var HandlerStack */
|
||||
private $handlerStack;
|
||||
|
||||
|
||||
/** @var callable */
|
||||
private $commandToRequestTransformer;
|
||||
|
||||
|
@ -30,19 +31,19 @@ class ServiceClient implements ServiceClientInterface
|
|||
/**
|
||||
* Instantiates a Guzzle ServiceClient for making requests to a web service.
|
||||
*
|
||||
* @param HttpClient $httpClient A fully-configured Guzzle HTTP client that
|
||||
* will be used to perform the underlying HTTP requests.
|
||||
* @param callable $commandToRequestTransformer A callable that transforms
|
||||
* a Command into a Request. The function should accept a
|
||||
* `GuzzleHttp\Command\CommandInterface` object and return a
|
||||
* `Psr\Http\Message\RequestInterface` object.
|
||||
* @param callable $responseToResultTransformer A callable that transforms a
|
||||
* Response into a Result. The function should accept a
|
||||
* `Psr\Http\Message\ResponseInterface` object (and optionally a
|
||||
* `Psr\Http\Message\RequestInterface` object) and return a
|
||||
* `GuzzleHttp\Command\ResultInterface` object.
|
||||
* @param HandlerStack $commandHandlerStack A Guzzle HandlerStack, which can
|
||||
* be used to add command-level middleware to the service client.
|
||||
* @param HttpClient $httpClient A fully-configured Guzzle HTTP client that
|
||||
* will be used to perform the underlying HTTP requests.
|
||||
* @param callable $commandToRequestTransformer A callable that transforms
|
||||
* a Command into a Request. The function should accept a
|
||||
* `GuzzleHttp\Command\CommandInterface` object and return a
|
||||
* `Psr\Http\Message\RequestInterface` object.
|
||||
* @param callable $responseToResultTransformer A callable that transforms a
|
||||
* Response into a Result. The function should accept a
|
||||
* `Psr\Http\Message\ResponseInterface` object (and optionally a
|
||||
* `Psr\Http\Message\RequestInterface` object) and return a
|
||||
* `GuzzleHttp\Command\ResultInterface` object.
|
||||
* @param HandlerStack $commandHandlerStack A Guzzle HandlerStack, which can
|
||||
* be used to add command-level middleware to the service client.
|
||||
*/
|
||||
public function __construct(
|
||||
HttpClient $httpClient,
|
||||
|
@ -106,6 +107,7 @@ class ServiceClient implements ServiceClientInterface
|
|||
return $this->executeAllAsync($commands, $options)
|
||||
->then(function () use (&$results) {
|
||||
ksort($results);
|
||||
|
||||
return $results;
|
||||
})
|
||||
->wait();
|
||||
|
@ -119,12 +121,12 @@ class ServiceClient implements ServiceClientInterface
|
|||
}
|
||||
|
||||
// Convert the iterator of commands to a generator of promises.
|
||||
$commands = Promise\iter_for($commands);
|
||||
$commands = Promise\Create::iterFor($commands);
|
||||
$promises = function () use ($commands) {
|
||||
foreach ($commands as $key => $command) {
|
||||
if (!$command instanceof CommandInterface) {
|
||||
throw new \InvalidArgumentException('The iterator must '
|
||||
. 'yield instances of ' . CommandInterface::class);
|
||||
.'yield instances of '.CommandInterface::class);
|
||||
}
|
||||
yield $key => $this->executeAsync($command);
|
||||
}
|
||||
|
@ -138,9 +140,10 @@ class ServiceClient implements ServiceClientInterface
|
|||
* Creates and executes a command for an operation by name.
|
||||
*
|
||||
* @param string $name Name of the command to execute.
|
||||
* @param array $args Arguments to pass to the getCommand method.
|
||||
* @param array $args Arguments to pass to the getCommand method.
|
||||
*
|
||||
* @return ResultInterface|PromiseInterface
|
||||
*
|
||||
* @see \GuzzleHttp\Command\ServiceClientInterface::getCommand
|
||||
*/
|
||||
public function __call($name, array $args)
|
||||
|
@ -148,6 +151,7 @@ class ServiceClient implements ServiceClientInterface
|
|||
$args = isset($args[0]) ? $args[0] : [];
|
||||
if (substr($name, -5) === 'Async') {
|
||||
$command = $this->getCommand(substr($name, 0, -5), $args);
|
||||
|
||||
return $this->executeAsync($command);
|
||||
} else {
|
||||
return $this->execute($this->getCommand($name, $args));
|
||||
|
@ -162,7 +166,7 @@ class ServiceClient implements ServiceClientInterface
|
|||
private function createCommandHandler()
|
||||
{
|
||||
return function (CommandInterface $command) {
|
||||
return Promise\coroutine(function () use ($command) {
|
||||
return Promise\Coroutine::of(function () use ($command) {
|
||||
// Prepare the HTTP options.
|
||||
$opts = $command['@http'] ?: [];
|
||||
unset($command['@http']);
|
||||
|
@ -185,7 +189,6 @@ class ServiceClient implements ServiceClientInterface
|
|||
/**
|
||||
* Transforms a Command object into a Request object.
|
||||
*
|
||||
* @param CommandInterface $command
|
||||
* @return RequestInterface
|
||||
*/
|
||||
private function transformCommandToRequest(CommandInterface $command)
|
||||
|
@ -195,14 +198,10 @@ class ServiceClient implements ServiceClientInterface
|
|||
return $transform($command);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a Response object, also using data from the Request object,
|
||||
* into a Result object.
|
||||
*
|
||||
* @param ResponseInterface $response
|
||||
* @param RequestInterface $request
|
||||
* @param CommandInterface $command
|
||||
* @return ResultInterface
|
||||
*/
|
||||
private function transformResponseToResult(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command;
|
||||
|
||||
use GuzzleHttp\ClientInterface;
|
||||
|
@ -22,6 +23,7 @@ interface ServiceClientInterface
|
|||
* @param array $args Arguments to pass to the command
|
||||
*
|
||||
* @return CommandInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException if no command can be found by name
|
||||
*/
|
||||
public function getCommand($name, array $args = []);
|
||||
|
@ -32,6 +34,7 @@ interface ServiceClientInterface
|
|||
* @param CommandInterface $command Command to execute
|
||||
*
|
||||
* @return ResultInterface The result of the executed command
|
||||
*
|
||||
* @throws CommandException
|
||||
*/
|
||||
public function execute(CommandInterface $command);
|
||||
|
@ -49,13 +52,14 @@ interface ServiceClientInterface
|
|||
* Executes multiple commands concurrently using a fixed pool size.
|
||||
*
|
||||
* @param array|\Iterator $commands Array or iterator that contains
|
||||
* CommandInterface objects to execute with the client.
|
||||
* @param array $options Associative array of options to apply.
|
||||
* - concurrency: (int) Max number of commands to execute concurrently.
|
||||
* - fulfilled: (callable) Function to invoke when a command completes.
|
||||
* - rejected: (callable) Function to invoke when a command fails.
|
||||
* CommandInterface objects to execute with the client.
|
||||
* @param array $options Associative array of options to apply.
|
||||
* - concurrency: (int) Max number of commands to execute concurrently.
|
||||
* - fulfilled: (callable) Function to invoke when a command completes.
|
||||
* - rejected: (callable) Function to invoke when a command fails.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see GuzzleHttp\Command\ServiceClientInterface::createPool for options.
|
||||
*/
|
||||
public function executeAll($commands, array $options = []);
|
||||
|
@ -65,13 +69,14 @@ interface ServiceClientInterface
|
|||
* fixed pool size.
|
||||
*
|
||||
* @param array|\Iterator $commands Array or iterator that contains
|
||||
* CommandInterface objects to execute with the client.
|
||||
* @param array $options Associative array of options to apply.
|
||||
* - concurrency: (int) Max number of commands to execute concurrently.
|
||||
* - fulfilled: (callable) Function to invoke when a command completes.
|
||||
* - rejected: (callable) Function to invoke when a command fails.
|
||||
* CommandInterface objects to execute with the client.
|
||||
* @param array $options Associative array of options to apply.
|
||||
* - concurrency: (int) Max number of commands to execute concurrently.
|
||||
* - fulfilled: (callable) Function to invoke when a command completes.
|
||||
* - rejected: (callable) Function to invoke when a command fails.
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*
|
||||
* @see GuzzleHttp\Command\ServiceClientInterface::createPool for options.
|
||||
*/
|
||||
public function executeAllAsync($commands, array $options = []);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"friendsofphp/php-cs-fixer": "3.16.0"
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
$config = (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PHP71Migration:risky' => true,
|
||||
'@PHPUnit75Migration:risky' => true,
|
||||
'@Symfony' => true,
|
||||
'declare_strict_types' => false,
|
||||
'global_namespace_import' => false,
|
||||
'phpdoc_annotation_without_dot' => false,
|
||||
'phpdoc_summary' => false,
|
||||
'phpdoc_to_comment' => false,
|
||||
'single_line_throw' => false,
|
||||
'void_return' => false,
|
||||
'yoda_style' => false,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__.'/src')
|
||||
->in(__DIR__.'/tests')
|
||||
->name('*.php')
|
||||
)
|
||||
;
|
||||
|
||||
return $config;
|
|
@ -26,12 +26,13 @@
|
|||
],
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"guzzlehttp/guzzle": "^7.4.1",
|
||||
"guzzlehttp/command": "^1.2.2",
|
||||
"guzzlehttp/psr7": "^1.8.3 || ^2.1",
|
||||
"guzzlehttp/guzzle": "^7.7",
|
||||
"guzzlehttp/command": "^1.3",
|
||||
"guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
|
||||
"guzzlehttp/uri-template": "^1.0.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
||||
"phpunit/phpunit": "^8.5.19 || ^9.5.8"
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -48,12 +49,16 @@
|
|||
"gimler/guzzle-description-loader": "^0.0.4"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3-dev"
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"bamarni/composer-bin-plugin": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
|
@ -35,7 +36,7 @@ class Description implements DescriptionInterface
|
|||
/**
|
||||
* @param array $config Service description data
|
||||
* @param array $options Custom options to apply to the description
|
||||
* - formatter: Can provide a custom SchemaFormatter class
|
||||
* - formatter: Can provide a custom SchemaFormatter class
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
@ -132,6 +133,7 @@ class Description implements DescriptionInterface
|
|||
* @param string $name Name of the command
|
||||
*
|
||||
* @return Operation
|
||||
*
|
||||
* @throws \InvalidArgumentException if the operation is not found
|
||||
*/
|
||||
public function getOperation($name)
|
||||
|
@ -155,6 +157,7 @@ class Description implements DescriptionInterface
|
|||
* @param string $id ID/name of the model to retrieve
|
||||
*
|
||||
* @return Parameter
|
||||
*
|
||||
* @throws \InvalidArgumentException if the model is not found
|
||||
*/
|
||||
public function getModel($id)
|
||||
|
@ -250,7 +253,7 @@ class Description implements DescriptionInterface
|
|||
*
|
||||
* @param string $key Data key to retrieve or null to retrieve all extra
|
||||
*
|
||||
* @return null|mixed
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getData($key = null)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
|
@ -34,6 +35,7 @@ interface DescriptionInterface
|
|||
* @param string $name Name of the command
|
||||
*
|
||||
* @return Operation
|
||||
*
|
||||
* @throws \InvalidArgumentException if the operation is not found
|
||||
*/
|
||||
public function getOperation($name);
|
||||
|
@ -44,6 +46,7 @@ interface DescriptionInterface
|
|||
* @param string $id ID/name of the model to retrieve
|
||||
*
|
||||
* @return Parameter
|
||||
*
|
||||
* @throws \InvalidArgumentException if the model is not found
|
||||
*/
|
||||
public function getModel($id);
|
||||
|
@ -101,7 +104,7 @@ interface DescriptionInterface
|
|||
*
|
||||
* @param string $key Data key to retrieve or null to retrieve all extra
|
||||
*
|
||||
* @return null|mixed
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getData($key = null);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -29,18 +30,17 @@ use Psr\Http\Message\ResponseInterface;
|
|||
*/
|
||||
class Deserializer
|
||||
{
|
||||
/** @var ResponseLocationInterface[] $responseLocations */
|
||||
/** @var ResponseLocationInterface[] */
|
||||
private $responseLocations;
|
||||
|
||||
/** @var DescriptionInterface $description */
|
||||
/** @var DescriptionInterface */
|
||||
private $description;
|
||||
|
||||
/** @var boolean $process */
|
||||
/** @var bool */
|
||||
private $process;
|
||||
|
||||
/**
|
||||
* @param DescriptionInterface $description
|
||||
* @param bool $process
|
||||
* @param bool $process
|
||||
* @param ResponseLocationInterface[] $responseLocations Extra response locations
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -51,12 +51,12 @@ class Deserializer
|
|||
static $defaultResponseLocations;
|
||||
if (!$defaultResponseLocations) {
|
||||
$defaultResponseLocations = [
|
||||
'body' => new BodyLocation(),
|
||||
'header' => new HeaderLocation(),
|
||||
'body' => new BodyLocation(),
|
||||
'header' => new HeaderLocation(),
|
||||
'reasonPhrase' => new ReasonPhraseLocation(),
|
||||
'statusCode' => new StatusCodeLocation(),
|
||||
'xml' => new XmlLocation(),
|
||||
'json' => new JsonLocation(),
|
||||
'statusCode' => new StatusCodeLocation(),
|
||||
'xml' => new XmlLocation(),
|
||||
'json' => new JsonLocation(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -68,9 +68,8 @@ class Deserializer
|
|||
/**
|
||||
* Deserialize the response into the specified result representation
|
||||
*
|
||||
* @param ResponseInterface $response
|
||||
* @param RequestInterface|null $request
|
||||
* @param CommandInterface $command
|
||||
*
|
||||
* @return Result|ResultInterface|void|ResponseInterface
|
||||
*/
|
||||
public function __invoke(ResponseInterface $response, RequestInterface $request, CommandInterface $command)
|
||||
|
@ -103,8 +102,6 @@ class Deserializer
|
|||
/**
|
||||
* Handles visit() and after() methods of the Response locations
|
||||
*
|
||||
* @param Parameter $model
|
||||
* @param ResponseInterface $response
|
||||
* @return Result|ResultInterface|void
|
||||
*/
|
||||
protected function visit(Parameter $model, ResponseInterface $response)
|
||||
|
@ -117,7 +114,7 @@ class Deserializer
|
|||
} elseif ($model->getType() === 'array') {
|
||||
$result = $this->visitOuterArray($model, $result, $response, $context);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid response model: ' . $model->getType());
|
||||
throw new \InvalidArgumentException('Invalid response model: '.$model->getType());
|
||||
}
|
||||
|
||||
// Call the after() method of each found visitor
|
||||
|
@ -132,11 +129,8 @@ class Deserializer
|
|||
/**
|
||||
* Handles the before() method of Response locations
|
||||
*
|
||||
* @param string $location
|
||||
* @param Parameter $model
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param array $context
|
||||
* @param string $location
|
||||
*
|
||||
* @return ResultInterface
|
||||
*/
|
||||
private function triggerBeforeVisitor(
|
||||
|
@ -164,10 +158,6 @@ class Deserializer
|
|||
/**
|
||||
* Visits the outer object
|
||||
*
|
||||
* @param Parameter $model
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param array $context
|
||||
* @return ResultInterface
|
||||
*/
|
||||
private function visitOuterObject(
|
||||
|
@ -212,10 +202,6 @@ class Deserializer
|
|||
/**
|
||||
* Visits the outer array
|
||||
*
|
||||
* @param Parameter $model
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param array $context
|
||||
* @return ResultInterface|void
|
||||
*/
|
||||
private function visitOuterArray(
|
||||
|
@ -246,11 +232,6 @@ class Deserializer
|
|||
* In order for the exception to be properly triggered, all your exceptions must be instance
|
||||
* of "GuzzleHttp\Command\Exception\CommandException". If that's not the case, your exceptions will be wrapped
|
||||
* around a CommandException
|
||||
*
|
||||
* @param ResponseInterface $response
|
||||
* @param RequestInterface $request
|
||||
* @param CommandInterface $command
|
||||
* @param Operation $operation
|
||||
*/
|
||||
protected function handleErrorResponses(
|
||||
ResponseInterface $response,
|
||||
|
@ -271,7 +252,7 @@ class Deserializer
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isset($error['phrase']) && ! ($error['phrase'] === $response->getReasonPhrase())) {
|
||||
if (isset($error['phrase']) && !($error['phrase'] === $response->getReasonPhrase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\ClientInterface;
|
||||
|
@ -12,7 +13,7 @@ use GuzzleHttp\HandlerStack;
|
|||
*/
|
||||
class GuzzleClient extends ServiceClient
|
||||
{
|
||||
/** @var array $config */
|
||||
/** @var array */
|
||||
private $config;
|
||||
|
||||
/** @var DescriptionInterface Guzzle service description */
|
||||
|
@ -33,12 +34,12 @@ class GuzzleClient extends ServiceClient
|
|||
* - response_locations: Associative array of location types mapping to
|
||||
* ResponseLocationInterface objects.
|
||||
*
|
||||
* @param ClientInterface $client HTTP client to use.
|
||||
* @param DescriptionInterface $description Guzzle service description
|
||||
* @param callable $commandToRequestTransformer
|
||||
* @param callable $responseToResultTransformer
|
||||
* @param HandlerStack $commandHandlerStack
|
||||
* @param array $config Configuration options
|
||||
* @param ClientInterface $client HTTP client to use.
|
||||
* @param DescriptionInterface $description Guzzle service description
|
||||
* @param callable $commandToRequestTransformer
|
||||
* @param callable $responseToResultTransformer
|
||||
* @param HandlerStack $commandHandlerStack
|
||||
* @param array $config Configuration options
|
||||
*/
|
||||
public function __construct(
|
||||
ClientInterface $client,
|
||||
|
@ -59,9 +60,11 @@ class GuzzleClient extends ServiceClient
|
|||
|
||||
/**
|
||||
* Returns the command if valid; otherwise an Exception
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $args
|
||||
*
|
||||
* @return CommandInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function getCommand($name, array $args = [])
|
||||
|
@ -95,6 +98,7 @@ class GuzzleClient extends ServiceClient
|
|||
* Returns the passed Serializer when set, a new instance otherwise
|
||||
*
|
||||
* @param callable|null $commandToRequestTransformer
|
||||
*
|
||||
* @return \GuzzleHttp\Command\Guzzle\Serializer
|
||||
*/
|
||||
private function getSerializer($commandToRequestTransformer)
|
||||
|
@ -108,11 +112,12 @@ class GuzzleClient extends ServiceClient
|
|||
* Returns the passed Deserializer when set, a new instance otherwise
|
||||
*
|
||||
* @param callable|null $responseToResultTransformer
|
||||
*
|
||||
* @return \GuzzleHttp\Command\Guzzle\Deserializer
|
||||
*/
|
||||
private function getDeserializer($responseToResultTransformer)
|
||||
{
|
||||
$process = (! isset($this->config['process']) || $this->config['process'] === true);
|
||||
$process = (!isset($this->config['process']) || $this->config['process'] === true);
|
||||
|
||||
return $responseToResultTransformer !== null
|
||||
? $responseToResultTransformer
|
||||
|
@ -123,6 +128,7 @@ class GuzzleClient extends ServiceClient
|
|||
* Get the config of the client
|
||||
*
|
||||
* @param array|string $option
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConfig($option = null)
|
||||
|
@ -132,10 +138,6 @@ class GuzzleClient extends ServiceClient
|
|||
: (isset($this->config[$option]) ? $this->config[$option] : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $option
|
||||
* @param $value
|
||||
*/
|
||||
public function setConfig($option, $value)
|
||||
{
|
||||
$this->config[$option] = $value;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<?php namespace GuzzleHttp\Command\Guzzle\Handler;
|
||||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\Handler;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use GuzzleHttp\Command\Exception\CommandException;
|
||||
|
@ -12,17 +14,14 @@ use GuzzleHttp\Command\Guzzle\SchemaValidator;
|
|||
*/
|
||||
class ValidatedDescriptionHandler
|
||||
{
|
||||
/** @var SchemaValidator $validator */
|
||||
/** @var SchemaValidator */
|
||||
private $validator;
|
||||
|
||||
/** @var DescriptionInterface $description */
|
||||
/** @var DescriptionInterface */
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* ValidatedDescriptionHandler constructor.
|
||||
*
|
||||
* @param DescriptionInterface $description
|
||||
* @param SchemaValidator|null $schemaValidator
|
||||
*/
|
||||
public function __construct(DescriptionInterface $description, SchemaValidator $schemaValidator = null)
|
||||
{
|
||||
|
@ -31,7 +30,6 @@ class ValidatedDescriptionHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* @param callable $handler
|
||||
* @return \Closure
|
||||
*/
|
||||
public function __invoke(callable $handler)
|
||||
|
@ -47,7 +45,7 @@ class ValidatedDescriptionHandler
|
|||
$value = $schema->filter($value);
|
||||
}
|
||||
|
||||
if (! $this->validator->validate($schema, $value)) {
|
||||
if (!$this->validator->validate($schema, $value)) {
|
||||
$errors = array_merge($errors, $this->validator->getErrors());
|
||||
} elseif ($value !== $command[$name]) {
|
||||
// Update the config value if it changed and no validation errors were encountered.
|
||||
|
@ -60,10 +58,10 @@ class ValidatedDescriptionHandler
|
|||
if ($params = $operation->getAdditionalParameters()) {
|
||||
foreach ($command->toArray() as $name => $value) {
|
||||
// It's only additional if it isn't defined in the schema
|
||||
if (! $operation->hasParam($name)) {
|
||||
if (!$operation->hasParam($name)) {
|
||||
// Always set the name so that error messages are useful
|
||||
$params->setName($name);
|
||||
if (! $this->validator->validate($params, $value)) {
|
||||
if (!$this->validator->validate($params, $value)) {
|
||||
$errors = array_merge($errors, $this->validator->getErrors());
|
||||
} elseif ($value !== $command[$name]) {
|
||||
$command[$name] = $value;
|
||||
|
@ -73,7 +71,7 @@ class ValidatedDescriptionHandler
|
|||
}
|
||||
|
||||
if ($errors) {
|
||||
throw new CommandException('Validation errors: ' . implode("\n", $errors), $command);
|
||||
throw new CommandException('Validation errors: '.implode("\n", $errors), $command);
|
||||
}
|
||||
|
||||
return $handler($command);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\Command\ToArrayInterface;
|
||||
|
@ -45,8 +46,9 @@ class Operation implements ToArrayInterface
|
|||
* - additionalParameters: (null|array) Parameter schema to use when an
|
||||
* option is passed to the operation that is not in the schema
|
||||
*
|
||||
* @param array $config Array of configuration data
|
||||
* @param DescriptionInterface $description Service description used to resolve models if $ref tags are found
|
||||
* @param array $config Array of configuration data
|
||||
* @param DescriptionInterface $description Service description used to resolve models if $ref tags are found
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $config = [], DescriptionInterface $description = null)
|
||||
|
@ -63,7 +65,7 @@ class Operation implements ToArrayInterface
|
|||
'data' => [],
|
||||
'parameters' => [],
|
||||
'additionalParameters' => null,
|
||||
'errorResponses' => []
|
||||
'errorResponses' => [],
|
||||
];
|
||||
|
||||
$this->description = $description === null ? new Description([]) : $description;
|
||||
|
@ -240,7 +242,7 @@ class Operation implements ToArrayInterface
|
|||
* Get extra data from the operation
|
||||
*
|
||||
* @param string $name Name of the data point to retrieve or null to
|
||||
* retrieve all of the extra data.
|
||||
* retrieve all of the extra data.
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
|
@ -256,14 +258,12 @@ class Operation implements ToArrayInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
private function resolveExtends($name, array $config)
|
||||
{
|
||||
if (!$this->description->hasOperation($name)) {
|
||||
throw new \InvalidArgumentException('No operation named ' . $name);
|
||||
throw new \InvalidArgumentException('No operation named '.$name);
|
||||
}
|
||||
|
||||
// Merge parameters together one level deep
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\Command\ToArrayInterface;
|
||||
|
@ -6,74 +7,75 @@ use GuzzleHttp\Command\ToArrayInterface;
|
|||
/**
|
||||
* API parameter object used with service descriptions
|
||||
*/
|
||||
#[\AllowDynamicProperties]
|
||||
class Parameter implements ToArrayInterface
|
||||
{
|
||||
private $originalData;
|
||||
|
||||
/** @var string $name */
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var string $description */
|
||||
/** @var string */
|
||||
private $description;
|
||||
|
||||
/** @var string|array $type */
|
||||
/** @var string|array */
|
||||
private $type;
|
||||
|
||||
/** @var bool $required*/
|
||||
/** @var bool */
|
||||
private $required;
|
||||
|
||||
/** @var array|null $enum */
|
||||
/** @var array|null */
|
||||
private $enum;
|
||||
|
||||
/** @var string $pattern */
|
||||
/** @var string */
|
||||
private $pattern;
|
||||
|
||||
/** @var int $minimum*/
|
||||
/** @var int */
|
||||
private $minimum;
|
||||
|
||||
/** @var int $maximum */
|
||||
/** @var int */
|
||||
private $maximum;
|
||||
|
||||
/** @var int $minLength */
|
||||
/** @var int */
|
||||
private $minLength;
|
||||
|
||||
/** @var int $maxLength */
|
||||
/** @var int */
|
||||
private $maxLength;
|
||||
|
||||
/** @var int $minItems */
|
||||
/** @var int */
|
||||
private $minItems;
|
||||
|
||||
/** @var int $maxItems */
|
||||
/** @var int */
|
||||
private $maxItems;
|
||||
|
||||
/** @var mixed $default */
|
||||
/** @var mixed */
|
||||
private $default;
|
||||
|
||||
/** @var bool $static */
|
||||
/** @var bool */
|
||||
private $static;
|
||||
|
||||
/** @var array $filters */
|
||||
/** @var array */
|
||||
private $filters;
|
||||
|
||||
/** @var string $location */
|
||||
/** @var string */
|
||||
private $location;
|
||||
|
||||
/** @var string $sentAs */
|
||||
/** @var string */
|
||||
private $sentAs;
|
||||
|
||||
/** @var array $data */
|
||||
/** @var array */
|
||||
private $data;
|
||||
|
||||
/** @var array $properties */
|
||||
/** @var array */
|
||||
private $properties = [];
|
||||
|
||||
/** @var array|bool|Parameter $additionalProperties */
|
||||
/** @var array|bool|Parameter */
|
||||
private $additionalProperties;
|
||||
|
||||
/** @var array|Parameter $items */
|
||||
/** @var array|Parameter */
|
||||
private $items;
|
||||
|
||||
/** @var string $format */
|
||||
/** @var string */
|
||||
private $format;
|
||||
|
||||
private $propertiesCache = null;
|
||||
|
@ -171,7 +173,7 @@ class Parameter implements ToArrayInterface
|
|||
*
|
||||
* @param array $data Array of data as seen in service descriptions
|
||||
* @param array $options Options used when creating the parameter. You can
|
||||
* specify a Guzzle service description in the 'description' key.
|
||||
* specify a Guzzle service description in the 'description' key.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
@ -252,8 +254,9 @@ class Parameter implements ToArrayInterface
|
|||
* @param mixed $value Value to filter
|
||||
*
|
||||
* @return mixed Returns the filtered value
|
||||
*
|
||||
* @throws \RuntimeException when trying to format when no service
|
||||
* description is available.
|
||||
* description is available.
|
||||
*/
|
||||
public function filter($value)
|
||||
{
|
||||
|
@ -261,8 +264,9 @@ class Parameter implements ToArrayInterface
|
|||
if ($this->format) {
|
||||
if (!$this->serviceDescription) {
|
||||
throw new \RuntimeException('No service description was set so '
|
||||
. 'the value cannot be formatted.');
|
||||
.'the value cannot be formatted.');
|
||||
}
|
||||
|
||||
return $this->serviceDescription->format($this->format, $value);
|
||||
}
|
||||
|
||||
|
@ -512,7 +516,7 @@ class Parameter implements ToArrayInterface
|
|||
*
|
||||
* @param string $name Name of the property to retrieve
|
||||
*
|
||||
* @return null|Parameter
|
||||
* @return Parameter|null
|
||||
*/
|
||||
public function getProperty($name)
|
||||
{
|
||||
|
@ -618,6 +622,7 @@ class Parameter implements ToArrayInterface
|
|||
* @param string|array $filter Method to filter the value through
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function addFilter($filter)
|
||||
|
@ -643,13 +648,15 @@ class Parameter implements ToArrayInterface
|
|||
* Check if a parameter has a specific variable and if it set.
|
||||
*
|
||||
* @param string $var
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($var)
|
||||
{
|
||||
if (!is_string($var)) {
|
||||
throw new \InvalidArgumentException('Expected a string. Got: ' . (is_object($var) ? get_class($var) : gettype($var)));
|
||||
throw new \InvalidArgumentException('Expected a string. Got: '.(is_object($var) ? get_class($var) : gettype($var)));
|
||||
}
|
||||
|
||||
return isset($this->{$var}) && !empty($this->{$var});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\QuerySerializer;
|
||||
|
||||
interface QuerySerializerInterface
|
||||
|
@ -6,8 +7,7 @@ interface QuerySerializerInterface
|
|||
/**
|
||||
* Aggregate query params and transform them into a string
|
||||
*
|
||||
* @param array $queryParams
|
||||
* @return string
|
||||
*/
|
||||
public function aggregate(array $queryParams);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -13,8 +14,6 @@ abstract class AbstractLocation implements RequestLocationInterface
|
|||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
* @param $locationName
|
||||
*/
|
||||
public function __construct($locationName)
|
||||
{
|
||||
|
@ -22,9 +21,6 @@ abstract class AbstractLocation implements RequestLocationInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -36,9 +32,6 @@ abstract class AbstractLocation implements RequestLocationInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Operation $operation
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function after(
|
||||
|
@ -53,8 +46,7 @@ abstract class AbstractLocation implements RequestLocationInterface
|
|||
* Prepare (filter and set desired name for request item) the value for
|
||||
* request.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param Parameter $param
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -12,7 +13,6 @@ use Psr\Http\Message\RequestInterface;
|
|||
*/
|
||||
class BodyLocation extends AbstractLocation
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
|
@ -24,10 +24,6 @@ class BodyLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return MessageInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -38,10 +34,10 @@ class BodyLocation extends AbstractLocation
|
|||
$oldValue = $request->getBody()->getContents();
|
||||
|
||||
$value = $command[$param->getName()];
|
||||
$value = $param->getName() . '=' . $param->filter($value);
|
||||
$value = $param->getName().'='.$param->filter($value);
|
||||
|
||||
if ($oldValue !== '') {
|
||||
$value = $oldValue . '&' . $value;
|
||||
$value = $oldValue.'&'.$value;
|
||||
}
|
||||
|
||||
return $request->withBody(Psr7\Utils::streamFor($value));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -12,10 +13,10 @@ use Psr\Http\Message\RequestInterface;
|
|||
*/
|
||||
class FormParamLocation extends AbstractLocation
|
||||
{
|
||||
/** @var string $contentType */
|
||||
/** @var string */
|
||||
protected $contentType = 'application/x-www-form-urlencoded; charset=utf-8';
|
||||
|
||||
/** @var array $formParamsData */
|
||||
/** @var array */
|
||||
protected $formParamsData = [];
|
||||
|
||||
/**
|
||||
|
@ -29,10 +30,6 @@ class FormParamLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -49,10 +46,6 @@ class FormParamLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Operation $operation
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function after(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -12,7 +13,6 @@ use Psr\Http\Message\RequestInterface;
|
|||
*/
|
||||
class HeaderLocation extends AbstractLocation
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
|
@ -24,10 +24,6 @@ class HeaderLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return MessageInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -41,10 +37,6 @@ class HeaderLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Operation $operation
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function after(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -23,7 +24,7 @@ class JsonLocation extends AbstractLocation
|
|||
/**
|
||||
* @param string $locationName Name of the location
|
||||
* @param string $contentType Content-Type header to add to the request if
|
||||
* JSON is added to the body. Pass an empty string to omit.
|
||||
* JSON is added to the body. Pass an empty string to omit.
|
||||
*/
|
||||
public function __construct($locationName = 'json', $contentType = 'application/json')
|
||||
{
|
||||
|
@ -32,10 +33,6 @@ class JsonLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -52,10 +49,6 @@ class JsonLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Operation $operation
|
||||
*
|
||||
* @return MessageInterface
|
||||
*/
|
||||
public function after(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -12,10 +13,10 @@ use Psr\Http\Message\RequestInterface;
|
|||
*/
|
||||
class MultiPartLocation extends AbstractLocation
|
||||
{
|
||||
/** @var string $contentType */
|
||||
/** @var string */
|
||||
protected $contentType = 'multipart/form-data; boundary=';
|
||||
|
||||
/** @var array $formParamsData */
|
||||
/** @var array */
|
||||
protected $multipartData = [];
|
||||
|
||||
/**
|
||||
|
@ -29,9 +30,6 @@ class MultiPartLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -41,17 +39,13 @@ class MultiPartLocation extends AbstractLocation
|
|||
) {
|
||||
$this->multipartData[] = [
|
||||
'name' => $param->getWireName(),
|
||||
'contents' => $this->prepareValue($command[$param->getName()], $param)
|
||||
'contents' => $this->prepareValue($command[$param->getName()], $param),
|
||||
];
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Operation $operation
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function after(
|
||||
|
@ -68,7 +62,7 @@ class MultiPartLocation extends AbstractLocation
|
|||
$request = Psr7\Utils::modifyRequest($request, $modify);
|
||||
if ($request->getBody() instanceof Psr7\MultipartStream) {
|
||||
// Use a multipart/form-data POST if a Content-Type is not set.
|
||||
$request->withHeader('Content-Type', $this->contentType . $request->getBody()->getBoundary());
|
||||
$request->withHeader('Content-Type', $this->contentType.$request->getBody()->getBoundary());
|
||||
}
|
||||
|
||||
return $request;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -22,8 +23,7 @@ class QueryLocation extends AbstractLocation
|
|||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
* @param string $locationName
|
||||
* @param QuerySerializerInterface|null $querySerializer
|
||||
* @param string $locationName
|
||||
*/
|
||||
public function __construct($locationName = 'query', QuerySerializerInterface $querySerializer = null)
|
||||
{
|
||||
|
@ -33,10 +33,6 @@ class QueryLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -58,10 +54,6 @@ class QueryLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Operation $operation
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function after(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -24,8 +25,8 @@ class XmlLocation extends AbstractLocation
|
|||
/**
|
||||
* @param string $locationName Name of the location
|
||||
* @param string $contentType Set to a non-empty string to add a
|
||||
* Content-Type header to a request if any XML content is added to the
|
||||
* body. Pass an empty string to disable the addition of the header.
|
||||
* Content-Type header to a request if any XML content is added to the
|
||||
* body. Pass an empty string to disable the addition of the header.
|
||||
*/
|
||||
public function __construct($locationName = 'xml', $contentType = 'application/xml')
|
||||
{
|
||||
|
@ -34,10 +35,6 @@ class XmlLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -58,10 +55,6 @@ class XmlLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Operation $operation
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function after(
|
||||
|
@ -149,8 +142,8 @@ class XmlLocation extends AbstractLocation
|
|||
* Recursively build the XML body
|
||||
*
|
||||
* @param \XMLWriter $writer XML to modify
|
||||
* @param Parameter $param API Parameter
|
||||
* @param mixed $value Value to add
|
||||
* @param Parameter $param API Parameter
|
||||
* @param mixed $value Value to add
|
||||
*/
|
||||
protected function addXml(\XMLWriter $writer, Parameter $param, $value)
|
||||
{
|
||||
|
@ -179,6 +172,7 @@ class XmlLocation extends AbstractLocation
|
|||
if (!$param->getData('xmlFlattened')) {
|
||||
$writer->endElement();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if ($param->getData('xmlAttribute')) {
|
||||
|
@ -191,11 +185,11 @@ class XmlLocation extends AbstractLocation
|
|||
/**
|
||||
* Write an attribute with namespace if used
|
||||
*
|
||||
* @param \XMLWriter $writer XMLWriter instance
|
||||
* @param string $prefix Namespace prefix if any
|
||||
* @param string $name Attribute name
|
||||
* @param string $namespace The uri of the namespace
|
||||
* @param string $value The attribute content
|
||||
* @param \XMLWriter $writer XMLWriter instance
|
||||
* @param string $prefix Namespace prefix if any
|
||||
* @param string $name Attribute name
|
||||
* @param string $namespace The uri of the namespace
|
||||
* @param string $value The attribute content
|
||||
*/
|
||||
protected function writeAttribute($writer, $prefix, $name, $namespace, $value)
|
||||
{
|
||||
|
@ -209,11 +203,11 @@ class XmlLocation extends AbstractLocation
|
|||
/**
|
||||
* Write an element with namespace if used
|
||||
*
|
||||
* @param \XMLWriter $writer XML writer resource
|
||||
* @param string $prefix Namespace prefix if any
|
||||
* @param string $name Element name
|
||||
* @param string $namespace The uri of the namespace
|
||||
* @param string $value The element content
|
||||
* @param \XMLWriter $writer XML writer resource
|
||||
* @param string $prefix Namespace prefix if any
|
||||
* @param string $name Element name
|
||||
* @param string $namespace The uri of the namespace
|
||||
* @param string $value The element content
|
||||
*/
|
||||
protected function writeElement(\XMLWriter $writer, $prefix, $name, $namespace, $value)
|
||||
{
|
||||
|
@ -233,9 +227,10 @@ class XmlLocation extends AbstractLocation
|
|||
/**
|
||||
* Create a new xml writer and start a document
|
||||
*
|
||||
* @param string $encoding document encoding
|
||||
* @param string $encoding document encoding
|
||||
*
|
||||
* @return \XMLWriter the writer resource
|
||||
*
|
||||
* @throws \RuntimeException if the document cannot be started
|
||||
*/
|
||||
protected function startDocument($encoding)
|
||||
|
@ -267,10 +262,6 @@ class XmlLocation extends AbstractLocation
|
|||
|
||||
/**
|
||||
* Add an array to the XML
|
||||
*
|
||||
* @param \XMLWriter $writer
|
||||
* @param Parameter $param
|
||||
* @param $value
|
||||
*/
|
||||
protected function addXmlArray(\XMLWriter $writer, Parameter $param, &$value)
|
||||
{
|
||||
|
@ -283,10 +274,6 @@ class XmlLocation extends AbstractLocation
|
|||
|
||||
/**
|
||||
* Add an object to the XML
|
||||
*
|
||||
* @param \XMLWriter $writer
|
||||
* @param Parameter $param
|
||||
* @param $value
|
||||
*/
|
||||
protected function addXmlObject(\XMLWriter $writer, Parameter $param, &$value)
|
||||
{
|
||||
|
@ -309,11 +296,6 @@ class XmlLocation extends AbstractLocation
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param Parameter $param
|
||||
* @param Operation $operation
|
||||
*/
|
||||
private function visitWithValue(
|
||||
$value,
|
||||
Parameter $param,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
@ -7,18 +8,14 @@ use Psr\Http\Message\ResponseInterface;
|
|||
|
||||
/**
|
||||
* Class AbstractLocation
|
||||
*
|
||||
* @package GuzzleHttp\Command\Guzzle\ResponseLocation
|
||||
*/
|
||||
abstract class AbstractLocation implements ResponseLocationInterface
|
||||
{
|
||||
/** @var string $locationName */
|
||||
/** @var string */
|
||||
protected $locationName;
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
* @param $locationName
|
||||
*/
|
||||
public function __construct($locationName)
|
||||
{
|
||||
|
@ -26,9 +23,6 @@ abstract class AbstractLocation implements ResponseLocationInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $model
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function before(
|
||||
|
@ -40,9 +34,6 @@ abstract class AbstractLocation implements ResponseLocationInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $model
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function after(
|
||||
|
@ -54,9 +45,6 @@ abstract class AbstractLocation implements ResponseLocationInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $param
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
@ -10,7 +11,6 @@ use Psr\Http\Message\ResponseInterface;
|
|||
*/
|
||||
class BodyLocation extends AbstractLocation
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
|
@ -22,9 +22,6 @@ class BodyLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $param
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
@ -10,7 +11,6 @@ use Psr\Http\Message\ResponseInterface;
|
|||
*/
|
||||
class HeaderLocation extends AbstractLocation
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
|
@ -22,10 +22,6 @@ class HeaderLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
@ -25,10 +26,6 @@ class JsonLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \GuzzleHttp\Command\ResultInterface $result
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @param \GuzzleHttp\Command\Guzzle\Parameter $model
|
||||
*
|
||||
* @return \GuzzleHttp\Command\ResultInterface
|
||||
*/
|
||||
public function before(
|
||||
|
@ -37,7 +34,7 @@ class JsonLocation extends AbstractLocation
|
|||
Parameter $model
|
||||
) {
|
||||
$body = (string) $response->getBody();
|
||||
$body = $body ?: "{}";
|
||||
$body = $body ?: '{}';
|
||||
$this->json = \GuzzleHttp\json_decode($body, true);
|
||||
// relocate named arrays, so that they have the same structure as
|
||||
// arrays nested in objects and visit can work on them in the same way
|
||||
|
@ -49,9 +46,6 @@ class JsonLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $model
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function after(
|
||||
|
@ -84,9 +78,6 @@ class JsonLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $param
|
||||
* @return Result|ResultInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -123,6 +114,7 @@ class JsonLocation extends AbstractLocation
|
|||
*
|
||||
* @param Parameter $param API parameter being validated
|
||||
* @param mixed $value Value to process.
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function recurse(Parameter $param, $value)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
@ -10,7 +11,6 @@ use Psr\Http\Message\ResponseInterface;
|
|||
*/
|
||||
class ReasonPhraseLocation extends AbstractLocation
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
|
@ -22,9 +22,6 @@ class ReasonPhraseLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $param
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
@ -10,7 +11,6 @@ use Psr\Http\Message\ResponseInterface;
|
|||
*/
|
||||
class StatusCodeLocation extends AbstractLocation
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
|
@ -22,9 +22,6 @@ class StatusCodeLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $param
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle\ResponseLocation;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
|
@ -25,9 +26,6 @@ class XmlLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $model
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function before(
|
||||
|
@ -41,9 +39,6 @@ class XmlLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $model
|
||||
* @return Result|ResultInterface
|
||||
*/
|
||||
public function after(
|
||||
|
@ -68,9 +63,6 @@ class XmlLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ResultInterface $result
|
||||
* @param ResponseInterface $response
|
||||
* @param Parameter $param
|
||||
* @return ResultInterface
|
||||
*/
|
||||
public function visit(
|
||||
|
@ -80,7 +72,7 @@ class XmlLocation extends AbstractLocation
|
|||
) {
|
||||
$sentAs = $param->getWireName();
|
||||
$ns = null;
|
||||
if (strstr($sentAs, ':')) {
|
||||
if (null !== $sentAs && strstr($sentAs, ':')) {
|
||||
list($ns, $sentAs) = explode(':', $sentAs);
|
||||
}
|
||||
|
||||
|
@ -100,6 +92,7 @@ class XmlLocation extends AbstractLocation
|
|||
*
|
||||
* @param Parameter $param API parameter being processed
|
||||
* @param \SimpleXMLElement $node Node being processed
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function recursiveProcess(
|
||||
|
@ -132,8 +125,6 @@ class XmlLocation extends AbstractLocation
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Parameter $param
|
||||
* @param \SimpleXMLElement $node
|
||||
* @return array
|
||||
*/
|
||||
private function processArray(Parameter $param, \SimpleXMLElement $node)
|
||||
|
@ -144,7 +135,7 @@ class XmlLocation extends AbstractLocation
|
|||
$result = [];
|
||||
$ns = null;
|
||||
|
||||
if (strstr($sentAs, ':')) {
|
||||
if (null !== $sentAs && strstr($sentAs, ':')) {
|
||||
// Get namespace from the wire name
|
||||
list($ns, $sentAs) = explode(':', $sentAs);
|
||||
} else {
|
||||
|
@ -174,6 +165,7 @@ class XmlLocation extends AbstractLocation
|
|||
*
|
||||
* @param Parameter $param API parameter being parsed
|
||||
* @param \SimpleXMLElement $node Value to process
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function processObject(Parameter $param, \SimpleXMLElement $node)
|
||||
|
@ -243,9 +235,8 @@ class XmlLocation extends AbstractLocation
|
|||
/**
|
||||
* Convert an XML document to an array.
|
||||
*
|
||||
* @param \SimpleXMLElement $xml
|
||||
* @param int $nesting
|
||||
* @param null $ns
|
||||
* @param int $nesting
|
||||
* @param null $ns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
/**
|
||||
|
@ -41,6 +42,7 @@ class SchemaFormatter
|
|||
* @param string $format Format of the result
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function dateFormatter($dateTime, $format)
|
||||
|
@ -58,18 +60,19 @@ class SchemaFormatter
|
|||
if (!$utc) {
|
||||
$utc = new \DateTimeZone('UTC');
|
||||
}
|
||||
|
||||
return $dateTime->setTimezone($utc)->format($format);
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('Date/Time values must be either '
|
||||
. 'be a string, integer, or DateTime object');
|
||||
.'be a string, integer, or DateTime object');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ISO 8601 (YYYY-MM-DDThh:mm:ssZ) formatted date time value in
|
||||
* UTC time.
|
||||
*
|
||||
* @param string|integer|\DateTime $value Date time value
|
||||
* @param string|int|\DateTime $value Date time value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -81,7 +84,7 @@ class SchemaFormatter
|
|||
/**
|
||||
* Create an HTTP date (RFC 1123 / RFC 822) formatted UTC date-time string
|
||||
*
|
||||
* @param string|integer|\DateTime $value Date time value
|
||||
* @param string|int|\DateTime $value Date time value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -93,7 +96,7 @@ class SchemaFormatter
|
|||
/**
|
||||
* Create a YYYY-MM-DD formatted string
|
||||
*
|
||||
* @param string|integer|\DateTime $value Date time value
|
||||
* @param string|int|\DateTime $value Date time value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -105,7 +108,7 @@ class SchemaFormatter
|
|||
/**
|
||||
* Create a hh:mm:ss formatted string
|
||||
*
|
||||
* @param string|integer|\DateTime $value Date time value
|
||||
* @param string|int|\DateTime $value Date time value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -117,8 +120,8 @@ class SchemaFormatter
|
|||
/**
|
||||
* Formats a boolean value as a string
|
||||
*
|
||||
* @param string|integer|bool $value Value to convert to a boolean
|
||||
* 'true' / 'false' value
|
||||
* @param string|int|bool $value Value to convert to a boolean
|
||||
* 'true' / 'false' value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -130,7 +133,7 @@ class SchemaFormatter
|
|||
/**
|
||||
* Return a UNIX timestamp in the UTC timezone
|
||||
*
|
||||
* @param string|integer|\DateTime $value Time value
|
||||
* @param string|int|\DateTime $value Time value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\Command\ToArrayInterface;
|
||||
|
@ -21,8 +22,8 @@ class SchemaValidator
|
|||
|
||||
/**
|
||||
* @param bool $castIntegerToStringType Set to true to convert integers
|
||||
* into strings when a required type is a string and the input value is
|
||||
* an integer. Defaults to true.
|
||||
* into strings when a required type is a string and the input value is
|
||||
* an integer. Defaults to true.
|
||||
*/
|
||||
public function __construct($castIntegerToStringType = true)
|
||||
{
|
||||
|
@ -30,8 +31,6 @@ class SchemaValidator
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Parameter $param
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function validate(Parameter $param, &$value)
|
||||
|
@ -43,6 +42,7 @@ class SchemaValidator
|
|||
return true;
|
||||
} else {
|
||||
sort($this->errors);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -60,8 +60,8 @@ class SchemaValidator
|
|||
/**
|
||||
* From the allowable types, determine the type that the variable matches
|
||||
*
|
||||
* @param string|array $type Parameter type
|
||||
* @param mixed $value Value to determine the type
|
||||
* @param string|array $type Parameter type
|
||||
* @param mixed $value Value to determine the type
|
||||
*
|
||||
* @return string|false Returns the matching type on
|
||||
*/
|
||||
|
@ -97,11 +97,11 @@ class SchemaValidator
|
|||
/**
|
||||
* Recursively validate a parameter
|
||||
*
|
||||
* @param Parameter $param API parameter being validated
|
||||
* @param mixed $value Value to validate and validate. The value may
|
||||
* change during this validate.
|
||||
* @param string $path Current validation path (used for error reporting)
|
||||
* @param int $depth Current depth in the validation validate
|
||||
* @param Parameter $param API parameter being validated
|
||||
* @param mixed $value Value to validate and validate. The value may
|
||||
* change during this validate.
|
||||
* @param string $path Current validation path (used for error reporting)
|
||||
* @param int $depth Current depth in the validation validate
|
||||
*
|
||||
* @return bool Returns true if valid, or false if invalid
|
||||
*/
|
||||
|
@ -146,6 +146,7 @@ class SchemaValidator
|
|||
// indexed
|
||||
if (isset($value[0])) {
|
||||
$this->errors[] = "{$path} must be an array of properties. Got a numerically indexed array.";
|
||||
|
||||
return false;
|
||||
}
|
||||
$traverse = true;
|
||||
|
@ -208,24 +209,24 @@ class SchemaValidator
|
|||
$valueIsArray = false;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($type == 'array' && $valueIsArray && $param->getItems()) {
|
||||
foreach ($value as $i => &$item) {
|
||||
// Validate each item in an array against the items attribute of the schema
|
||||
$this->recursiveProcess($param->getItems(), $item, $path . "[{$i}]", $depth + 1);
|
||||
$this->recursiveProcess($param->getItems(), $item, $path."[{$i}]", $depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// If the value is required and the type is not null, then there is an
|
||||
// error if the value is not set
|
||||
if ($required && $value === null && $type != 'null') {
|
||||
$message = "{$path} is " . ($param->getType()
|
||||
? ('a required ' . implode(' or ', (array) $param->getType()))
|
||||
$message = "{$path} is ".($param->getType()
|
||||
? ('a required '.implode(' or ', (array) $param->getType()))
|
||||
: 'required');
|
||||
if ($param->has('description')) {
|
||||
$message .= ': ' . $param->getDescription();
|
||||
$message .= ': '.$param->getDescription();
|
||||
}
|
||||
$this->errors[] = $message;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -239,7 +240,7 @@ class SchemaValidator
|
|||
) {
|
||||
$value = (string) $value;
|
||||
} else {
|
||||
$this->errors[] = "{$path} must be of type " . implode(' or ', (array) $param->getType());
|
||||
$this->errors[] = "{$path} must be of type ".implode(' or ', (array) $param->getType());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,12 +248,12 @@ class SchemaValidator
|
|||
if ($type == 'string') {
|
||||
// Strings can have enums which are a list of predefined values
|
||||
if (($enum = $param->getEnum()) && !in_array($value, $enum)) {
|
||||
$this->errors[] = "{$path} must be one of " . implode(' or ', array_map(function ($s) {
|
||||
return '"' . addslashes($s) . '"';
|
||||
$this->errors[] = "{$path} must be one of ".implode(' or ', array_map(function ($s) {
|
||||
return '"'.addslashes($s).'"';
|
||||
}, $enum));
|
||||
}
|
||||
// Strings can have a regex pattern that the value must match
|
||||
if (($pattern = $param->getPattern()) && !preg_match($pattern, $value)) {
|
||||
if (($pattern = $param->getPattern()) && !preg_match($pattern, $value)) {
|
||||
$this->errors[] = "{$path} must match the following regular expression: {$pattern}";
|
||||
}
|
||||
|
||||
|
@ -268,7 +269,6 @@ class SchemaValidator
|
|||
$this->errors[] = "{$path} length must be less than or equal to {$max}";
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($type == 'array') {
|
||||
$size = null;
|
||||
if ($min = $param->getMinItems()) {
|
||||
|
@ -282,7 +282,6 @@ class SchemaValidator
|
|||
$this->errors[] = "{$path} must contain {$max} or fewer elements";
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($type == 'integer' || $type == 'number' || $type == 'numeric') {
|
||||
if (($min = $param->getMinimum()) && $value < $min) {
|
||||
$this->errors[] = "{$path} must be greater than or equal to {$min}";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Command\Guzzle;
|
||||
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
|
@ -28,7 +29,6 @@ class Serializer
|
|||
private $description;
|
||||
|
||||
/**
|
||||
* @param DescriptionInterface $description
|
||||
* @param RequestLocationInterface[] $requestLocations Extra request locations
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -38,11 +38,11 @@ class Serializer
|
|||
static $defaultRequestLocations;
|
||||
if (!$defaultRequestLocations) {
|
||||
$defaultRequestLocations = [
|
||||
'body' => new BodyLocation(),
|
||||
'query' => new QueryLocation(),
|
||||
'header' => new HeaderLocation(),
|
||||
'json' => new JsonLocation(),
|
||||
'xml' => new XmlLocation(),
|
||||
'body' => new BodyLocation(),
|
||||
'query' => new QueryLocation(),
|
||||
'header' => new HeaderLocation(),
|
||||
'json' => new JsonLocation(),
|
||||
'xml' => new XmlLocation(),
|
||||
'formParam' => new FormParamLocation(),
|
||||
'multipart' => new MultiPartLocation(),
|
||||
];
|
||||
|
@ -53,21 +53,22 @@ class Serializer
|
|||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function __invoke(CommandInterface $command)
|
||||
{
|
||||
$request = $this->createRequest($command);
|
||||
|
||||
return $this->prepareRequest($command, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a request for sending using location visitors
|
||||
*
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request Request being created
|
||||
*
|
||||
* @return RequestInterface
|
||||
*
|
||||
* @throws \RuntimeException If a location cannot be handled
|
||||
*/
|
||||
protected function prepareRequest(
|
||||
|
@ -109,9 +110,8 @@ class Serializer
|
|||
/**
|
||||
* Create a request for the command and operation
|
||||
*
|
||||
* @param CommandInterface $command
|
||||
*
|
||||
* @return RequestInterface
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function createRequest(CommandInterface $command)
|
||||
|
@ -133,7 +133,6 @@ class Serializer
|
|||
* Create a request for an operation with a uri merged onto a base URI
|
||||
*
|
||||
* @param \GuzzleHttp\Command\Guzzle\Operation $operation
|
||||
* @param \GuzzleHttp\Command\CommandInterface $command
|
||||
*
|
||||
* @return \GuzzleHttp\Psr7\Request
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"friendsofphp/php-cs-fixer": "3.16.0"
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
}
|
||||
}
|
|
@ -2,12 +2,36 @@
|
|||
|
||||
Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version.
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
### Added
|
||||
|
||||
- Support `guzzlehttp/promises` v2
|
||||
|
||||
|
||||
## 7.6.1 - 2023-05-15
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `SetCookie::fromString` MaxAge deprecation warning and skip invalid MaxAge values
|
||||
|
||||
|
||||
## 7.6.0 - 2023-05-14
|
||||
|
||||
### Added
|
||||
|
@ -15,6 +39,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
- Support for setting the minimum TLS version in a unified way
|
||||
- Apply on request the version set in options parameters
|
||||
|
||||
|
||||
## 7.5.2 - 2023-05-14
|
||||
|
||||
### Fixed
|
||||
|
@ -26,6 +51,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
|
||||
- Corrected docs and default connect timeout value to 300 seconds
|
||||
|
||||
|
||||
## 7.5.1 - 2023-04-17
|
||||
|
||||
### Fixed
|
||||
|
@ -36,6 +62,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
|
||||
- Adjusted `guzzlehttp/psr7` version constraint to `^1.9.1 || ^2.4.5`
|
||||
|
||||
|
||||
## 7.5.0 - 2022-08-28
|
||||
|
||||
### Added
|
||||
|
@ -43,6 +70,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
- Support PHP 8.2
|
||||
- Add request to delay closure params
|
||||
|
||||
|
||||
## 7.4.5 - 2022-06-20
|
||||
|
||||
### Fixed
|
||||
|
@ -50,6 +78,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
* Fix change in port should be considered a change in origin
|
||||
* Fix `CURLOPT_HTTPAUTH` option not cleared on change of origin
|
||||
|
||||
|
||||
## 7.4.4 - 2022-06-09
|
||||
|
||||
### Fixed
|
||||
|
@ -57,12 +86,14 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
* Fix failure to strip Authorization header on HTTP downgrade
|
||||
* Fix failure to strip the Cookie header on change in host or HTTP downgrade
|
||||
|
||||
|
||||
## 7.4.3 - 2022-05-25
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix cross-domain cookie leakage
|
||||
|
||||
|
||||
## 7.4.2 - 2022-03-20
|
||||
|
||||
### Fixed
|
||||
|
@ -71,6 +102,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
- Reject non-HTTP schemes in StreamHandler
|
||||
- Set a default ssl.peer_name context in StreamHandler to allow `force_ip_resolve`
|
||||
|
||||
|
||||
## 7.4.1 - 2021-12-06
|
||||
|
||||
### Changed
|
||||
|
@ -82,6 +114,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
|
||||
- Only close curl handle if it's done [#2950](https://github.com/guzzle/guzzle/pull/2950)
|
||||
|
||||
|
||||
## 7.4.0 - 2021-10-18
|
||||
|
||||
### Added
|
||||
|
@ -99,6 +132,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
|
||||
- Be more strict with types [#2914](https://github.com/guzzle/guzzle/pull/2914), [#2917](https://github.com/guzzle/guzzle/pull/2917), [#2919](https://github.com/guzzle/guzzle/pull/2919), [#2945](https://github.com/guzzle/guzzle/pull/2945)
|
||||
|
||||
|
||||
## 7.3.0 - 2021-03-23
|
||||
|
||||
### Added
|
||||
|
@ -111,6 +145,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
|
||||
- Handle exceptions on invalid header consistently between PHP versions and handlers [#2872](https://github.com/guzzle/guzzle/pull/2872)
|
||||
|
||||
|
||||
## 7.2.0 - 2020-10-10
|
||||
|
||||
### Added
|
||||
|
@ -133,6 +168,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
|
||||
- Using environment variable GUZZLE_CURL_SELECT_TIMEOUT [#2786](https://github.com/guzzle/guzzle/pull/2786)
|
||||
|
||||
|
||||
## 7.1.1 - 2020-09-30
|
||||
|
||||
### Fixed
|
||||
|
@ -144,6 +180,7 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
- We dont connect curl `sink` on HEAD requests.
|
||||
- Removed some PHP 5 workarounds
|
||||
|
||||
|
||||
## 7.1.0 - 2020-09-22
|
||||
|
||||
### Added
|
||||
|
@ -166,14 +203,17 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version
|
|||
- `Utils::defaultCaBundle()`
|
||||
- `CurlFactory::LOW_CURL_VERSION_NUMBER`
|
||||
|
||||
|
||||
## 7.0.1 - 2020-06-27
|
||||
|
||||
* Fix multiply defined functions fatal error [#2699](https://github.com/guzzle/guzzle/pull/2699)
|
||||
|
||||
|
||||
## 7.0.0 - 2020-06-27
|
||||
|
||||
No changes since 7.0.0-rc1.
|
||||
|
||||
|
||||
## 7.0.0-rc1 - 2020-06-15
|
||||
|
||||
### Changed
|
||||
|
@ -181,6 +221,7 @@ No changes since 7.0.0-rc1.
|
|||
* Use error level for logging errors in Middleware [#2629](https://github.com/guzzle/guzzle/pull/2629)
|
||||
* Disabled IDN support by default and require ext-intl to use it [#2675](https://github.com/guzzle/guzzle/pull/2675)
|
||||
|
||||
|
||||
## 7.0.0-beta2 - 2020-05-25
|
||||
|
||||
### Added
|
||||
|
@ -206,6 +247,7 @@ No changes since 7.0.0-rc1.
|
|||
|
||||
* Pool option `pool_size` [#2528](https://github.com/guzzle/guzzle/pull/2528)
|
||||
|
||||
|
||||
## 7.0.0-beta1 - 2019-12-30
|
||||
|
||||
The diff might look very big but 95% of Guzzle users will be able to upgrade without modification.
|
||||
|
@ -239,15 +281,18 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* `uri_template()` and `UriTemplate` [#2440](https://github.com/guzzle/guzzle/pull/2440)
|
||||
* Request options `save_to` and `exceptions` [#2464](https://github.com/guzzle/guzzle/pull/2464)
|
||||
|
||||
|
||||
## 6.5.2 - 2019-12-23
|
||||
|
||||
* idn_to_ascii() fix for old PHP versions [#2489](https://github.com/guzzle/guzzle/pull/2489)
|
||||
|
||||
|
||||
## 6.5.1 - 2019-12-21
|
||||
|
||||
* Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454)
|
||||
* IDN support for redirects [#2424](https://github.com/guzzle/guzzle/pull/2424)
|
||||
|
||||
|
||||
## 6.5.0 - 2019-12-07
|
||||
|
||||
* Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143)
|
||||
|
@ -257,11 +302,13 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Fix: Prevent undefined offset when using array for ssl_key options. [#2348](https://github.com/guzzle/guzzle/pull/2348)
|
||||
* Deprecated `ClientInterface::VERSION`
|
||||
|
||||
|
||||
## 6.4.1 - 2019-10-23
|
||||
|
||||
* No `guzzle.phar` was created in 6.4.0 due expired API token. This release will fix that
|
||||
* Added `parent::__construct()` to `FileCookieJar` and `SessionCookieJar`
|
||||
|
||||
|
||||
## 6.4.0 - 2019-10-23
|
||||
|
||||
* Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108)
|
||||
|
@ -274,6 +321,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Fix: Prevent concurrent writes to file when saving `CookieJar` [#2335](https://github.com/guzzle/guzzle/pull/2335)
|
||||
* Improvement: Update `MockHandler` so we can test transfer time [#2362](https://github.com/guzzle/guzzle/pull/2362)
|
||||
|
||||
|
||||
## 6.3.3 - 2018-04-22
|
||||
|
||||
* Fix: Default headers when decode_content is specified
|
||||
|
@ -315,13 +363,14 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684)
|
||||
* Improvement: Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827)
|
||||
|
||||
|
||||
+ Minor code cleanups, documentation fixes and clarifications.
|
||||
|
||||
|
||||
## 6.2.3 - 2017-02-28
|
||||
|
||||
* Fix deprecations with guzzle/psr7 version 1.4
|
||||
|
||||
|
||||
## 6.2.2 - 2016-10-08
|
||||
|
||||
* Allow to pass nullable Response to delay callable
|
||||
|
@ -329,6 +378,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Fix drain case where content-length is the literal string zero
|
||||
* Obfuscate in-URL credentials in exceptions
|
||||
|
||||
|
||||
## 6.2.1 - 2016-07-18
|
||||
|
||||
* Address HTTP_PROXY security vulnerability, CVE-2016-5385:
|
||||
|
@ -339,6 +389,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
a server does not honor `Connection: close`.
|
||||
* Ignore URI fragment when sending requests.
|
||||
|
||||
|
||||
## 6.2.0 - 2016-03-21
|
||||
|
||||
* Feature: added `GuzzleHttp\json_encode` and `GuzzleHttp\json_decode`.
|
||||
|
@ -358,6 +409,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Bug fix: provide an empty string to `http_build_query` for HHVM workaround.
|
||||
https://github.com/guzzle/guzzle/pull/1367
|
||||
|
||||
|
||||
## 6.1.1 - 2015-11-22
|
||||
|
||||
* Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler
|
||||
|
@ -373,6 +425,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Bug fix: fixed regression where MockHandler was not using `sink`.
|
||||
https://github.com/guzzle/guzzle/pull/1292
|
||||
|
||||
|
||||
## 6.1.0 - 2015-09-08
|
||||
|
||||
* Feature: Added the `on_stats` request option to provide access to transfer
|
||||
|
@ -407,6 +460,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Bug fix: Adding a Content-Length to PHP stream wrapper requests if not set.
|
||||
https://github.com/guzzle/guzzle/pull/1189
|
||||
|
||||
|
||||
## 6.0.2 - 2015-07-04
|
||||
|
||||
* Fixed a memory leak in the curl handlers in which references to callbacks
|
||||
|
@ -424,6 +478,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Functions are now conditionally required using an additional level of
|
||||
indirection to help with global Composer installations.
|
||||
|
||||
|
||||
## 6.0.1 - 2015-05-27
|
||||
|
||||
* Fixed a bug with serializing the `query` request option where the `&`
|
||||
|
@ -432,6 +487,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
use `form_params` or `multipart` instead.
|
||||
* Various doc fixes.
|
||||
|
||||
|
||||
## 6.0.0 - 2015-05-26
|
||||
|
||||
* See the UPGRADING.md document for more information.
|
||||
|
@ -456,6 +512,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* `$maxHandles` has been removed from CurlMultiHandler.
|
||||
* `MultipartPostBody` is now part of the `guzzlehttp/psr7` package.
|
||||
|
||||
|
||||
## 5.3.0 - 2015-05-19
|
||||
|
||||
* Mock now supports `save_to`
|
||||
|
@ -466,6 +523,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated.
|
||||
* URL scheme is now always lowercased.
|
||||
|
||||
|
||||
## 6.0.0-beta.1
|
||||
|
||||
* Requires PHP >= 5.5
|
||||
|
@ -518,6 +576,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* `GuzzleHttp\QueryParser` has been replaced with the
|
||||
`GuzzleHttp\Psr7\parse_query`.
|
||||
|
||||
|
||||
## 5.2.0 - 2015-01-27
|
||||
|
||||
* Added `AppliesHeadersInterface` to make applying headers to a request based
|
||||
|
@ -528,6 +587,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
RingBridge.
|
||||
* Added a guard in the Pool class to not use recursion for request retries.
|
||||
|
||||
|
||||
## 5.1.0 - 2014-12-19
|
||||
|
||||
* Pool class no longer uses recursion when a request is intercepted.
|
||||
|
@ -548,6 +608,7 @@ Please see [the upgrade document](UPGRADING.md) that describes all BC breaking c
|
|||
* Exceptions thrown in the `end` event are now correctly wrapped with Guzzle
|
||||
specific exceptions if necessary.
|
||||
|
||||
|
||||
## 5.0.3 - 2014-11-03
|
||||
|
||||
This change updates query strings so that they are treated as un-encoded values
|
||||
|
@ -562,6 +623,7 @@ string that should not be parsed or encoded (unless a call to getQuery() is
|
|||
subsequently made, forcing the query-string to be converted into a Query
|
||||
object).
|
||||
|
||||
|
||||
## 5.0.2 - 2014-10-30
|
||||
|
||||
* Added a trailing `\r\n` to multipart/form-data payloads. See
|
||||
|
@ -583,6 +645,7 @@ object).
|
|||
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
|
||||
|
||||
|
||||
## 5.0.1 - 2014-10-16
|
||||
|
||||
Bugfix release.
|
||||
|
@ -594,6 +657,7 @@ Bugfix release.
|
|||
* Fixed an issue where transfer statistics were not being populated in the
|
||||
RingBridge. https://github.com/guzzle/guzzle/issues/866
|
||||
|
||||
|
||||
## 5.0.0 - 2014-10-12
|
||||
|
||||
Adding support for non-blocking responses and some minor API cleanup.
|
||||
|
@ -675,6 +739,7 @@ interfaces.
|
|||
argument. They now accept an associative array of options, including the
|
||||
"size" key and "metadata" key which can be used to provide custom metadata.
|
||||
|
||||
|
||||
## 4.2.2 - 2014-09-08
|
||||
|
||||
* Fixed a memory leak in the CurlAdapter when reusing cURL handles.
|
||||
|
|
|
@ -60,13 +60,13 @@ composer require guzzlehttp/guzzle
|
|||
|
||||
## Version Guidance
|
||||
|
||||
| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version |
|
||||
|---------|----------------|---------------------|--------------|---------------------|---------------------|-------|--------------|
|
||||
| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<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 |
|
||||
| 6.x | Security fixes | `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 |
|
||||
| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version |
|
||||
|---------|---------------------|---------------------|--------------|---------------------|---------------------|-------|--------------|
|
||||
| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<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 |
|
||||
| 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 |
|
||||
|
||||
[guzzle-3-repo]: https://github.com/guzzle/guzzle3
|
||||
[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.
|
||||
Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative.
|
||||
- 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`.
|
||||
- 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.
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/promises": "^1.5",
|
||||
"guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
|
||||
"guzzlehttp/promises": "^1.5.3 || ^2.0.1",
|
||||
"guzzlehttp/psr7": "^1.9.1 || ^2.5.1",
|
||||
"psr/http-client": "^1.0",
|
||||
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||
},
|
||||
|
@ -64,7 +64,8 @@
|
|||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
||||
"php-http/client-integration-tests": "^3.0",
|
||||
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
|
||||
"php-http/message-factory": "^1.1",
|
||||
"phpunit/phpunit": "^8.5.29 || ^9.5.23",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
|
|
|
@ -120,13 +120,14 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
public function send(RequestInterface $request, array $options = []): ResponseInterface
|
||||
{
|
||||
$options[RequestOptions::SYNCHRONOUS] = true;
|
||||
|
||||
return $this->sendAsync($request, $options)->wait();
|
||||
}
|
||||
|
||||
/**
|
||||
* The HttpClient PSR (PSR-18) specify this method.
|
||||
*
|
||||
* @inheritDoc
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function sendRequest(RequestInterface $request): ResponseInterface
|
||||
{
|
||||
|
@ -184,6 +185,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
public function request(string $method, $uri = '', array $options = []): ResponseInterface
|
||||
{
|
||||
$options[RequestOptions::SYNCHRONOUS] = true;
|
||||
|
||||
return $this->requestAsync($method, $uri, $options)->wait();
|
||||
}
|
||||
|
||||
|
@ -200,7 +202,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
*
|
||||
* @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
|
||||
? $this->config
|
||||
|
@ -228,11 +230,11 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
{
|
||||
$defaults = [
|
||||
'allow_redirects' => RedirectMiddleware::$defaultSettings,
|
||||
'http_errors' => true,
|
||||
'decode_content' => true,
|
||||
'verify' => true,
|
||||
'cookies' => false,
|
||||
'idn_conversion' => false,
|
||||
'http_errors' => true,
|
||||
'decode_content' => true,
|
||||
'verify' => true,
|
||||
'cookies' => false,
|
||||
'idn_conversion' => false,
|
||||
];
|
||||
|
||||
// Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
|
||||
|
@ -354,10 +356,10 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
if (isset($options['form_params'])) {
|
||||
if (isset($options['multipart'])) {
|
||||
throw new InvalidArgumentException('You cannot use '
|
||||
. 'form_params and multipart at the same time. Use the '
|
||||
. 'form_params option if you want to send application/'
|
||||
. 'x-www-form-urlencoded requests, and the multipart '
|
||||
. 'option to send multipart/form-data requests.');
|
||||
.'form_params and multipart at the same time. Use the '
|
||||
.'form_params option if you want to send application/'
|
||||
.'x-www-form-urlencoded requests, and the multipart '
|
||||
.'option to send multipart/form-data requests.');
|
||||
}
|
||||
$options['body'] = \http_build_query($options['form_params'], '', '&');
|
||||
unset($options['form_params']);
|
||||
|
@ -403,7 +405,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
// Ensure that we don't have the header in different case and set the new value.
|
||||
$modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']);
|
||||
$modify['set_headers']['Authorization'] = 'Basic '
|
||||
. \base64_encode("$value[0]:$value[1]");
|
||||
.\base64_encode("$value[0]:$value[1]");
|
||||
break;
|
||||
case 'digest':
|
||||
// @todo: Do not rely on curl
|
||||
|
@ -447,7 +449,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
// Ensure that we don't have the header in different case and set the new value.
|
||||
$options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
|
||||
$options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
|
||||
. $request->getBody()->getBoundary();
|
||||
.$request->getBody()->getBoundary();
|
||||
}
|
||||
|
||||
// Merge in conditional headers if they are not present.
|
||||
|
@ -473,9 +475,9 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||
private function invalidBody(): InvalidArgumentException
|
||||
{
|
||||
return new InvalidArgumentException('Passing in the "body" request '
|
||||
. 'option as an array to send a request is not supported. '
|
||||
. 'Please use the "form_params" request option to send a '
|
||||
. 'application/x-www-form-urlencoded request, or the "multipart" '
|
||||
. 'request option to send a multipart/form-data request.');
|
||||
.'option as an array to send a request is not supported. '
|
||||
.'Please use the "form_params" request option to send a '
|
||||
.'application/x-www-form-urlencoded request, or the "multipart" '
|
||||
.'request option to send a multipart/form-data request.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,5 +80,5 @@ interface ClientInterface
|
|||
*
|
||||
* @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0.
|
||||
*/
|
||||
public function getConfig(?string $option = null);
|
||||
public function getConfig(string $option = null);
|
||||
}
|
||||
|
|
|
@ -50,10 +50,10 @@ class CookieJar implements CookieJarInterface
|
|||
$cookieJar = new self();
|
||||
foreach ($cookies as $name => $value) {
|
||||
$cookieJar->setCookie(new SetCookie([
|
||||
'Domain' => $domain,
|
||||
'Name' => $name,
|
||||
'Value' => $value,
|
||||
'Discard' => true
|
||||
'Domain' => $domain,
|
||||
'Name' => $name,
|
||||
'Value' => $value,
|
||||
'Discard' => true,
|
||||
]));
|
||||
}
|
||||
|
||||
|
@ -96,9 +96,6 @@ class CookieJar implements CookieJarInterface
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return \array_map(static function (SetCookie $cookie): array {
|
||||
|
@ -106,13 +103,11 @@ class CookieJar implements CookieJarInterface
|
|||
}, $this->getIterator()->getArrayCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
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
|
||||
{
|
||||
if (!$domain) {
|
||||
$this->cookies = [];
|
||||
|
||||
return;
|
||||
} elseif (!$path) {
|
||||
$this->cookies = \array_filter(
|
||||
|
@ -125,25 +120,22 @@ class CookieJar implements CookieJarInterface
|
|||
$this->cookies = \array_filter(
|
||||
$this->cookies,
|
||||
static function (SetCookie $cookie) use ($path, $domain): bool {
|
||||
return !($cookie->matchesPath($path) &&
|
||||
$cookie->matchesDomain($domain));
|
||||
return !($cookie->matchesPath($path)
|
||||
&& $cookie->matchesDomain($domain));
|
||||
}
|
||||
);
|
||||
} else {
|
||||
$this->cookies = \array_filter(
|
||||
$this->cookies,
|
||||
static function (SetCookie $cookie) use ($path, $domain, $name) {
|
||||
return !($cookie->getName() == $name &&
|
||||
$cookie->matchesPath($path) &&
|
||||
$cookie->matchesDomain($domain));
|
||||
return !($cookie->getName() == $name
|
||||
&& $cookie->matchesPath($path)
|
||||
&& $cookie->matchesDomain($domain));
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function clearSessionCookies(): void
|
||||
{
|
||||
$this->cookies = \array_filter(
|
||||
|
@ -154,9 +146,6 @@ class CookieJar implements CookieJarInterface
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setCookie(SetCookie $cookie): bool
|
||||
{
|
||||
// If the name string is empty (but not 0), ignore the set-cookie
|
||||
|
@ -170,9 +159,10 @@ class CookieJar implements CookieJarInterface
|
|||
$result = $cookie->validate();
|
||||
if ($result !== true) {
|
||||
if ($this->strictMode) {
|
||||
throw new \RuntimeException('Invalid cookie: ' . $result);
|
||||
throw new \RuntimeException('Invalid cookie: '.$result);
|
||||
}
|
||||
$this->removeCookieIfEmpty($cookie);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -180,9 +170,9 @@ class CookieJar implements CookieJarInterface
|
|||
foreach ($this->cookies as $i => $c) {
|
||||
// Two cookies are identical, when their path, and domain are
|
||||
// identical.
|
||||
if ($c->getPath() != $cookie->getPath() ||
|
||||
$c->getDomain() != $cookie->getDomain() ||
|
||||
$c->getName() != $cookie->getName()
|
||||
if ($c->getPath() != $cookie->getPath()
|
||||
|| $c->getDomain() != $cookie->getDomain()
|
||||
|| $c->getName() != $cookie->getName()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
@ -253,7 +243,7 @@ class CookieJar implements CookieJarInterface
|
|||
/**
|
||||
* Computes cookie path following RFC 6265 section 5.1.4
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6265#section-5.1.4
|
||||
* @see https://tools.ietf.org/html/rfc6265#section-5.1.4
|
||||
*/
|
||||
private function getCookiePathFromRequest(RequestInterface $request): string
|
||||
{
|
||||
|
@ -284,13 +274,13 @@ class CookieJar implements CookieJarInterface
|
|||
$path = $uri->getPath() ?: '/';
|
||||
|
||||
foreach ($this->cookies as $cookie) {
|
||||
if ($cookie->matchesPath($path) &&
|
||||
$cookie->matchesDomain($host) &&
|
||||
!$cookie->isExpired() &&
|
||||
(!$cookie->getSecure() || $scheme === 'https')
|
||||
if ($cookie->matchesPath($path)
|
||||
&& $cookie->matchesDomain($host)
|
||||
&& !$cookie->isExpired()
|
||||
&& (!$cookie->getSecure() || $scheme === 'https')
|
||||
) {
|
||||
$values[] = $cookie->getName() . '='
|
||||
. $cookie->getValue();
|
||||
$values[] = $cookie->getName().'='
|
||||
.$cookie->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ use Psr\Http\Message\ResponseInterface;
|
|||
* necessary. Subclasses are also responsible for storing and retrieving
|
||||
* cookies from a file, database, etc.
|
||||
*
|
||||
* @link https://docs.python.org/2/library/cookielib.html Inspiration
|
||||
* @see https://docs.python.org/2/library/cookielib.html Inspiration
|
||||
*
|
||||
* @extends \IteratorAggregate<SetCookie>
|
||||
*/
|
||||
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 $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.
|
||||
|
|
|
@ -71,7 +71,7 @@ class SessionCookieJar extends CookieJar
|
|||
$this->setCookie(new SetCookie($cookie));
|
||||
}
|
||||
} elseif (\strlen($data)) {
|
||||
throw new \RuntimeException("Invalid cookie data");
|
||||
throw new \RuntimeException('Invalid cookie data');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,15 +11,15 @@ class SetCookie
|
|||
* @var array
|
||||
*/
|
||||
private static $defaults = [
|
||||
'Name' => null,
|
||||
'Value' => null,
|
||||
'Domain' => null,
|
||||
'Path' => '/',
|
||||
'Max-Age' => null,
|
||||
'Expires' => null,
|
||||
'Secure' => false,
|
||||
'Discard' => false,
|
||||
'HttpOnly' => false
|
||||
'Name' => null,
|
||||
'Value' => null,
|
||||
'Domain' => null,
|
||||
'Path' => '/',
|
||||
'Max-Age' => null,
|
||||
'Expires' => null,
|
||||
'Secure' => false,
|
||||
'Discard' => false,
|
||||
'HttpOnly' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -134,13 +134,13 @@ class SetCookie
|
|||
|
||||
public function __toString()
|
||||
{
|
||||
$str = $this->data['Name'] . '=' . ($this->data['Value'] ?? '') . '; ';
|
||||
$str = $this->data['Name'].'='.($this->data['Value'] ?? '').'; ';
|
||||
foreach ($this->data as $k => $v) {
|
||||
if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) {
|
||||
if ($k === 'Expires') {
|
||||
$str .= 'Expires=' . \gmdate('D, d M Y H:i:s \G\M\T', $v) . '; ';
|
||||
$str .= 'Expires='.\gmdate('D, d M Y H:i:s \G\M\T', $v).'; ';
|
||||
} else {
|
||||
$str .= ($v === true ? $k : "{$k}={$v}") . '; ';
|
||||
$str .= ($v === true ? $k : "{$k}={$v}").'; ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +436,7 @@ class SetCookie
|
|||
return false;
|
||||
}
|
||||
|
||||
return (bool) \preg_match('/\.' . \preg_quote($cookieDomain, '/') . '$/', $domain);
|
||||
return (bool) \preg_match('/\.'.\preg_quote($cookieDomain, '/').'$/', $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -465,8 +465,8 @@ class SetCookie
|
|||
$name
|
||||
)) {
|
||||
return 'Cookie name must not contain invalid characters: ASCII '
|
||||
. 'Control characters (0-31;127), space, tab and the '
|
||||
. 'following characters: ()<>@,;:\"/?={}';
|
||||
.'Control characters (0-31;127), space, tab and the '
|
||||
.'following characters: ()<>@,;:\"/?={}';
|
||||
}
|
||||
|
||||
// Value must not be null. 0 and empty string are valid. Empty strings
|
||||
|
|
|
@ -51,7 +51,7 @@ class CurlFactory implements CurlFactoryInterface
|
|||
unset($options['curl']['body_as_string']);
|
||||
}
|
||||
|
||||
$easy = new EasyHandle;
|
||||
$easy = new EasyHandle();
|
||||
$easy->request = $request;
|
||||
$easy->options = $options;
|
||||
$conf = $this->getDefaultConf($easy);
|
||||
|
@ -161,11 +161,11 @@ class CurlFactory implements CurlFactoryInterface
|
|||
private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface
|
||||
{
|
||||
static $connectionErrors = [
|
||||
\CURLE_OPERATION_TIMEOUTED => true,
|
||||
\CURLE_OPERATION_TIMEOUTED => true,
|
||||
\CURLE_COULDNT_RESOLVE_HOST => true,
|
||||
\CURLE_COULDNT_CONNECT => true,
|
||||
\CURLE_SSL_CONNECT_ERROR => true,
|
||||
\CURLE_GOT_NOTHING => true,
|
||||
\CURLE_COULDNT_CONNECT => true,
|
||||
\CURLE_SSL_CONNECT_ERROR => true,
|
||||
\CURLE_GOT_NOTHING => true,
|
||||
];
|
||||
|
||||
if ($easy->createResponseException) {
|
||||
|
@ -219,11 +219,11 @@ class CurlFactory implements CurlFactoryInterface
|
|||
private function getDefaultConf(EasyHandle $easy): array
|
||||
{
|
||||
$conf = [
|
||||
'_headers' => $easy->request->getHeaders(),
|
||||
\CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
|
||||
\CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
|
||||
'_headers' => $easy->request->getHeaders(),
|
||||
\CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
|
||||
\CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
|
||||
\CURLOPT_RETURNTRANSFER => false,
|
||||
\CURLOPT_HEADER => false,
|
||||
\CURLOPT_HEADER => false,
|
||||
\CURLOPT_CONNECTTIMEOUT => 300,
|
||||
];
|
||||
|
||||
|
@ -250,6 +250,7 @@ class CurlFactory implements CurlFactoryInterface
|
|||
|
||||
if ($size === null || $size > 0) {
|
||||
$this->applyBody($easy->request, $easy->options, $conf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -341,6 +342,7 @@ class CurlFactory implements CurlFactoryInterface
|
|||
foreach (\array_keys($options['_headers']) as $key) {
|
||||
if (!\strcasecmp($key, $name)) {
|
||||
unset($options['_headers'][$key]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -365,11 +367,11 @@ class CurlFactory implements CurlFactoryInterface
|
|||
// 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 (
|
||||
\is_dir($options['verify']) ||
|
||||
(
|
||||
\is_link($options['verify']) === true &&
|
||||
($verifyLink = \readlink($options['verify'])) !== false &&
|
||||
\is_dir($verifyLink)
|
||||
\is_dir($options['verify'])
|
||||
|| (
|
||||
\is_link($options['verify']) === true
|
||||
&& ($verifyLink = \readlink($options['verify'])) !== false
|
||||
&& \is_dir($verifyLink)
|
||||
)
|
||||
) {
|
||||
$conf[\CURLOPT_CAPATH] = $options['verify'];
|
||||
|
@ -487,8 +489,8 @@ class CurlFactory implements CurlFactoryInterface
|
|||
if (!\file_exists($cert)) {
|
||||
throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
|
||||
}
|
||||
# OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
|
||||
# see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
|
||||
// OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
|
||||
// see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
|
||||
$ext = pathinfo($cert, \PATHINFO_EXTENSION);
|
||||
if (preg_match('#^(der|p12)$#i', $ext)) {
|
||||
$conf[\CURLOPT_SSLCERTTYPE] = strtoupper($ext);
|
||||
|
@ -551,9 +553,10 @@ class CurlFactory implements CurlFactoryInterface
|
|||
}
|
||||
} catch (\RuntimeException $e) {
|
||||
$ctx['error'] = 'The connection unexpectedly failed without '
|
||||
. 'providing an error. The request would have been retried, '
|
||||
. 'but attempting to rewind the request body failed. '
|
||||
. 'Exception: ' . $e;
|
||||
.'providing an error. The request would have been retried, '
|
||||
.'but attempting to rewind the request body failed. '
|
||||
.'Exception: '.$e;
|
||||
|
||||
return self::createRejection($easy, $ctx);
|
||||
}
|
||||
|
||||
|
@ -562,14 +565,15 @@ class CurlFactory implements CurlFactoryInterface
|
|||
$easy->options['_curl_retries'] = 1;
|
||||
} elseif ($easy->options['_curl_retries'] == 2) {
|
||||
$ctx['error'] = 'The cURL request was retried 3 times '
|
||||
. 'and did not succeed. The most likely reason for the failure '
|
||||
. 'is that cURL was unable to rewind the body of the request '
|
||||
. 'and subsequent retries resulted in the same error. Turn on '
|
||||
. 'the debug option to see what went wrong. See '
|
||||
. 'https://bugs.php.net/bug.php?id=47204 for more information.';
|
||||
.'and did not succeed. The most likely reason for the failure '
|
||||
.'is that cURL was unable to rewind the body of the request '
|
||||
.'and subsequent retries resulted in the same error. Turn on '
|
||||
.'the debug option to see what went wrong. See '
|
||||
.'https://bugs.php.net/bug.php?id=47204 for more information.';
|
||||
|
||||
return self::createRejection($easy, $ctx);
|
||||
} else {
|
||||
$easy->options['_curl_retries']++;
|
||||
++$easy->options['_curl_retries'];
|
||||
}
|
||||
|
||||
return $handler($easy->request, $easy->options);
|
||||
|
@ -599,6 +603,7 @@ class CurlFactory implements CurlFactoryInterface
|
|||
$easy->createResponse();
|
||||
} catch (\Exception $e) {
|
||||
$easy->createResponseException = $e;
|
||||
|
||||
return -1;
|
||||
}
|
||||
if ($onHeaders !== null) {
|
||||
|
@ -608,6 +613,7 @@ class CurlFactory implements CurlFactoryInterface
|
|||
// Associate the exception with the handle and trigger
|
||||
// a curl header write error by returning 0.
|
||||
$easy->onHeadersException = $e;
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -617,7 +623,16 @@ class CurlFactory implements CurlFactoryInterface
|
|||
} else {
|
||||
$easy->headers[] = $value;
|
||||
}
|
||||
|
||||
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
|
||||
* **curl** key of the provided request options.
|
||||
*
|
||||
* @property resource|\CurlMultiHandle $_mh Internal use only. Lazy loaded multi-handle.
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
#[\AllowDynamicProperties]
|
||||
class CurlMultiHandler
|
||||
{
|
||||
/**
|
||||
|
@ -56,6 +53,9 @@ class CurlMultiHandler
|
|||
*/
|
||||
private $options = [];
|
||||
|
||||
/** @var resource|\CurlMultiHandle */
|
||||
private $_mh;
|
||||
|
||||
/**
|
||||
* This handler accepts the following options:
|
||||
*
|
||||
|
@ -79,6 +79,10 @@ class CurlMultiHandler
|
|||
}
|
||||
|
||||
$this->options = $options['options'] ?? [];
|
||||
|
||||
// unsetting the property forces the first access to go through
|
||||
// __get().
|
||||
unset($this->_mh);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,7 +168,8 @@ class CurlMultiHandler
|
|||
\usleep(250);
|
||||
}
|
||||
|
||||
while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM);
|
||||
while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
|
||||
}
|
||||
|
||||
$this->processMessages();
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ final class EasyHandle
|
|||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: ' . $name;
|
||||
$msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: '.$name;
|
||||
throw new \BadMethodCallException($msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ final class HeaderProcessor
|
|||
*
|
||||
* @param string[] $headers
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return array{0:string, 1:int, 2:?string, 3:array}
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public static function parseHeaders(array $headers): array
|
||||
{
|
||||
|
|
|
@ -138,6 +138,7 @@ class MockHandler implements \Countable
|
|||
if ($this->onRejected) {
|
||||
($this->onRejected)($reason);
|
||||
}
|
||||
|
||||
return P\Create::rejectionFor($reason);
|
||||
}
|
||||
);
|
||||
|
@ -159,7 +160,7 @@ class MockHandler implements \Countable
|
|||
) {
|
||||
$this->queue[] = $value;
|
||||
} else {
|
||||
throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found ' . Utils::describeType($value));
|
||||
throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found '.Utils::describeType($value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ class StreamHandler
|
|||
if (false !== \strpos($message, 'getaddrinfo') // DNS lookup failed
|
||||
|| false !== \strpos($message, 'Connection refused')
|
||||
|| false !== \strpos($message, "couldn't connect to host") // error on HHVM
|
||||
|| false !== \strpos($message, "connection attempt failed")
|
||||
|| false !== \strpos($message, 'connection attempt failed')
|
||||
) {
|
||||
$e = new ConnectException($e->getMessage(), $request, $e);
|
||||
} else {
|
||||
|
@ -231,9 +231,10 @@ class StreamHandler
|
|||
\set_error_handler(static function ($_, $msg, $file, $line) use (&$errors): bool {
|
||||
$errors[] = [
|
||||
'message' => $msg,
|
||||
'file' => $file,
|
||||
'line' => $line
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
];
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -247,7 +248,7 @@ class StreamHandler
|
|||
$message = 'Error creating resource: ';
|
||||
foreach ($errors as $err) {
|
||||
foreach ($err as $key => $value) {
|
||||
$message .= "[$key] $value" . \PHP_EOL;
|
||||
$message .= "[$key] $value".\PHP_EOL;
|
||||
}
|
||||
}
|
||||
throw new \RuntimeException(\trim($message));
|
||||
|
@ -350,6 +351,7 @@ class StreamHandler
|
|||
if (false === $records || !isset($records[0]['ip'])) {
|
||||
throw new ConnectException(\sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
|
||||
}
|
||||
|
||||
return $uri->withHost($records[0]['ip']);
|
||||
}
|
||||
if ('v6' === $options['force_ip_resolve']) {
|
||||
|
@ -357,7 +359,8 @@ class StreamHandler
|
|||
if (false === $records || !isset($records[0]['ipv6'])) {
|
||||
throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
|
||||
}
|
||||
return $uri->withHost('[' . $records[0]['ipv6'] . ']');
|
||||
|
||||
return $uri->withHost('['.$records[0]['ipv6'].']');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,11 +378,11 @@ class StreamHandler
|
|||
|
||||
$context = [
|
||||
'http' => [
|
||||
'method' => $request->getMethod(),
|
||||
'header' => $headers,
|
||||
'method' => $request->getMethod(),
|
||||
'header' => $headers,
|
||||
'protocol_version' => $request->getProtocolVersion(),
|
||||
'ignore_errors' => true,
|
||||
'follow_location' => 0,
|
||||
'ignore_errors' => true,
|
||||
'follow_location' => 0,
|
||||
],
|
||||
'ssl' => [
|
||||
'peer_name' => $request->getUri()->getHost(),
|
||||
|
@ -561,27 +564,27 @@ class StreamHandler
|
|||
}
|
||||
|
||||
static $map = [
|
||||
\STREAM_NOTIFY_CONNECT => 'CONNECT',
|
||||
\STREAM_NOTIFY_CONNECT => 'CONNECT',
|
||||
\STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED',
|
||||
\STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
|
||||
\STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
|
||||
\STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
|
||||
\STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
|
||||
\STREAM_NOTIFY_PROGRESS => 'PROGRESS',
|
||||
\STREAM_NOTIFY_FAILURE => 'FAILURE',
|
||||
\STREAM_NOTIFY_COMPLETED => 'COMPLETED',
|
||||
\STREAM_NOTIFY_RESOLVE => 'RESOLVE',
|
||||
\STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
|
||||
\STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
|
||||
\STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
|
||||
\STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
|
||||
\STREAM_NOTIFY_PROGRESS => 'PROGRESS',
|
||||
\STREAM_NOTIFY_FAILURE => 'FAILURE',
|
||||
\STREAM_NOTIFY_COMPLETED => 'COMPLETED',
|
||||
\STREAM_NOTIFY_RESOLVE => 'RESOLVE',
|
||||
];
|
||||
static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max'];
|
||||
|
||||
$value = Utils::debugResource($value);
|
||||
$ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
|
||||
$ident = $request->getMethod().' '.$request->getUri()->withFragment('');
|
||||
self::addNotification(
|
||||
$params,
|
||||
static function (int $code, ...$passed) use ($ident, $value, $map, $args): void {
|
||||
\fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
|
||||
foreach (\array_filter($passed) as $i => $v) {
|
||||
\fwrite($value, $args[$i] . ': "' . $v . '" ');
|
||||
\fwrite($value, $args[$i].': "'.$v.'" ');
|
||||
}
|
||||
\fwrite($value, "\n");
|
||||
}
|
||||
|
@ -596,7 +599,7 @@ class StreamHandler
|
|||
} else {
|
||||
$params['notification'] = self::callArray([
|
||||
$params['notification'],
|
||||
$notify
|
||||
$notify,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ class HandlerStack
|
|||
* handler is provided, the best handler for your
|
||||
* 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->push(Middleware::httpErrors(), 'http_errors');
|
||||
|
@ -86,14 +86,14 @@ class HandlerStack
|
|||
$stack = [];
|
||||
|
||||
if ($this->handler !== null) {
|
||||
$stack[] = "0) Handler: " . $this->debugCallable($this->handler);
|
||||
$stack[] = '0) Handler: '.$this->debugCallable($this->handler);
|
||||
}
|
||||
|
||||
$result = '';
|
||||
foreach (\array_reverse($this->stack) as $tuple) {
|
||||
$depth++;
|
||||
++$depth;
|
||||
$str = "{$depth}) Name: '{$tuple[1]}', ";
|
||||
$str .= "Function: " . $this->debugCallable($tuple[0]);
|
||||
$str .= 'Function: '.$this->debugCallable($tuple[0]);
|
||||
$result = "> {$str}\n{$result}";
|
||||
$stack[] = $str;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ class HandlerStack
|
|||
*/
|
||||
public function hasHandler(): bool
|
||||
{
|
||||
return $this->handler !== null ;
|
||||
return $this->handler !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,7 +131,7 @@ class HandlerStack
|
|||
* @param callable(callable): callable $middleware Middleware function
|
||||
* @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]);
|
||||
$this->cached = null;
|
||||
|
@ -266,10 +266,10 @@ class HandlerStack
|
|||
if (\is_array($fn)) {
|
||||
return \is_string($fn[0])
|
||||
? "callable({$fn[0]}::{$fn[1]})"
|
||||
: "callable(['" . \get_class($fn[0]) . "', '{$fn[1]}'])";
|
||||
: "callable(['".\get_class($fn[0])."', '{$fn[1]}'])";
|
||||
}
|
||||
|
||||
/** @var object $fn */
|
||||
return 'callable(' . \spl_object_hash($fn) . ')';
|
||||
return 'callable('.\spl_object_hash($fn).')';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,11 +40,11 @@ class MessageFormatter implements MessageFormatterInterface
|
|||
/**
|
||||
* Apache Common Log Format.
|
||||
*
|
||||
* @link https://httpd.apache.org/docs/2.4/logs.html#common
|
||||
* @see https://httpd.apache.org/docs/2.4/logs.html#common
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}";
|
||||
public const CLF = '{hostname} {req_header_User-Agent} - [{date_common_log}] "{method} {target} HTTP/{version}" {code} {res_header_Content-Length}';
|
||||
public const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
|
||||
public const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
|
||||
|
||||
|
@ -68,7 +68,7 @@ class MessageFormatter implements MessageFormatterInterface
|
|||
* @param ResponseInterface|null $response Response 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 = [];
|
||||
|
||||
|
@ -90,9 +90,9 @@ class MessageFormatter implements MessageFormatterInterface
|
|||
break;
|
||||
case 'req_headers':
|
||||
$result = \trim($request->getMethod()
|
||||
. ' ' . $request->getRequestTarget())
|
||||
. ' HTTP/' . $request->getProtocolVersion() . "\r\n"
|
||||
. $this->headers($request);
|
||||
.' '.$request->getRequestTarget())
|
||||
.' HTTP/'.$request->getProtocolVersion()."\r\n"
|
||||
.$this->headers($request);
|
||||
break;
|
||||
case 'res_headers':
|
||||
$result = $response ?
|
||||
|
@ -101,7 +101,7 @@ class MessageFormatter implements MessageFormatterInterface
|
|||
$response->getProtocolVersion(),
|
||||
$response->getStatusCode(),
|
||||
$response->getReasonPhrase()
|
||||
) . "\r\n" . $this->headers($response)
|
||||
)."\r\n".$this->headers($response)
|
||||
: 'NULL';
|
||||
break;
|
||||
case 'req_body':
|
||||
|
@ -177,6 +177,7 @@ class MessageFormatter implements MessageFormatterInterface
|
|||
}
|
||||
|
||||
$cache[$matches[1]] = $result;
|
||||
|
||||
return $result;
|
||||
},
|
||||
$this->template
|
||||
|
@ -190,7 +191,7 @@ class MessageFormatter implements MessageFormatterInterface
|
|||
{
|
||||
$result = '';
|
||||
foreach ($message->getHeaders() as $name => $values) {
|
||||
$result .= $name . ': ' . \implode(', ', $values) . "\r\n";
|
||||
$result .= $name.': '.\implode(', ', $values)."\r\n";
|
||||
}
|
||||
|
||||
return \trim($result);
|
||||
|
|
|
@ -14,5 +14,5 @@ interface MessageFormatterInterface
|
|||
* @param ResponseInterface|null $response Response 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;
|
||||
}
|
||||
|
|
|
@ -34,10 +34,12 @@ final class Middleware
|
|||
}
|
||||
$cookieJar = $options['cookies'];
|
||||
$request = $cookieJar->withCookieHeader($request);
|
||||
|
||||
return $handler($request, $options)
|
||||
->then(
|
||||
static function (ResponseInterface $response) use ($cookieJar, $request): ResponseInterface {
|
||||
$cookieJar->extractCookies($request, $response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
);
|
||||
|
@ -60,6 +62,7 @@ final class Middleware
|
|||
if (empty($options['http_errors'])) {
|
||||
return $handler($request, $options);
|
||||
}
|
||||
|
||||
return $handler($request, $options)->then(
|
||||
static function (ResponseInterface $response) use ($request, $bodySummarizer) {
|
||||
$code = $response->getStatusCode();
|
||||
|
@ -93,20 +96,22 @@ final class Middleware
|
|||
return $handler($request, $options)->then(
|
||||
static function ($value) use ($request, &$container, $options) {
|
||||
$container[] = [
|
||||
'request' => $request,
|
||||
'request' => $request,
|
||||
'response' => $value,
|
||||
'error' => null,
|
||||
'options' => $options
|
||||
'error' => null,
|
||||
'options' => $options,
|
||||
];
|
||||
|
||||
return $value;
|
||||
},
|
||||
static function ($reason) use ($request, &$container, $options) {
|
||||
$container[] = [
|
||||
'request' => $request,
|
||||
'request' => $request,
|
||||
'response' => null,
|
||||
'error' => $reason,
|
||||
'options' => $options
|
||||
'error' => $reason,
|
||||
'options' => $options,
|
||||
];
|
||||
|
||||
return P\Create::rejectionFor($reason);
|
||||
}
|
||||
);
|
||||
|
@ -138,6 +143,7 @@ final class Middleware
|
|||
if ($after) {
|
||||
$after($request, $options, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
};
|
||||
};
|
||||
|
@ -202,12 +208,14 @@ final class Middleware
|
|||
static function ($response) use ($logger, $request, $formatter, $logLevel): ResponseInterface {
|
||||
$message = $formatter->format($request, $response);
|
||||
$logger->log($logLevel, $message);
|
||||
|
||||
return $response;
|
||||
},
|
||||
static function ($reason) use ($logger, $request, $formatter): PromiseInterface {
|
||||
$response = $reason instanceof RequestException ? $reason->getResponse() : null;
|
||||
$message = $formatter->format($request, $response, P\Create::exceptionFor($reason));
|
||||
$logger->error($message);
|
||||
|
||||
return P\Create::rejectionFor($reason);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -84,6 +84,7 @@ class PrepareBodyMiddleware
|
|||
// The expect header is unconditionally enabled
|
||||
if ($expect === true) {
|
||||
$modify['set_headers']['Expect'] = '100-Continue';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ class RedirectMiddleware
|
|||
* @var array
|
||||
*/
|
||||
public static $defaultSettings = [
|
||||
'max' => 5,
|
||||
'protocols' => ['http', 'https'],
|
||||
'strict' => false,
|
||||
'referer' => false,
|
||||
'max' => 5,
|
||||
'protocols' => ['http', 'https'],
|
||||
'strict' => false,
|
||||
'referer' => false,
|
||||
'track_redirects' => false,
|
||||
];
|
||||
|
||||
|
@ -166,8 +166,8 @@ class RedirectMiddleware
|
|||
// not forcing RFC compliance, but rather emulating what all browsers
|
||||
// would do.
|
||||
$statusCode = $response->getStatusCode();
|
||||
if ($statusCode == 303 ||
|
||||
($statusCode <= 302 && !$options['allow_redirects']['strict'])
|
||||
if ($statusCode == 303
|
||||
|| ($statusCode <= 302 && !$options['allow_redirects']['strict'])
|
||||
) {
|
||||
$safeMethods = ['GET', 'HEAD', 'OPTIONS'];
|
||||
$requestMethod = $request->getMethod();
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace GuzzleHttp;
|
|||
*
|
||||
* More documentation for each option can be found at http://guzzlephp.org/.
|
||||
*
|
||||
* @link http://docs.guzzlephp.org/en/v6/request-options.html
|
||||
* @see http://docs.guzzlephp.org/en/v6/request-options.html
|
||||
*/
|
||||
final class RequestOptions
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ class RetryMiddleware
|
|||
{
|
||||
$this->decider = $decider;
|
||||
$this->nextHandler = $nextHandler;
|
||||
$this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
|
||||
$this->delay = $delay ?: __CLASS__.'::exponentialDelay';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@ class RetryMiddleware
|
|||
*/
|
||||
public static function exponentialDelay(int $retries): int
|
||||
{
|
||||
return (int) \pow(2, $retries - 1) * 1000;
|
||||
return (int) 2 ** ($retries - 1) * 1000;
|
||||
}
|
||||
|
||||
public function __invoke(RequestInterface $request, array $options): PromiseInterface
|
||||
|
@ -64,6 +64,7 @@ class RetryMiddleware
|
|||
}
|
||||
|
||||
$fn = $this->nextHandler;
|
||||
|
||||
return $fn($request, $options)
|
||||
->then(
|
||||
$this->onFulfilled($request, $options),
|
||||
|
@ -85,6 +86,7 @@ class RetryMiddleware
|
|||
)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $this->doRetry($request, $options, $value);
|
||||
};
|
||||
}
|
||||
|
@ -103,6 +105,7 @@ class RetryMiddleware
|
|||
)) {
|
||||
return P\Create::rejectionFor($reason);
|
||||
}
|
||||
|
||||
return $this->doRetry($req, $options);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ final class TransferStats
|
|||
*/
|
||||
public function __construct(
|
||||
RequestInterface $request,
|
||||
?ResponseInterface $response = null,
|
||||
?float $transferTime = null,
|
||||
ResponseInterface $response = null,
|
||||
float $transferTime = null,
|
||||
$handlerErrorData = null,
|
||||
array $handlerStats = []
|
||||
) {
|
||||
|
|
|
@ -23,9 +23,9 @@ final class Utils
|
|||
{
|
||||
switch (\gettype($input)) {
|
||||
case 'object':
|
||||
return 'object(' . \get_class($input) . ')';
|
||||
return 'object('.\get_class($input).')';
|
||||
case 'array':
|
||||
return 'array(' . \count($input) . ')';
|
||||
return 'array('.\count($input).')';
|
||||
default:
|
||||
\ob_start();
|
||||
\var_dump($input);
|
||||
|
@ -79,9 +79,9 @@ final class Utils
|
|||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*/
|
||||
public static function chooseHandler(): callable
|
||||
{
|
||||
|
@ -247,8 +247,8 @@ EOT
|
|||
}
|
||||
// Special match if the area when prefixed with ".". Remove any
|
||||
// existing leading "." and add a new leading ".".
|
||||
$area = '.' . \ltrim($area, '.');
|
||||
if (\substr($host, -(\strlen($area))) === $area) {
|
||||
$area = '.'.\ltrim($area, '.');
|
||||
if (\substr($host, -\strlen($area)) === $area) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -269,13 +269,13 @@ EOT
|
|||
*
|
||||
* @throws InvalidArgumentException if the JSON cannot be decoded.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/function.json-decode.php
|
||||
* @see https://www.php.net/manual/en/function.json-decode.php
|
||||
*/
|
||||
public static function jsonDecode(string $json, bool $assoc = false, int $depth = 512, int $options = 0)
|
||||
{
|
||||
$data = \json_decode($json, $assoc, $depth, $options);
|
||||
if (\JSON_ERROR_NONE !== \json_last_error()) {
|
||||
throw new InvalidArgumentException('json_decode error: ' . \json_last_error_msg());
|
||||
throw new InvalidArgumentException('json_decode error: '.\json_last_error_msg());
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
@ -290,13 +290,13 @@ EOT
|
|||
*
|
||||
* @throws InvalidArgumentException if the JSON cannot be encoded.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/function.json-encode.php
|
||||
* @see https://www.php.net/manual/en/function.json-encode.php
|
||||
*/
|
||||
public static function jsonEncode($value, int $options = 0, int $depth = 512): string
|
||||
{
|
||||
$json = \json_encode($value, $options, $depth);
|
||||
if (\JSON_ERROR_NONE !== \json_last_error()) {
|
||||
throw new InvalidArgumentException('json_encode error: ' . \json_last_error_msg());
|
||||
throw new InvalidArgumentException('json_encode error: '.\json_last_error_msg());
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
|
@ -341,7 +341,7 @@ EOT
|
|||
|
||||
$errorMessage = 'IDN conversion failed';
|
||||
if ($errors) {
|
||||
$errorMessage .= ' (errors: ' . implode(', ', $errors) . ')';
|
||||
$errorMessage .= ' (errors: '.implode(', ', $errors).')';
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException($errorMessage);
|
||||
|
|
|
@ -50,10 +50,10 @@ function debug_resource($value = null)
|
|||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*
|
||||
* @deprecated choose_handler will be removed in guzzlehttp/guzzle:8.0. Use Utils::chooseHandler instead.
|
||||
*/
|
||||
function choose_handler(): callable
|
||||
|
@ -141,7 +141,7 @@ function is_host_in_noproxy(string $host, array $noProxyArray): bool
|
|||
*
|
||||
* @throws Exception\InvalidArgumentException if the JSON cannot be decoded.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/function.json-decode.php
|
||||
* @see https://www.php.net/manual/en/function.json-decode.php
|
||||
* @deprecated json_decode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonDecode instead.
|
||||
*/
|
||||
function json_decode(string $json, bool $assoc = false, int $depth = 512, int $options = 0)
|
||||
|
@ -158,7 +158,7 @@ function json_decode(string $json, bool $assoc = false, int $depth = 512, int $o
|
|||
*
|
||||
* @throws Exception\InvalidArgumentException if the JSON cannot be encoded.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/function.json-encode.php
|
||||
* @see https://www.php.net/manual/en/function.json-encode.php
|
||||
* @deprecated json_encode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonEncode instead.
|
||||
*/
|
||||
function json_encode($value, int $options = 0, int $depth = 512): string
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
// Don't redefine the functions if included multiple times.
|
||||
if (!\function_exists('GuzzleHttp\describe_type')) {
|
||||
require __DIR__ . '/functions.php';
|
||||
require __DIR__.'/functions.php';
|
||||
}
|
||||
|
|
|
@ -1,11 +1,43 @@
|
|||
# CHANGELOG
|
||||
|
||||
|
||||
## 2.0.1 - 2023-08-03
|
||||
|
||||
### Changed
|
||||
|
||||
- PHP 8.3 support
|
||||
|
||||
|
||||
## 2.0.0 - 2023-05-21
|
||||
|
||||
### Added
|
||||
|
||||
- Added PHP 7 type hints
|
||||
|
||||
### Changed
|
||||
|
||||
- All previously non-final non-exception classes have been marked as soft-final
|
||||
|
||||
### Removed
|
||||
|
||||
- Dropped PHP < 7.2 support
|
||||
- All functions in the `GuzzleHttp\Promise` namespace
|
||||
|
||||
|
||||
## 1.5.3 - 2023-05-21
|
||||
|
||||
### Changed
|
||||
|
||||
- Removed remaining usage of deprecated functions
|
||||
|
||||
|
||||
## 1.5.2 - 2022-08-07
|
||||
|
||||
### Changed
|
||||
|
||||
- Officially support PHP 8.2
|
||||
|
||||
|
||||
## 1.5.1 - 2021-10-22
|
||||
|
||||
### Fixed
|
||||
|
@ -13,6 +45,7 @@
|
|||
- Revert "Call handler when waiting on fulfilled/rejected Promise"
|
||||
- Fix pool memory leak when empty array of promises provided
|
||||
|
||||
|
||||
## 1.5.0 - 2021-10-07
|
||||
|
||||
### Changed
|
||||
|
@ -24,12 +57,14 @@
|
|||
|
||||
- Fix manually settle promises generated with `Utils::task`
|
||||
|
||||
|
||||
## 1.4.1 - 2021-02-18
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `each_limit` skipping promises and failing
|
||||
|
||||
|
||||
## 1.4.0 - 2020-09-30
|
||||
|
||||
### Added
|
||||
|
|
|
@ -29,6 +29,21 @@ for a general introduction to promises.
|
|||
`GuzzleHttp\Promise\Coroutine::of()`.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```shell
|
||||
composer require guzzlehttp/promises
|
||||
```
|
||||
|
||||
|
||||
## Version Guidance
|
||||
|
||||
| Version | Status | PHP Version |
|
||||
|---------|------------------------|--------------|
|
||||
| 1.x | Bug and security fixes | >=5.5,<8.3 |
|
||||
| 2.x | Latest | >=7.2.5,<8.4 |
|
||||
|
||||
|
||||
## Quick Start
|
||||
|
||||
A *promise* represents the eventual result of an asynchronous operation. The
|
||||
|
@ -430,8 +445,6 @@ $loop = React\EventLoop\Factory::create();
|
|||
$loop->addPeriodicTimer(0, [$queue, 'run']);
|
||||
```
|
||||
|
||||
*TODO*: Perhaps adding a `futureTick()` on each tick would be faster?
|
||||
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
|
@ -501,8 +514,8 @@ $promise->resolve('foo');
|
|||
|
||||
A static API was first introduced in 1.4.0, in order to mitigate problems with
|
||||
functions conflicting between global and local copies of the package. The
|
||||
function API will be removed in 2.0.0. A migration table has been provided here
|
||||
for your convenience:
|
||||
function API was removed in 2.0.0. A migration table has been provided here for
|
||||
your convenience:
|
||||
|
||||
| Original Function | Replacement Method |
|
||||
|----------------|----------------|
|
||||
|
|
|
@ -26,32 +26,32 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5"
|
||||
"php": "^7.2.5 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.4 || ^5.1"
|
||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
||||
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Promise\\": "src/"
|
||||
},
|
||||
"files": ["src/functions_include.php"]
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Promise\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/simple-phpunit",
|
||||
"test-ci": "vendor/bin/simple-phpunit --coverage-text"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.5-dev"
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"bamarni/composer-bin-plugin": true
|
||||
},
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
/**
|
||||
|
@ -7,7 +9,7 @@ namespace GuzzleHttp\Promise;
|
|||
*/
|
||||
class AggregateException extends RejectionException
|
||||
{
|
||||
public function __construct($msg, array $reasons)
|
||||
public function __construct(string $msg, array $reasons)
|
||||
{
|
||||
parent::__construct(
|
||||
$reasons,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
use Exception;
|
||||
use Generator;
|
||||
use Throwable;
|
||||
|
||||
|
@ -27,7 +28,7 @@ use Throwable;
|
|||
* $value = (yield createPromise('a'));
|
||||
* try {
|
||||
* $value = (yield createPromise($value . 'b'));
|
||||
* } catch (\Exception $e) {
|
||||
* } catch (\Throwable $e) {
|
||||
* // The promise was rejected.
|
||||
* }
|
||||
* yield $value . 'c';
|
||||
|
@ -40,7 +41,7 @@ use Throwable;
|
|||
*
|
||||
* @return Promise
|
||||
*
|
||||
* @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
|
||||
* @see https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
|
||||
*/
|
||||
final class Coroutine implements PromiseInterface
|
||||
{
|
||||
|
@ -62,15 +63,13 @@ final class Coroutine implements PromiseInterface
|
|||
public function __construct(callable $generatorFn)
|
||||
{
|
||||
$this->generator = $generatorFn();
|
||||
$this->result = new Promise(function () {
|
||||
$this->result = new Promise(function (): void {
|
||||
while (isset($this->currentPromise)) {
|
||||
$this->currentPromise->wait();
|
||||
}
|
||||
});
|
||||
try {
|
||||
$this->nextCoroutine($this->generator->current());
|
||||
} catch (\Exception $exception) {
|
||||
$this->result->reject($exception);
|
||||
} catch (Throwable $throwable) {
|
||||
$this->result->reject($throwable);
|
||||
}
|
||||
|
@ -78,10 +77,8 @@ final class Coroutine implements PromiseInterface
|
|||
|
||||
/**
|
||||
* Create a new coroutine.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function of(callable $generatorFn)
|
||||
public static function of(callable $generatorFn): self
|
||||
{
|
||||
return new self($generatorFn);
|
||||
}
|
||||
|
@ -89,42 +86,42 @@ final class Coroutine implements PromiseInterface
|
|||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
) {
|
||||
): PromiseInterface {
|
||||
return $this->result->then($onFulfilled, $onRejected);
|
||||
}
|
||||
|
||||
public function otherwise(callable $onRejected)
|
||||
public function otherwise(callable $onRejected): PromiseInterface
|
||||
{
|
||||
return $this->result->otherwise($onRejected);
|
||||
}
|
||||
|
||||
public function wait($unwrap = true)
|
||||
public function wait(bool $unwrap = true)
|
||||
{
|
||||
return $this->result->wait($unwrap);
|
||||
}
|
||||
|
||||
public function getState()
|
||||
public function getState(): string
|
||||
{
|
||||
return $this->result->getState();
|
||||
}
|
||||
|
||||
public function resolve($value)
|
||||
public function resolve($value): void
|
||||
{
|
||||
$this->result->resolve($value);
|
||||
}
|
||||
|
||||
public function reject($reason)
|
||||
public function reject($reason): void
|
||||
{
|
||||
$this->result->reject($reason);
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
public function cancel(): void
|
||||
{
|
||||
$this->currentPromise->cancel();
|
||||
$this->result->cancel();
|
||||
}
|
||||
|
||||
private function nextCoroutine($yielded)
|
||||
private function nextCoroutine($yielded): void
|
||||
{
|
||||
$this->currentPromise = Create::promiseFor($yielded)
|
||||
->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
|
||||
|
@ -133,7 +130,7 @@ final class Coroutine implements PromiseInterface
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function _handleSuccess($value)
|
||||
public function _handleSuccess($value): void
|
||||
{
|
||||
unset($this->currentPromise);
|
||||
try {
|
||||
|
@ -143,8 +140,6 @@ final class Coroutine implements PromiseInterface
|
|||
} else {
|
||||
$this->result->resolve($value);
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
$this->result->reject($exception);
|
||||
} catch (Throwable $throwable) {
|
||||
$this->result->reject($throwable);
|
||||
}
|
||||
|
@ -153,15 +148,13 @@ final class Coroutine implements PromiseInterface
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function _handleFailure($reason)
|
||||
public function _handleFailure($reason): void
|
||||
{
|
||||
unset($this->currentPromise);
|
||||
try {
|
||||
$nextYield = $this->generator->throw(Create::exceptionFor($reason));
|
||||
// The throw was caught, so keep iterating on the coroutine
|
||||
$this->nextCoroutine($nextYield);
|
||||
} catch (Exception $exception) {
|
||||
$this->result->reject($exception);
|
||||
} catch (Throwable $throwable) {
|
||||
$this->result->reject($throwable);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
final class Create
|
||||
|
@ -8,10 +10,8 @@ final class Create
|
|||
* Creates a promise for a value if the value is not a promise.
|
||||
*
|
||||
* @param mixed $value Promise or value.
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public static function promiseFor($value)
|
||||
public static function promiseFor($value): PromiseInterface
|
||||
{
|
||||
if ($value instanceof PromiseInterface) {
|
||||
return $value;
|
||||
|
@ -23,6 +23,7 @@ final class Create
|
|||
$cfn = method_exists($value, 'cancel') ? [$value, 'cancel'] : null;
|
||||
$promise = new Promise($wfn, $cfn);
|
||||
$value->then([$promise, 'resolve'], [$promise, 'reject']);
|
||||
|
||||
return $promise;
|
||||
}
|
||||
|
||||
|
@ -34,10 +35,8 @@ final class Create
|
|||
* If the provided reason is a promise, then it is returned as-is.
|
||||
*
|
||||
* @param mixed $reason Promise or reason.
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public static function rejectionFor($reason)
|
||||
public static function rejectionFor($reason): PromiseInterface
|
||||
{
|
||||
if ($reason instanceof PromiseInterface) {
|
||||
return $reason;
|
||||
|
@ -50,12 +49,10 @@ final class Create
|
|||
* Create an exception for a rejected promise value.
|
||||
*
|
||||
* @param mixed $reason
|
||||
*
|
||||
* @return \Exception|\Throwable
|
||||
*/
|
||||
public static function exceptionFor($reason)
|
||||
public static function exceptionFor($reason): \Throwable
|
||||
{
|
||||
if ($reason instanceof \Exception || $reason instanceof \Throwable) {
|
||||
if ($reason instanceof \Throwable) {
|
||||
return $reason;
|
||||
}
|
||||
|
||||
|
@ -66,10 +63,8 @@ final class Create
|
|||
* Returns an iterator for the given value.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return \Iterator
|
||||
*/
|
||||
public static function iterFor($value)
|
||||
public static function iterFor($value): \Iterator
|
||||
{
|
||||
if ($value instanceof \Iterator) {
|
||||
return $value;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
final class Each
|
||||
|
@ -20,17 +22,15 @@ final class Each
|
|||
* @param mixed $iterable Iterator or array to iterate over.
|
||||
* @param callable $onFulfilled
|
||||
* @param callable $onRejected
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public static function of(
|
||||
$iterable,
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
) {
|
||||
): PromiseInterface {
|
||||
return (new EachPromise($iterable, [
|
||||
'fulfilled' => $onFulfilled,
|
||||
'rejected' => $onRejected
|
||||
'rejected' => $onRejected,
|
||||
]))->promise();
|
||||
}
|
||||
|
||||
|
@ -46,19 +46,17 @@ final class Each
|
|||
* @param int|callable $concurrency
|
||||
* @param callable $onFulfilled
|
||||
* @param callable $onRejected
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public static function ofLimit(
|
||||
$iterable,
|
||||
$concurrency,
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
) {
|
||||
): PromiseInterface {
|
||||
return (new EachPromise($iterable, [
|
||||
'fulfilled' => $onFulfilled,
|
||||
'rejected' => $onRejected,
|
||||
'concurrency' => $concurrency
|
||||
'fulfilled' => $onFulfilled,
|
||||
'rejected' => $onRejected,
|
||||
'concurrency' => $concurrency,
|
||||
]))->promise();
|
||||
}
|
||||
|
||||
|
@ -70,19 +68,17 @@ final class Each
|
|||
* @param mixed $iterable
|
||||
* @param int|callable $concurrency
|
||||
* @param callable $onFulfilled
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public static function ofLimitAll(
|
||||
$iterable,
|
||||
$concurrency,
|
||||
callable $onFulfilled = null
|
||||
) {
|
||||
return each_limit(
|
||||
): PromiseInterface {
|
||||
return self::ofLimit(
|
||||
$iterable,
|
||||
$concurrency,
|
||||
$onFulfilled,
|
||||
function ($reason, $idx, PromiseInterface $aggregate) {
|
||||
function ($reason, $idx, PromiseInterface $aggregate): void {
|
||||
$aggregate->reject($reason);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
/**
|
||||
* Represents a promise that iterates over many promises and invokes
|
||||
* side-effect functions in the process.
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class EachPromise implements PromisorInterface
|
||||
{
|
||||
|
@ -69,7 +73,7 @@ class EachPromise implements PromisorInterface
|
|||
}
|
||||
|
||||
/** @psalm-suppress InvalidNullableReturnType */
|
||||
public function promise()
|
||||
public function promise(): PromiseInterface
|
||||
{
|
||||
if ($this->aggregate) {
|
||||
return $this->aggregate;
|
||||
|
@ -82,21 +86,18 @@ class EachPromise implements PromisorInterface
|
|||
$this->refillPending();
|
||||
} catch (\Throwable $e) {
|
||||
$this->aggregate->reject($e);
|
||||
} catch (\Exception $e) {
|
||||
$this->aggregate->reject($e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress NullableReturnStatement
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
return $this->aggregate;
|
||||
}
|
||||
|
||||
private function createPromise()
|
||||
private function createPromise(): void
|
||||
{
|
||||
$this->mutex = false;
|
||||
$this->aggregate = new Promise(function () {
|
||||
$this->aggregate = new Promise(function (): void {
|
||||
if ($this->checkIfFinished()) {
|
||||
return;
|
||||
}
|
||||
|
@ -113,7 +114,7 @@ class EachPromise implements PromisorInterface
|
|||
});
|
||||
|
||||
// Clear the references when the promise is resolved.
|
||||
$clearFn = function () {
|
||||
$clearFn = function (): void {
|
||||
$this->iterable = $this->concurrency = $this->pending = null;
|
||||
$this->onFulfilled = $this->onRejected = null;
|
||||
$this->nextPendingIndex = 0;
|
||||
|
@ -122,11 +123,13 @@ class EachPromise implements PromisorInterface
|
|||
$this->aggregate->then($clearFn, $clearFn);
|
||||
}
|
||||
|
||||
private function refillPending()
|
||||
private function refillPending(): void
|
||||
{
|
||||
if (!$this->concurrency) {
|
||||
// Add all pending promises.
|
||||
while ($this->addPending() && $this->advanceIterator());
|
||||
while ($this->addPending() && $this->advanceIterator()) {
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -147,10 +150,11 @@ class EachPromise implements PromisorInterface
|
|||
// next value to yield until promise callbacks are called.
|
||||
while (--$concurrency
|
||||
&& $this->advanceIterator()
|
||||
&& $this->addPending());
|
||||
&& $this->addPending()) {
|
||||
}
|
||||
}
|
||||
|
||||
private function addPending()
|
||||
private function addPending(): bool
|
||||
{
|
||||
if (!$this->iterable || !$this->iterable->valid()) {
|
||||
return false;
|
||||
|
@ -164,7 +168,7 @@ class EachPromise implements PromisorInterface
|
|||
$idx = $this->nextPendingIndex++;
|
||||
|
||||
$this->pending[$idx] = $promise->then(
|
||||
function ($value) use ($idx, $key) {
|
||||
function ($value) use ($idx, $key): void {
|
||||
if ($this->onFulfilled) {
|
||||
call_user_func(
|
||||
$this->onFulfilled,
|
||||
|
@ -175,7 +179,7 @@ class EachPromise implements PromisorInterface
|
|||
}
|
||||
$this->step($idx);
|
||||
},
|
||||
function ($reason) use ($idx, $key) {
|
||||
function ($reason) use ($idx, $key): void {
|
||||
if ($this->onRejected) {
|
||||
call_user_func(
|
||||
$this->onRejected,
|
||||
|
@ -191,7 +195,7 @@ class EachPromise implements PromisorInterface
|
|||
return true;
|
||||
}
|
||||
|
||||
private function advanceIterator()
|
||||
private function advanceIterator(): bool
|
||||
{
|
||||
// Place a lock on the iterator so that we ensure to not recurse,
|
||||
// preventing fatal generator errors.
|
||||
|
@ -204,19 +208,17 @@ class EachPromise implements PromisorInterface
|
|||
try {
|
||||
$this->iterable->next();
|
||||
$this->mutex = false;
|
||||
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
$this->aggregate->reject($e);
|
||||
$this->mutex = false;
|
||||
return false;
|
||||
} catch (\Exception $e) {
|
||||
$this->aggregate->reject($e);
|
||||
$this->mutex = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function step($idx)
|
||||
private function step(int $idx): void
|
||||
{
|
||||
// If the promise was already resolved, then ignore this step.
|
||||
if (Is::settled($this->aggregate)) {
|
||||
|
@ -234,11 +236,12 @@ class EachPromise implements PromisorInterface
|
|||
}
|
||||
}
|
||||
|
||||
private function checkIfFinished()
|
||||
private function checkIfFinished(): bool
|
||||
{
|
||||
if (!$this->pending && !$this->iterable->valid()) {
|
||||
// Resolve the promise if there's nothing left to do.
|
||||
$this->aggregate->resolve(null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
/**
|
||||
|
@ -7,11 +9,16 @@ namespace GuzzleHttp\Promise;
|
|||
*
|
||||
* Thenning off of this promise will invoke the onFulfilled callback
|
||||
* immediately and ignore other callbacks.
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class FulfilledPromise implements PromiseInterface
|
||||
{
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __construct($value)
|
||||
{
|
||||
if (is_object($value) && method_exists($value, 'then')) {
|
||||
|
@ -26,7 +33,7 @@ class FulfilledPromise implements PromiseInterface
|
|||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
) {
|
||||
): PromiseInterface {
|
||||
// Return itself if there is no onFulfilled function.
|
||||
if (!$onFulfilled) {
|
||||
return $this;
|
||||
|
@ -35,14 +42,12 @@ class FulfilledPromise implements PromiseInterface
|
|||
$queue = Utils::queue();
|
||||
$p = new Promise([$queue, 'run']);
|
||||
$value = $this->value;
|
||||
$queue->add(static function () use ($p, $value, $onFulfilled) {
|
||||
$queue->add(static function () use ($p, $value, $onFulfilled): void {
|
||||
if (Is::pending($p)) {
|
||||
try {
|
||||
$p->resolve($onFulfilled($value));
|
||||
} catch (\Throwable $e) {
|
||||
$p->reject($e);
|
||||
} catch (\Exception $e) {
|
||||
$p->reject($e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -50,34 +55,34 @@ class FulfilledPromise implements PromiseInterface
|
|||
return $p;
|
||||
}
|
||||
|
||||
public function otherwise(callable $onRejected)
|
||||
public function otherwise(callable $onRejected): PromiseInterface
|
||||
{
|
||||
return $this->then(null, $onRejected);
|
||||
}
|
||||
|
||||
public function wait($unwrap = true, $defaultDelivery = null)
|
||||
public function wait(bool $unwrap = true)
|
||||
{
|
||||
return $unwrap ? $this->value : null;
|
||||
}
|
||||
|
||||
public function getState()
|
||||
public function getState(): string
|
||||
{
|
||||
return self::FULFILLED;
|
||||
}
|
||||
|
||||
public function resolve($value)
|
||||
public function resolve($value): void
|
||||
{
|
||||
if ($value !== $this->value) {
|
||||
throw new \LogicException("Cannot resolve a fulfilled promise");
|
||||
throw new \LogicException('Cannot resolve a fulfilled promise');
|
||||
}
|
||||
}
|
||||
|
||||
public function reject($reason)
|
||||
public function reject($reason): void
|
||||
{
|
||||
throw new \LogicException("Cannot reject a fulfilled promise");
|
||||
throw new \LogicException('Cannot reject a fulfilled promise');
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
public function cancel(): void
|
||||
{
|
||||
// pass
|
||||
}
|
||||
|
|
|
@ -1,45 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
final class Is
|
||||
{
|
||||
/**
|
||||
* Returns true if a promise is pending.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function pending(PromiseInterface $promise)
|
||||
public static function pending(PromiseInterface $promise): bool
|
||||
{
|
||||
return $promise->getState() === PromiseInterface::PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a promise is fulfilled or rejected.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function settled(PromiseInterface $promise)
|
||||
public static function settled(PromiseInterface $promise): bool
|
||||
{
|
||||
return $promise->getState() !== PromiseInterface::PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a promise is fulfilled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function fulfilled(PromiseInterface $promise)
|
||||
public static function fulfilled(PromiseInterface $promise): bool
|
||||
{
|
||||
return $promise->getState() === PromiseInterface::FULFILLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a promise is rejected.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function rejected(PromiseInterface $promise)
|
||||
public static function rejected(PromiseInterface $promise): bool
|
||||
{
|
||||
return $promise->getState() === PromiseInterface::REJECTED;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
/**
|
||||
* Promises/A+ implementation that avoids recursion when possible.
|
||||
*
|
||||
* @link https://promisesaplus.com/
|
||||
* @see https://promisesaplus.com/
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class Promise implements PromiseInterface
|
||||
{
|
||||
|
@ -31,33 +35,36 @@ class Promise implements PromiseInterface
|
|||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
) {
|
||||
): PromiseInterface {
|
||||
if ($this->state === self::PENDING) {
|
||||
$p = new Promise(null, [$this, 'cancel']);
|
||||
$this->handlers[] = [$p, $onFulfilled, $onRejected];
|
||||
$p->waitList = $this->waitList;
|
||||
$p->waitList[] = $this;
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
// Return a fulfilled promise and immediately invoke any callbacks.
|
||||
if ($this->state === self::FULFILLED) {
|
||||
$promise = Create::promiseFor($this->result);
|
||||
|
||||
return $onFulfilled ? $promise->then($onFulfilled) : $promise;
|
||||
}
|
||||
|
||||
// It's either cancelled or rejected, so return a rejected promise
|
||||
// and immediately invoke any callbacks.
|
||||
$rejection = Create::rejectionFor($this->result);
|
||||
|
||||
return $onRejected ? $rejection->then(null, $onRejected) : $rejection;
|
||||
}
|
||||
|
||||
public function otherwise(callable $onRejected)
|
||||
public function otherwise(callable $onRejected): PromiseInterface
|
||||
{
|
||||
return $this->then(null, $onRejected);
|
||||
}
|
||||
|
||||
public function wait($unwrap = true)
|
||||
public function wait(bool $unwrap = true)
|
||||
{
|
||||
$this->waitIfPending();
|
||||
|
||||
|
@ -73,12 +80,12 @@ class Promise implements PromiseInterface
|
|||
}
|
||||
}
|
||||
|
||||
public function getState()
|
||||
public function getState(): string
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
public function cancel(): void
|
||||
{
|
||||
if ($this->state !== self::PENDING) {
|
||||
return;
|
||||
|
@ -93,8 +100,6 @@ class Promise implements PromiseInterface
|
|||
$fn();
|
||||
} catch (\Throwable $e) {
|
||||
$this->reject($e);
|
||||
} catch (\Exception $e) {
|
||||
$this->reject($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,17 +110,17 @@ class Promise implements PromiseInterface
|
|||
}
|
||||
}
|
||||
|
||||
public function resolve($value)
|
||||
public function resolve($value): void
|
||||
{
|
||||
$this->settle(self::FULFILLED, $value);
|
||||
}
|
||||
|
||||
public function reject($reason)
|
||||
public function reject($reason): void
|
||||
{
|
||||
$this->settle(self::REJECTED, $reason);
|
||||
}
|
||||
|
||||
private function settle($state, $value)
|
||||
private function settle(string $state, $value): void
|
||||
{
|
||||
if ($this->state !== self::PENDING) {
|
||||
// Ignore calls with the same resolution.
|
||||
|
@ -148,7 +153,7 @@ class Promise implements PromiseInterface
|
|||
if (!is_object($value) || !method_exists($value, 'then')) {
|
||||
$id = $state === self::FULFILLED ? 1 : 2;
|
||||
// It's a success, so resolve the handlers in the queue.
|
||||
Utils::queue()->add(static function () use ($id, $value, $handlers) {
|
||||
Utils::queue()->add(static function () use ($id, $value, $handlers): void {
|
||||
foreach ($handlers as $handler) {
|
||||
self::callHandler($id, $value, $handler);
|
||||
}
|
||||
|
@ -159,12 +164,12 @@ class Promise implements PromiseInterface
|
|||
} else {
|
||||
// Resolve the handlers when the forwarded promise is resolved.
|
||||
$value->then(
|
||||
static function ($value) use ($handlers) {
|
||||
static function ($value) use ($handlers): void {
|
||||
foreach ($handlers as $handler) {
|
||||
self::callHandler(1, $value, $handler);
|
||||
}
|
||||
},
|
||||
static function ($reason) use ($handlers) {
|
||||
static function ($reason) use ($handlers): void {
|
||||
foreach ($handlers as $handler) {
|
||||
self::callHandler(2, $reason, $handler);
|
||||
}
|
||||
|
@ -180,7 +185,7 @@ class Promise implements PromiseInterface
|
|||
* @param mixed $value Value to pass to the callback.
|
||||
* @param array $handler Array of handler data (promise and callbacks).
|
||||
*/
|
||||
private static function callHandler($index, $value, array $handler)
|
||||
private static function callHandler(int $index, $value, array $handler): void
|
||||
{
|
||||
/** @var PromiseInterface $promise */
|
||||
$promise = $handler[0];
|
||||
|
@ -211,12 +216,10 @@ class Promise implements PromiseInterface
|
|||
}
|
||||
} catch (\Throwable $reason) {
|
||||
$promise->reject($reason);
|
||||
} catch (\Exception $reason) {
|
||||
$promise->reject($reason);
|
||||
}
|
||||
}
|
||||
|
||||
private function waitIfPending()
|
||||
private function waitIfPending(): void
|
||||
{
|
||||
if ($this->state !== self::PENDING) {
|
||||
return;
|
||||
|
@ -227,9 +230,9 @@ class Promise implements PromiseInterface
|
|||
} else {
|
||||
// If there's no wait function, then reject the promise.
|
||||
$this->reject('Cannot wait on a promise that has '
|
||||
. 'no internal wait function. You must provide a wait '
|
||||
. 'function when constructing the promise to be able to '
|
||||
. 'wait on a promise.');
|
||||
.'no internal wait function. You must provide a wait '
|
||||
.'function when constructing the promise to be able to '
|
||||
.'wait on a promise.');
|
||||
}
|
||||
|
||||
Utils::queue()->run();
|
||||
|
@ -240,13 +243,13 @@ class Promise implements PromiseInterface
|
|||
}
|
||||
}
|
||||
|
||||
private function invokeWaitFn()
|
||||
private function invokeWaitFn(): void
|
||||
{
|
||||
try {
|
||||
$wfn = $this->waitFn;
|
||||
$this->waitFn = null;
|
||||
$wfn(true);
|
||||
} catch (\Exception $reason) {
|
||||
} catch (\Throwable $reason) {
|
||||
if ($this->state === self::PENDING) {
|
||||
// The promise has not been resolved yet, so reject the promise
|
||||
// with the exception.
|
||||
|
@ -259,7 +262,7 @@ class Promise implements PromiseInterface
|
|||
}
|
||||
}
|
||||
|
||||
private function invokeWaitList()
|
||||
private function invokeWaitList(): void
|
||||
{
|
||||
$waitList = $this->waitList;
|
||||
$this->waitList = null;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue