mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-25 19:48:49 +02:00
Re-dump autoloader and composer.lock
This commit is contained in:
@@ -21,19 +21,19 @@
|
||||
"pelago/emogrifier": "^7.2.0",
|
||||
"psr/log": "^3.0.0",
|
||||
"scssphp/scssphp": "^1.12.1",
|
||||
"soundasleep/html2text": "~2.1",
|
||||
"symfony/console": "~6.4.0",
|
||||
"symfony/dotenv": "~6.4.0",
|
||||
"symfony/framework-bundle": "~6.4.0",
|
||||
"symfony/http-foundation": "~6.4.0",
|
||||
"symfony/http-kernel": "~6.4.0",
|
||||
"symfony/mailer": "^6.4",
|
||||
"symfony/runtime": "~6.4.0",
|
||||
"symfony/twig-bundle": "~6.4.0",
|
||||
"symfony/var-dumper": "~6.4.0",
|
||||
"symfony/yaml": "~6.4.0",
|
||||
"symfony/mailer": "~6.4.0",
|
||||
"tecnickcom/tcpdf": "^6.6.0",
|
||||
"thenetworg/oauth2-azure": "^2.0",
|
||||
"soundasleep/html2text": "~2.1"
|
||||
"thenetworg/oauth2-azure": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/debug-bundle": "~6.4.0",
|
||||
|
||||
709
composer.lock
generated
709
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -14,10 +14,7 @@ if (PHP_VERSION_ID < 50600) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
throw new RuntimeException($err);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/patch-type-declarations
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
||||
0
lib/bin/pscss
Normal file → Executable file
0
lib/bin/pscss
Normal file → Executable file
@@ -1,5 +0,0 @@
|
||||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/pscss
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
||||
@@ -1,5 +0,0 @@
|
||||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/var-dump-server
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
||||
@@ -1,5 +0,0 @@
|
||||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/yaml-lint
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
||||
@@ -948,6 +948,7 @@ return array(
|
||||
'PDF417' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/pdf417.php',
|
||||
'PDFBulkExport' => $baseDir . '/core/pdfbulkexport.class.inc.php',
|
||||
'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php',
|
||||
'PEAR_Error' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php',
|
||||
'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
|
||||
'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php',
|
||||
'Pelago\\Emogrifier\\Caching\\SimpleStringCache' => $vendorDir . '/pelago/emogrifier/src/Caching/SimpleStringCache.php',
|
||||
@@ -1473,6 +1474,8 @@ return array(
|
||||
'Symfony\\Bridge\\Twig\\Node\\StopwatchNode' => $vendorDir . '/symfony/twig-bridge/Node/StopwatchNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransDefaultDomainNode' => $vendorDir . '/symfony/twig-bridge/Node/TransDefaultDomainNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransNode' => $vendorDir . '/symfony/twig-bridge/Node/TransNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase' => $vendorDir . '/symfony/twig-bridge/Test/FormLayoutTestCase.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\Traits\\RuntimeLoaderProvider' => $vendorDir . '/symfony/twig-bridge/Test/Traits/RuntimeLoaderProvider.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\DumpTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/DumpTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\FormThemeTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/FormThemeTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\StopwatchTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/StopwatchTokenParser.php',
|
||||
@@ -2284,6 +2287,17 @@ return array(
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => $vendorDir . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedJsonResponse' => $vendorDir . '/symfony/http-foundation/StreamedJsonResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => $vendorDir . '/symfony/http-foundation/StreamedResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderLocationSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHeaderLocationSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UriSigner' => $vendorDir . '/symfony/http-foundation/UriSigner.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UrlHelper' => $vendorDir . '/symfony/http-foundation/UrlHelper.php',
|
||||
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => $vendorDir . '/symfony/http-kernel/Attribute/AsController.php',
|
||||
@@ -2739,6 +2753,7 @@ return array(
|
||||
'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => $vendorDir . '/symfony/var-dumper/Exception/ThrowingCasterException.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\Connection' => $vendorDir . '/symfony/var-dumper/Server/Connection.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => $vendorDir . '/symfony/var-dumper/Server/DumpServer.php',
|
||||
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
|
||||
'Symfony\\Component\\VarDumper\\VarDumper' => $vendorDir . '/symfony/var-dumper/VarDumper.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/var-exporter/Exception/ExceptionInterface.php',
|
||||
@@ -3191,5 +3206,5 @@ return array(
|
||||
'privUITransactionFile' => $baseDir . '/application/transaction.class.inc.php',
|
||||
'privUITransactionSession' => $baseDir . '/application/transaction.class.inc.php',
|
||||
'utils' => $baseDir . '/application/utils.inc.php',
|
||||
'<EFBFBD>' => $vendorDir . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
'©' => $vendorDir . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
);
|
||||
|
||||
@@ -20,7 +20,6 @@ return array(
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
|
||||
'344f11dc3484aaed5cbde58e23513be4' => $vendorDir . '/apereo/phpcas/source/CAS.php',
|
||||
'6997bc0ca52a383ea79e2a4a84bb1f3e' => $baseDir . '/sources/alias.php',
|
||||
|
||||
@@ -8,5 +8,4 @@ $baseDir = dirname($vendorDir);
|
||||
return array(
|
||||
'Console' => array($vendorDir . '/pear/console_getopt'),
|
||||
'Archive_Tar' => array($vendorDir . '/pear/archive_tar'),
|
||||
'' => array($vendorDir . '/pear/pear-core-minimal/src'),
|
||||
);
|
||||
|
||||
@@ -56,13 +56,7 @@ return array(
|
||||
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||
'Pelago\\Emogrifier\\' => array($vendorDir . '/pelago/emogrifier/src'),
|
||||
'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-client/src', $vendorDir . '/league/oauth2-google/src'),
|
||||
'Laminas\\Validator\\' => array($vendorDir . '/laminas/laminas-validator/src'),
|
||||
'Laminas\\Stdlib\\' => array($vendorDir . '/laminas/laminas-stdlib/src'),
|
||||
'Laminas\\ServiceManager\\' => array($vendorDir . '/laminas/laminas-servicemanager/src'),
|
||||
'Laminas\\Mime\\' => array($vendorDir . '/laminas/laminas-mime/src'),
|
||||
'Laminas\\Mail\\' => array($vendorDir . '/laminas/laminas-mail/src'),
|
||||
'Laminas\\Loader\\' => array($vendorDir . '/laminas/laminas-loader/src'),
|
||||
'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-google/src', $vendorDir . '/league/oauth2-client/src'),
|
||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
||||
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
|
||||
|
||||
@@ -21,7 +21,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
|
||||
'344f11dc3484aaed5cbde58e23513be4' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS.php',
|
||||
'6997bc0ca52a383ea79e2a4a84bb1f3e' => __DIR__ . '/../..' . '/sources/alias.php',
|
||||
@@ -315,8 +314,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
),
|
||||
'League\\OAuth2\\Client\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/league/oauth2-client/src',
|
||||
1 => __DIR__ . '/..' . '/league/oauth2-google/src',
|
||||
0 => __DIR__ . '/..' . '/league/oauth2-google/src',
|
||||
1 => __DIR__ . '/..' . '/league/oauth2-client/src',
|
||||
),
|
||||
'GuzzleHttp\\Psr7\\' =>
|
||||
array (
|
||||
@@ -361,10 +360,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
),
|
||||
);
|
||||
|
||||
public static $fallbackDirsPsr0 = array (
|
||||
0 => __DIR__ . '/..' . '/pear/pear-core-minimal/src',
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'AbstractApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension/backoffice/AbstractApplicationUIExtension.php',
|
||||
'AbstractLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension/login/AbstractLoginFSMExtension.php',
|
||||
@@ -1308,6 +1303,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'PDF417' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/pdf417.php',
|
||||
'PDFBulkExport' => __DIR__ . '/../..' . '/core/pdfbulkexport.class.inc.php',
|
||||
'PEAR' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php',
|
||||
'PEAR_Error' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php',
|
||||
'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
|
||||
'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php',
|
||||
'Pelago\\Emogrifier\\Caching\\SimpleStringCache' => __DIR__ . '/..' . '/pelago/emogrifier/src/Caching/SimpleStringCache.php',
|
||||
@@ -1833,6 +1829,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Bridge\\Twig\\Node\\StopwatchNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/StopwatchNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransDefaultDomainNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/TransDefaultDomainNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/TransNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase' => __DIR__ . '/..' . '/symfony/twig-bridge/Test/FormLayoutTestCase.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\Traits\\RuntimeLoaderProvider' => __DIR__ . '/..' . '/symfony/twig-bridge/Test/Traits/RuntimeLoaderProvider.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\DumpTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/DumpTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\FormThemeTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/FormThemeTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\StopwatchTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/StopwatchTokenParser.php',
|
||||
@@ -2644,6 +2642,17 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => __DIR__ . '/..' . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedJsonResponse' => __DIR__ . '/..' . '/symfony/http-foundation/StreamedJsonResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => __DIR__ . '/..' . '/symfony/http-foundation/StreamedResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderLocationSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHeaderLocationSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UriSigner' => __DIR__ . '/..' . '/symfony/http-foundation/UriSigner.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UrlHelper' => __DIR__ . '/..' . '/symfony/http-foundation/UrlHelper.php',
|
||||
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => __DIR__ . '/..' . '/symfony/http-kernel/Attribute/AsController.php',
|
||||
@@ -3099,6 +3108,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => __DIR__ . '/..' . '/symfony/var-dumper/Exception/ThrowingCasterException.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\Connection' => __DIR__ . '/..' . '/symfony/var-dumper/Server/Connection.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => __DIR__ . '/..' . '/symfony/var-dumper/Server/DumpServer.php',
|
||||
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => __DIR__ . '/..' . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
|
||||
'Symfony\\Component\\VarDumper\\VarDumper' => __DIR__ . '/..' . '/symfony/var-dumper/VarDumper.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ExceptionInterface.php',
|
||||
@@ -3551,7 +3561,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'privUITransactionFile' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
|
||||
'privUITransactionSession' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
|
||||
'utils' => __DIR__ . '/../..' . '/application/utils.inc.php',
|
||||
'<EFBFBD>' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
'©' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
@@ -3560,7 +3570,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$prefixesPsr0;
|
||||
$loader->fallbackDirsPsr0 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$fallbackDirsPsr0;
|
||||
$loader->classMap = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
|
||||
@@ -8,6 +8,6 @@ $baseDir = dirname($vendorDir);
|
||||
return array(
|
||||
$vendorDir . '/pear/archive_tar',
|
||||
$vendorDir . '/pear/console_getopt',
|
||||
$vendorDir . '/pear/pear-core-minimal/src',
|
||||
$vendorDir . '/pear/pear_exception',
|
||||
$vendorDir . '/pear/pear-core-minimal/src',
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
'name' => 'combodo/itop',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => 'bf1b2a5104e537e3b5f5a26beefc57068d2ef5b2',
|
||||
'reference' => '7e515e7216f019f4c69e3699ad9bc6221988ff1e',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -22,7 +22,7 @@
|
||||
'combodo/itop' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => 'bf1b2a5104e537e3b5f5a26beefc57068d2ef5b2',
|
||||
'reference' => '7e515e7216f019f4c69e3699ad9bc6221988ff1e',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -47,45 +47,45 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'firebase/php-jwt' => array(
|
||||
'pretty_version' => 'v6.10.0',
|
||||
'version' => '6.10.0.0',
|
||||
'reference' => 'a49db6f0a5033aef5143295342f1c95521b075ff',
|
||||
'pretty_version' => 'v6.11.1',
|
||||
'version' => '6.11.1.0',
|
||||
'reference' => 'd1e91ecf8c598d073d0995afa8cd5c75c6e19e66',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/guzzle' => array(
|
||||
'pretty_version' => '7.8.1',
|
||||
'version' => '7.8.1.0',
|
||||
'reference' => '41042bc7ab002487b876a0683fc8dce04ddce104',
|
||||
'pretty_version' => '7.10.0',
|
||||
'version' => '7.10.0.0',
|
||||
'reference' => 'b51ac707cfa420b7bfd4e4d5e510ba8008e822b4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/promises' => array(
|
||||
'pretty_version' => '2.0.2',
|
||||
'version' => '2.0.2.0',
|
||||
'reference' => 'bbff78d96034045e58e13dedd6ad91b5d1253223',
|
||||
'pretty_version' => '2.3.0',
|
||||
'version' => '2.3.0.0',
|
||||
'reference' => '481557b130ef3790cf82b713667b43030dc9c957',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/promises',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/psr7' => array(
|
||||
'pretty_version' => '2.6.2',
|
||||
'version' => '2.6.2.0',
|
||||
'reference' => '45b30f99ac27b5ca93cb4831afe16285f57b8221',
|
||||
'pretty_version' => '2.8.0',
|
||||
'version' => '2.8.0.0',
|
||||
'reference' => '21dc724a0583619cd1652f673303492272778051',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'league/oauth2-client' => array(
|
||||
'pretty_version' => '2.7.0',
|
||||
'version' => '2.7.0.0',
|
||||
'reference' => '160d6274b03562ebeb55ed18399281d8118b76c8',
|
||||
'pretty_version' => '2.8.1',
|
||||
'version' => '2.8.1.0',
|
||||
'reference' => '9df2924ca644736c835fc60466a3a60390d334f9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../league/oauth2-client',
|
||||
'aliases' => array(),
|
||||
@@ -111,15 +111,6 @@
|
||||
),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paragonie/random_compat' => array(
|
||||
'pretty_version' => 'v9.99.100',
|
||||
'version' => '9.99.100.0',
|
||||
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paragonie/random_compat',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'pear/archive_tar' => array(
|
||||
'pretty_version' => '1.4.14',
|
||||
'version' => '1.4.14.0',
|
||||
@@ -139,9 +130,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'pear/pear-core-minimal' => array(
|
||||
'pretty_version' => 'v1.10.11',
|
||||
'version' => '1.10.11.0',
|
||||
'reference' => '68d0d32ada737153b7e93b8d3c710ebe70ac867d',
|
||||
'pretty_version' => 'v1.10.16',
|
||||
'version' => '1.10.16.0',
|
||||
'reference' => 'c0f51b45f50683bf5bbf558036854ebc9b54d033',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../pear/pear-core-minimal',
|
||||
'aliases' => array(),
|
||||
@@ -157,9 +148,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'pelago/emogrifier' => array(
|
||||
'pretty_version' => 'v7.2.0',
|
||||
'version' => '7.2.0.0',
|
||||
'reference' => '727bdf7255b51798307f17dec52ff8a91f1c7de3',
|
||||
'pretty_version' => 'v7.3.0',
|
||||
'version' => '7.3.0.0',
|
||||
'reference' => '6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../pelago/emogrifier',
|
||||
'aliases' => array(),
|
||||
@@ -181,9 +172,9 @@
|
||||
),
|
||||
),
|
||||
'psr/container' => array(
|
||||
'pretty_version' => '1.1.2',
|
||||
'version' => '1.1.2.0',
|
||||
'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea',
|
||||
'pretty_version' => '2.0.2',
|
||||
'version' => '2.0.2.0',
|
||||
'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/container',
|
||||
'aliases' => array(),
|
||||
@@ -226,9 +217,9 @@
|
||||
),
|
||||
),
|
||||
'psr/http-factory' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => 'e616d01114759c4c489f93b099585439f795fe35',
|
||||
'pretty_version' => '1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-factory',
|
||||
'aliases' => array(),
|
||||
@@ -256,9 +247,9 @@
|
||||
),
|
||||
),
|
||||
'psr/log' => array(
|
||||
'pretty_version' => '3.0.0',
|
||||
'version' => '3.0.0.0',
|
||||
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
|
||||
'pretty_version' => '3.0.2',
|
||||
'version' => '3.0.2.0',
|
||||
'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/log',
|
||||
'aliases' => array(),
|
||||
@@ -288,22 +279,22 @@
|
||||
'rsky/pear-core-min' => array(
|
||||
'dev_requirement' => false,
|
||||
'replaced' => array(
|
||||
0 => 'v1.10.11',
|
||||
0 => 'v1.10.16',
|
||||
),
|
||||
),
|
||||
'sabberworm/php-css-parser' => array(
|
||||
'pretty_version' => '8.4.0',
|
||||
'version' => '8.4.0.0',
|
||||
'reference' => 'e41d2140031d533348b2192a83f02d8dd8a71d30',
|
||||
'pretty_version' => 'v8.9.0',
|
||||
'version' => '8.9.0.0',
|
||||
'reference' => 'd8e916507b88e389e26d4ab03c904a082aa66bb9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sabberworm/php-css-parser',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'scssphp/scssphp' => array(
|
||||
'pretty_version' => 'v1.12.1',
|
||||
'version' => '1.12.1.0',
|
||||
'reference' => '394ed1e960138710a60d035c1a85d43d0bf0faeb',
|
||||
'pretty_version' => 'v1.13.0',
|
||||
'version' => '1.13.0.0',
|
||||
'reference' => '63d1157457e5554edf00b0c1fabab4c1511d2520',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../scssphp/scssphp',
|
||||
'aliases' => array(),
|
||||
@@ -319,9 +310,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/cache' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => 'c88690befb8d4a85dc321fb78d677507f5eb141b',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => 'd038cd3054aeaf1c674022a77048b2ef6376a175',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/cache',
|
||||
'aliases' => array(),
|
||||
@@ -343,27 +334,27 @@
|
||||
),
|
||||
),
|
||||
'symfony/config' => array(
|
||||
'pretty_version' => 'v6.4.22',
|
||||
'version' => '6.4.22.0',
|
||||
'reference' => 'af5917a3b1571f54689e56677a3f06440d2fe4c7',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => '80e2cf005cf17138c97193be0434cdcfd1b2212e',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/config',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/console' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => '9056771b8eca08d026cd3280deeec3cfd99c4d93',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '273fd29ff30ba0a88ca5fb83f7cf1ab69306adae',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/console',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/css-selector' => array(
|
||||
'pretty_version' => 'v6.4.13',
|
||||
'version' => '6.4.13.0',
|
||||
'reference' => 'cb23e97813c5837a041b73a6d63a9ddff0778f5e',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => '9b784413143701aa3c94ac1869a159a9e53e8761',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/css-selector',
|
||||
'aliases' => array(),
|
||||
@@ -379,9 +370,9 @@
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/dependency-injection' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => '0d9f24f3de0a83573fce5c9ed025d6306c6e166b',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '900da8a42eceeb4a13a0ec34caa7db49328daff3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/dependency-injection',
|
||||
'aliases' => array(),
|
||||
@@ -397,27 +388,27 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/dotenv' => array(
|
||||
'pretty_version' => 'v6.4.16',
|
||||
'version' => '6.4.16.0',
|
||||
'reference' => '1ac5e7e7e862d4d574258daf08bd569ba926e4a5',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => '234b6c602f12b00693f4b0d1054386fb30dfc8ff',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/dotenv',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/error-handler' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => 'b088e0b175c30b4e06d8085200fa465b586f44fa',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => '30fd0b3cf0e972e82636038ce4db0e4fe777112c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/error-handler',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/event-dispatcher' => array(
|
||||
'pretty_version' => 'v6.4.13',
|
||||
'version' => '6.4.13.0',
|
||||
'reference' => '0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => 'b0cf3162020603587363f0551cd3be43958611ff',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
|
||||
'aliases' => array(),
|
||||
@@ -439,45 +430,45 @@
|
||||
),
|
||||
),
|
||||
'symfony/filesystem' => array(
|
||||
'pretty_version' => 'v6.4.13',
|
||||
'version' => '6.4.13.0',
|
||||
'reference' => '4856c9cf585d5a0313d8d35afd681a526f038dd3',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => '75ae2edb7cdcc0c53766c30b0a2512b8df574bd8',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/filesystem',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/finder' => array(
|
||||
'pretty_version' => 'v6.4.17',
|
||||
'version' => '6.4.17.0',
|
||||
'reference' => '1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => '73089124388c8510efb8d2d1689285d285937b08',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/finder',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/framework-bundle' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => 'ff892d3ab4b8aa35921bc2120a4b31d57948fe22',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '1d6a764b58e4f780df00f71c20ba3a61095ea447',
|
||||
'type' => 'symfony-bundle',
|
||||
'install_path' => __DIR__ . '/../symfony/framework-bundle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/http-foundation' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => '452d19f945ee41345fd8a50c18b60783546b7bd3',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '6bc974c0035b643aa497c58d46d9e25185e4b272',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/http-kernel' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => '2bb2cba685aabd859f22cf6946554e8e7f3c329a',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => 'a0ee3cea5cabf4ed960fd2ef57668ceeacdb6e15',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-kernel',
|
||||
'aliases' => array(),
|
||||
@@ -502,8 +493,8 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-ctype' => array(
|
||||
'pretty_version' => 'v1.32.0',
|
||||
'version' => '1.32.0.0',
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||
@@ -511,17 +502,17 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-grapheme' => array(
|
||||
'pretty_version' => 'v1.32.0',
|
||||
'version' => '1.32.0.0',
|
||||
'reference' => 'b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe',
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '380872130d3a5dd3ace2f4010d95125fde5d5c70',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-idn' => array(
|
||||
'pretty_version' => 'v1.32.0',
|
||||
'version' => '1.32.0.0',
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '9614ac4d8061dc257ecc64cba1b140873dce8ad3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
|
||||
@@ -529,8 +520,8 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-normalizer' => array(
|
||||
'pretty_version' => 'v1.32.0',
|
||||
'version' => '1.32.0.0',
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '3833d7255cc303546435cb650316bff708a1c75c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
|
||||
@@ -538,8 +529,8 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.32.0',
|
||||
'version' => '1.32.0.0',
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '6d857f4d76bd4b343eac26d6b539585d2bc56493',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
@@ -547,27 +538,27 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php83' => array(
|
||||
'pretty_version' => 'v1.32.0',
|
||||
'version' => '1.32.0.0',
|
||||
'reference' => '2fb86d65e2d424369ad2905e83b236a8805ba491',
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '17f6f9a6b1735c0f163024d959f700cfbc5155e5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php83',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/routing' => array(
|
||||
'pretty_version' => 'v6.4.22',
|
||||
'version' => '6.4.22.0',
|
||||
'reference' => '1f5234e8457164a3a0038a4c0a4ba27876a9c670',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => 'e4f94e625c8e6f910aa004a0042f7b2d398278f5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/routing',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/runtime' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => 'ef1f03c2ab1144ac4ef7744b9e026bdb06f2f88f',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => 'c1cc6721646f546627236c57f835272806087337',
|
||||
'type' => 'composer-plugin',
|
||||
'install_path' => __DIR__ . '/../symfony/runtime',
|
||||
'aliases' => array(),
|
||||
@@ -589,18 +580,18 @@
|
||||
),
|
||||
),
|
||||
'symfony/stopwatch' => array(
|
||||
'pretty_version' => 'v6.4.19',
|
||||
'version' => '6.4.19.0',
|
||||
'reference' => 'dfe1481c12c06266d0c3d58c0cb4b09bd497ab9c',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => 'b67e94e06a05d9572c2fa354483b3e13e3cb1898',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/stopwatch',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/string' => array(
|
||||
'pretty_version' => 'v6.4.21',
|
||||
'version' => '6.4.21.0',
|
||||
'reference' => '73e2c6966a5aef1d4892873ed5322245295370c6',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/string',
|
||||
'aliases' => array(),
|
||||
@@ -616,54 +607,54 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/twig-bridge' => array(
|
||||
'pretty_version' => 'v6.4.22',
|
||||
'version' => '6.4.22.0',
|
||||
'reference' => '04ab306a2f2c9dbd46f4363383812954f704af9d',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '9d13e87591c9de3221c8d6f23cd9a2b5958607bf',
|
||||
'type' => 'symfony-bridge',
|
||||
'install_path' => __DIR__ . '/../symfony/twig-bridge',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/twig-bundle' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => 'ef970ed7eb9e547d21628e4c803de0943759cbcd',
|
||||
'pretty_version' => 'v6.4.24',
|
||||
'version' => '6.4.24.0',
|
||||
'reference' => '3b48b6e8225495c6d2438828982b4d219ca565ba',
|
||||
'type' => 'symfony-bundle',
|
||||
'install_path' => __DIR__ . '/../symfony/twig-bundle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-dumper' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => 'd55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => 'c6cd92486e9fc32506370822c57bc02353a5a92c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-exporter' => array(
|
||||
'pretty_version' => 'v6.4.22',
|
||||
'version' => '6.4.22.0',
|
||||
'reference' => 'f28cf841f5654955c9f88ceaf4b9dc29571988a9',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '4ff50a1b7c75d1d596aca50899d0c8c7e3de8358',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-exporter',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/web-profiler-bundle' => array(
|
||||
'pretty_version' => 'v6.4.19',
|
||||
'version' => '6.4.19.0',
|
||||
'reference' => '7d1026a8e950d416cb5148ae88ac23db5d264839',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => '4c1754d6b3ffe52e9eaed0d9a392eb43a60fc910',
|
||||
'type' => 'symfony-bundle',
|
||||
'install_path' => __DIR__ . '/../symfony/web-profiler-bundle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/yaml' => array(
|
||||
'pretty_version' => 'v6.4.23',
|
||||
'version' => '6.4.23.0',
|
||||
'reference' => '93e29e0deb5f1b2e360adfb389a20d25eb81a27b',
|
||||
'pretty_version' => 'v6.4.25',
|
||||
'version' => '6.4.25.0',
|
||||
'reference' => 'e54b060bc9c3dc3d4258bf0d165d0064e755f565',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/yaml',
|
||||
'aliases' => array(),
|
||||
|
||||
@@ -36,8 +36,7 @@ if ($issues) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
throw new \RuntimeException(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
# Changelog
|
||||
|
||||
## [6.11.1](https://github.com/firebase/php-jwt/compare/v6.11.0...v6.11.1) (2025-04-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update error text for consistency ([#528](https://github.com/firebase/php-jwt/issues/528)) ([c11113a](https://github.com/firebase/php-jwt/commit/c11113afa13265e016a669e75494b9203b8a7775))
|
||||
|
||||
## [6.11.0](https://github.com/firebase/php-jwt/compare/v6.10.2...v6.11.0) (2025-01-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support octet typed JWK ([#587](https://github.com/firebase/php-jwt/issues/587)) ([7cb8a26](https://github.com/firebase/php-jwt/commit/7cb8a265fa81edf2fa6ef8098f5bc5ae573c33ad))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* refactor constructor Key to use PHP 8.0 syntax ([#577](https://github.com/firebase/php-jwt/issues/577)) ([29fa2ce](https://github.com/firebase/php-jwt/commit/29fa2ce9e0582cd397711eec1e80c05ce20fabca))
|
||||
|
||||
## [6.10.2](https://github.com/firebase/php-jwt/compare/v6.10.1...v6.10.2) (2024-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Mitigate PHP8.4 deprecation warnings ([#570](https://github.com/firebase/php-jwt/issues/570)) ([76808fa](https://github.com/firebase/php-jwt/commit/76808fa227f3811aa5cdb3bf81233714b799a5b5))
|
||||
* support php 8.4 ([#583](https://github.com/firebase/php-jwt/issues/583)) ([e3d68b0](https://github.com/firebase/php-jwt/commit/e3d68b044421339443c74199edd020e03fb1887e))
|
||||
|
||||
## [6.10.1](https://github.com/firebase/php-jwt/compare/v6.10.0...v6.10.1) (2024-05-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ensure ratelimit expiry is set every time ([#556](https://github.com/firebase/php-jwt/issues/556)) ([09cb208](https://github.com/firebase/php-jwt/commit/09cb2081c2c3bc0f61e2f2a5fbea5741f7498648))
|
||||
* ratelimit cache expiration ([#550](https://github.com/firebase/php-jwt/issues/550)) ([dda7250](https://github.com/firebase/php-jwt/commit/dda725033585ece30ff8cae8937320d7e9f18bae))
|
||||
|
||||
## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28)
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ composer require firebase/php-jwt
|
||||
```
|
||||
|
||||
Optionally, install the `paragonie/sodium_compat` package from composer if your
|
||||
php is < 7.2 or does not have libsodium installed:
|
||||
php env does not have libsodium installed:
|
||||
|
||||
```bash
|
||||
composer require paragonie/sodium_compat
|
||||
@@ -48,7 +48,8 @@ $decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||
print_r($decoded);
|
||||
|
||||
// Pass a stdClass in as the third parameter to get the decoded header values
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass());
|
||||
$headers = new stdClass();
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers);
|
||||
print_r($headers);
|
||||
|
||||
/*
|
||||
@@ -290,7 +291,7 @@ $jwks = ['keys' => []];
|
||||
|
||||
// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
|
||||
// objects. Pass this as the second parameter to JWT::decode.
|
||||
JWT::decode($payload, JWK::parseKeySet($jwks));
|
||||
JWT::decode($jwt, JWK::parseKeySet($jwks));
|
||||
```
|
||||
|
||||
Using Cached Key Sets
|
||||
@@ -349,7 +350,7 @@ use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
$decoded = JWT::decode($jwt, $keys);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
// provided key/key-array is empty or malformed.
|
||||
} catch (DomainException $e) {
|
||||
@@ -379,7 +380,7 @@ like this:
|
||||
use Firebase\JWT\JWT;
|
||||
use UnexpectedValueException;
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
$decoded = JWT::decode($jwt, $keys);
|
||||
} catch (LogicException $e) {
|
||||
// errors having to do with environmental setup or malformed JWT Keys
|
||||
} catch (UnexpectedValueException $e) {
|
||||
@@ -394,7 +395,7 @@ instead, you can do the following:
|
||||
|
||||
```php
|
||||
// return type is stdClass
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
$decoded = JWT::decode($jwt, $keys);
|
||||
|
||||
// cast to array
|
||||
$decoded = json_decode(json_encode($decoded), true);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"require": {
|
||||
"php": "^7.4||^8.0"
|
||||
"php": "^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
|
||||
@@ -32,10 +32,10 @@
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/cache": "^2.0||^3.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
}
|
||||
|
||||
@@ -80,9 +80,9 @@ class CachedKeySet implements ArrayAccess
|
||||
ClientInterface $httpClient,
|
||||
RequestFactoryInterface $httpFactory,
|
||||
CacheItemPoolInterface $cache,
|
||||
int $expiresAfter = null,
|
||||
?int $expiresAfter = null,
|
||||
bool $rateLimit = false,
|
||||
string $defaultAlg = null
|
||||
?string $defaultAlg = null
|
||||
) {
|
||||
$this->jwksUri = $jwksUri;
|
||||
$this->httpClient = $httpClient;
|
||||
@@ -180,7 +180,7 @@ class CachedKeySet implements ArrayAccess
|
||||
$jwksResponse = $this->httpClient->sendRequest($request);
|
||||
if ($jwksResponse->getStatusCode() !== 200) {
|
||||
throw new UnexpectedValueException(
|
||||
sprintf('HTTP Error: %d %s for URI "%s"',
|
||||
\sprintf('HTTP Error: %d %s for URI "%s"',
|
||||
$jwksResponse->getStatusCode(),
|
||||
$jwksResponse->getReasonPhrase(),
|
||||
$this->jwksUri,
|
||||
@@ -212,15 +212,21 @@ class CachedKeySet implements ArrayAccess
|
||||
}
|
||||
|
||||
$cacheItem = $this->cache->getItem($this->rateLimitCacheKey);
|
||||
if (!$cacheItem->isHit()) {
|
||||
$cacheItem->expiresAfter(1); // # of calls are cached each minute
|
||||
|
||||
$cacheItemData = [];
|
||||
if ($cacheItem->isHit() && \is_array($data = $cacheItem->get())) {
|
||||
$cacheItemData = $data;
|
||||
}
|
||||
|
||||
$callsPerMinute = (int) $cacheItem->get();
|
||||
$callsPerMinute = $cacheItemData['callsPerMinute'] ?? 0;
|
||||
$expiry = $cacheItemData['expiry'] ?? new \DateTime('+60 seconds', new \DateTimeZone('UTC'));
|
||||
|
||||
if (++$callsPerMinute > $this->maxCallsPerMinute) {
|
||||
return true;
|
||||
}
|
||||
$cacheItem->set($callsPerMinute);
|
||||
|
||||
$cacheItem->set(['expiry' => $expiry, 'callsPerMinute' => $callsPerMinute]);
|
||||
$cacheItem->expiresAt($expiry);
|
||||
$this->cache->save($cacheItem);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class JWK
|
||||
*
|
||||
* @uses parseKey
|
||||
*/
|
||||
public static function parseKeySet(array $jwks, string $defaultAlg = null): array
|
||||
public static function parseKeySet(array $jwks, ?string $defaultAlg = null): array
|
||||
{
|
||||
$keys = [];
|
||||
|
||||
@@ -93,7 +93,7 @@ class JWK
|
||||
*
|
||||
* @uses createPemFromModulusAndExponent
|
||||
*/
|
||||
public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
|
||||
public static function parseKey(array $jwk, ?string $defaultAlg = null): ?Key
|
||||
{
|
||||
if (empty($jwk)) {
|
||||
throw new InvalidArgumentException('JWK must not be empty');
|
||||
@@ -172,6 +172,12 @@ class JWK
|
||||
// This library works internally with EdDSA keys (Ed25519) encoded in standard base64.
|
||||
$publicKey = JWT::convertBase64urlToBase64($jwk['x']);
|
||||
return new Key($publicKey, $jwk['alg']);
|
||||
case 'oct':
|
||||
if (!isset($jwk['k'])) {
|
||||
throw new UnexpectedValueException('k not set');
|
||||
}
|
||||
|
||||
return new Key(JWT::urlsafeB64Decode($jwk['k']), $jwk['alg']);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -212,7 +218,7 @@ class JWK
|
||||
)
|
||||
);
|
||||
|
||||
return sprintf(
|
||||
return \sprintf(
|
||||
"-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n",
|
||||
wordwrap(base64_encode($pem), 64, "\n", true)
|
||||
);
|
||||
|
||||
@@ -96,7 +96,7 @@ class JWT
|
||||
public static function decode(
|
||||
string $jwt,
|
||||
$keyOrKeyArray,
|
||||
stdClass &$headers = null
|
||||
?stdClass &$headers = null
|
||||
): stdClass {
|
||||
// Validate JWT
|
||||
$timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
|
||||
@@ -154,7 +154,7 @@ class JWT
|
||||
// token can actually be used. If it's not yet that time, abort.
|
||||
if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) {
|
||||
$ex = new BeforeValidException(
|
||||
'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf)
|
||||
'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) floor($payload->nbf))
|
||||
);
|
||||
$ex->setPayload($payload);
|
||||
throw $ex;
|
||||
@@ -165,7 +165,7 @@ class JWT
|
||||
// correctly used the nbf claim).
|
||||
if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) {
|
||||
$ex = new BeforeValidException(
|
||||
'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat)
|
||||
'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) floor($payload->iat))
|
||||
);
|
||||
$ex->setPayload($payload);
|
||||
throw $ex;
|
||||
@@ -200,11 +200,11 @@ class JWT
|
||||
array $payload,
|
||||
$key,
|
||||
string $alg,
|
||||
string $keyId = null,
|
||||
array $head = null
|
||||
?string $keyId = null,
|
||||
?array $head = null
|
||||
): string {
|
||||
$header = ['typ' => 'JWT'];
|
||||
if (isset($head) && \is_array($head)) {
|
||||
if (isset($head)) {
|
||||
$header = \array_merge($header, $head);
|
||||
}
|
||||
$header['alg'] = $alg;
|
||||
@@ -251,6 +251,9 @@ class JWT
|
||||
return \hash_hmac($algorithm, $msg, $key, true);
|
||||
case 'openssl':
|
||||
$signature = '';
|
||||
if (!\is_resource($key) && !openssl_pkey_get_private($key)) {
|
||||
throw new DomainException('OpenSSL unable to validate key');
|
||||
}
|
||||
$success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line
|
||||
if (!$success) {
|
||||
throw new DomainException('OpenSSL unable to sign data');
|
||||
@@ -384,12 +387,7 @@ class JWT
|
||||
*/
|
||||
public static function jsonEncode(array $input): string
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50400) {
|
||||
$json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
|
||||
} else {
|
||||
// PHP 5.3 only
|
||||
$json = \json_encode($input);
|
||||
}
|
||||
if ($errno = \json_last_error()) {
|
||||
self::handleJsonError($errno);
|
||||
} elseif ($json === 'null') {
|
||||
|
||||
@@ -9,18 +9,13 @@ use TypeError;
|
||||
|
||||
class Key
|
||||
{
|
||||
/** @var string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */
|
||||
private $keyMaterial;
|
||||
/** @var string */
|
||||
private $algorithm;
|
||||
|
||||
/**
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial
|
||||
* @param string $algorithm
|
||||
*/
|
||||
public function __construct(
|
||||
$keyMaterial,
|
||||
string $algorithm
|
||||
private $keyMaterial,
|
||||
private string $algorithm
|
||||
) {
|
||||
if (
|
||||
!\is_string($keyMaterial)
|
||||
@@ -38,10 +33,6 @@ class Key
|
||||
if (empty($algorithm)) {
|
||||
throw new InvalidArgumentException('Algorithm must not be empty');
|
||||
}
|
||||
|
||||
// TODO: Remove in PHP 8.0 in favor of class constructor property promotion
|
||||
$this->keyMaterial = $keyMaterial;
|
||||
$this->algorithm = $algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,56 @@
|
||||
|
||||
Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version.
|
||||
|
||||
## 7.10.0 - 2025-08-23
|
||||
|
||||
### Added
|
||||
|
||||
- Support for PHP 8.5
|
||||
|
||||
### Changed
|
||||
|
||||
- Adjusted `guzzlehttp/promises` version constraint to `^2.3`
|
||||
- Adjusted `guzzlehttp/psr7` version constraint to `^2.8`
|
||||
|
||||
|
||||
## 7.9.3 - 2025-03-27
|
||||
|
||||
### Changed
|
||||
|
||||
- Remove explicit content-length header for GET requests
|
||||
- Improve compatibility with bad servers for boolean cookie values
|
||||
|
||||
|
||||
## 7.9.2 - 2024-07-24
|
||||
|
||||
### Fixed
|
||||
|
||||
- Adjusted handler selection to use cURL if its version is 7.21.2 or higher, rather than 7.34.0
|
||||
|
||||
|
||||
## 7.9.1 - 2024-07-19
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix TLS 1.3 check for HTTP/2 requests
|
||||
|
||||
|
||||
## 7.9.0 - 2024-07-18
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve protocol version checks to provide feedback around unsupported protocols
|
||||
- Only select the cURL handler by default if 7.34.0 or higher is linked
|
||||
- Improved `CurlMultiHandler` to avoid busy wait if possible
|
||||
- Dropped support for EOL `guzzlehttp/psr7` v1
|
||||
- Improved URI user info redaction in errors
|
||||
|
||||
## 7.8.2 - 2024-07-18
|
||||
|
||||
### Added
|
||||
|
||||
- Support for PHP 8.4
|
||||
|
||||
|
||||
## 7.8.1 - 2023-12-03
|
||||
|
||||
|
||||
@@ -62,11 +62,11 @@ composer require guzzlehttp/guzzle
|
||||
|
||||
| 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.4 |
|
||||
| 3.x | EOL (2016-10-31) | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<7.0 |
|
||||
| 4.x | EOL (2016-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 |
|
||||
| 5.x | EOL (2019-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 |
|
||||
| 6.x | EOL (2023-10-31) | `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.5 |
|
||||
|
||||
[guzzle-3-repo]: https://github.com/guzzle/guzzle3
|
||||
[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x
|
||||
|
||||
@@ -50,11 +50,39 @@
|
||||
"homepage": "https://github.com/Tobion"
|
||||
}
|
||||
],
|
||||
"repositories": [
|
||||
{
|
||||
"type": "package",
|
||||
"package": {
|
||||
"name": "guzzle/client-integration-tests",
|
||||
"version": "v3.0.2",
|
||||
"dist": {
|
||||
"url": "https://codeload.github.com/guzzle/client-integration-tests/zip/2c025848417c1135031fdf9c728ee53d0a7ceaee",
|
||||
"type": "zip"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.11",
|
||||
"php-http/message": "^1.0 || ^2.0",
|
||||
"guzzlehttp/psr7": "^1.7 || ^2.0",
|
||||
"th3n3rd/cartesian-product": "^0.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Http\\Client\\Tests\\": "src/"
|
||||
}
|
||||
},
|
||||
"bin": [
|
||||
"bin/http_test_server"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/promises": "^1.5.3 || ^2.0.1",
|
||||
"guzzlehttp/psr7": "^1.9.1 || ^2.5.1",
|
||||
"guzzlehttp/promises": "^2.3",
|
||||
"guzzlehttp/psr7": "^2.8",
|
||||
"psr/http-client": "^1.0",
|
||||
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||
},
|
||||
@@ -64,9 +92,9 @@
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
|
||||
"guzzle/client-integration-tests": "3.0.2",
|
||||
"php-http/message-factory": "^1.1",
|
||||
"phpunit/phpunit": "^8.5.36 || ^9.6.15",
|
||||
"phpunit/phpunit": "^8.5.39 || ^9.6.20",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
|
||||
@@ -11,7 +11,7 @@ final class BodySummarizer implements BodySummarizerInterface
|
||||
*/
|
||||
private $truncateAt;
|
||||
|
||||
public function __construct(int $truncateAt = null)
|
||||
public function __construct(?int $truncateAt = null)
|
||||
{
|
||||
$this->truncateAt = $truncateAt;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ final class BodySummarizer implements BodySummarizerInterface
|
||||
public function summarize(MessageInterface $message): ?string
|
||||
{
|
||||
return $this->truncateAt === null
|
||||
? \GuzzleHttp\Psr7\Message::bodySummary($message)
|
||||
: \GuzzleHttp\Psr7\Message::bodySummary($message, $this->truncateAt);
|
||||
? Psr7\Message::bodySummary($message)
|
||||
: Psr7\Message::bodySummary($message, $this->truncateAt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
||||
*
|
||||
* @param array $config Client configuration settings.
|
||||
*
|
||||
* @see \GuzzleHttp\RequestOptions for a list of available request options.
|
||||
* @see RequestOptions for a list of available request options.
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
@@ -202,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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ class CookieJar implements CookieJarInterface
|
||||
}, $this->getIterator()->getArrayCopy());
|
||||
}
|
||||
|
||||
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 = [];
|
||||
|
||||
@@ -62,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.
|
||||
|
||||
@@ -62,6 +62,10 @@ class SetCookie
|
||||
if (is_numeric($value)) {
|
||||
$data[$search] = (int) $value;
|
||||
}
|
||||
} elseif ($search === 'Secure' || $search === 'Discard' || $search === 'HttpOnly') {
|
||||
if ($value) {
|
||||
$data[$search] = true;
|
||||
}
|
||||
} else {
|
||||
$data[$search] = $value;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class BadResponseException extends RequestException
|
||||
string $message,
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response,
|
||||
\Throwable $previous = null,
|
||||
?\Throwable $previous = null,
|
||||
array $handlerContext = []
|
||||
) {
|
||||
parent::__construct($message, $request, $response, $previous, $handlerContext);
|
||||
|
||||
@@ -25,7 +25,7 @@ class ConnectException extends TransferException implements NetworkExceptionInte
|
||||
public function __construct(
|
||||
string $message,
|
||||
RequestInterface $request,
|
||||
\Throwable $previous = null,
|
||||
?\Throwable $previous = null,
|
||||
array $handlerContext = []
|
||||
) {
|
||||
parent::__construct($message, 0, $previous);
|
||||
|
||||
@@ -7,7 +7,6 @@ use GuzzleHttp\BodySummarizerInterface;
|
||||
use Psr\Http\Client\RequestExceptionInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* HTTP Request exception
|
||||
@@ -32,8 +31,8 @@ class RequestException extends TransferException implements RequestExceptionInte
|
||||
public function __construct(
|
||||
string $message,
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response = null,
|
||||
\Throwable $previous = null,
|
||||
?ResponseInterface $response = null,
|
||||
?\Throwable $previous = null,
|
||||
array $handlerContext = []
|
||||
) {
|
||||
// Set the code of the exception if the response is set and not future.
|
||||
@@ -63,10 +62,10 @@ class RequestException extends TransferException implements RequestExceptionInte
|
||||
*/
|
||||
public static function create(
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response = null,
|
||||
\Throwable $previous = null,
|
||||
?ResponseInterface $response = null,
|
||||
?\Throwable $previous = null,
|
||||
array $handlerContext = [],
|
||||
BodySummarizerInterface $bodySummarizer = null
|
||||
?BodySummarizerInterface $bodySummarizer = null
|
||||
): self {
|
||||
if (!$response) {
|
||||
return new self(
|
||||
@@ -90,8 +89,7 @@ class RequestException extends TransferException implements RequestExceptionInte
|
||||
$className = __CLASS__;
|
||||
}
|
||||
|
||||
$uri = $request->getUri();
|
||||
$uri = static::obfuscateUri($uri);
|
||||
$uri = \GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri());
|
||||
|
||||
// Client Error: `GET /` resulted in a `404 Not Found` response:
|
||||
// <html> ... (truncated)
|
||||
@@ -113,20 +111,6 @@ class RequestException extends TransferException implements RequestExceptionInte
|
||||
return new $className($message, $request, $response, $previous, $handlerContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obfuscates URI if there is a username and a password present
|
||||
*/
|
||||
private static function obfuscateUri(UriInterface $uri): UriInterface
|
||||
{
|
||||
$userInfo = $uri->getUserInfo();
|
||||
|
||||
if (false !== ($pos = \strpos($userInfo, ':'))) {
|
||||
return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request that caused the exception
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,7 @@ use GuzzleHttp\Psr7\LazyOpenStream;
|
||||
use GuzzleHttp\TransferStats;
|
||||
use GuzzleHttp\Utils;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* Creates curl resources from a request
|
||||
@@ -46,6 +47,16 @@ class CurlFactory implements CurlFactoryInterface
|
||||
|
||||
public function create(RequestInterface $request, array $options): EasyHandle
|
||||
{
|
||||
$protocolVersion = $request->getProtocolVersion();
|
||||
|
||||
if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
|
||||
if (!self::supportsHttp2()) {
|
||||
throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
|
||||
}
|
||||
} elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
|
||||
throw new ConnectException(sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
|
||||
}
|
||||
|
||||
if (isset($options['curl']['body_as_string'])) {
|
||||
$options['_body_as_string'] = $options['curl']['body_as_string'];
|
||||
unset($options['curl']['body_as_string']);
|
||||
@@ -72,13 +83,51 @@ class CurlFactory implements CurlFactoryInterface
|
||||
return $easy;
|
||||
}
|
||||
|
||||
private static function supportsHttp2(): bool
|
||||
{
|
||||
static $supportsHttp2 = null;
|
||||
|
||||
if (null === $supportsHttp2) {
|
||||
$supportsHttp2 = self::supportsTls12()
|
||||
&& defined('CURL_VERSION_HTTP2')
|
||||
&& (\CURL_VERSION_HTTP2 & \curl_version()['features']);
|
||||
}
|
||||
|
||||
return $supportsHttp2;
|
||||
}
|
||||
|
||||
private static function supportsTls12(): bool
|
||||
{
|
||||
static $supportsTls12 = null;
|
||||
|
||||
if (null === $supportsTls12) {
|
||||
$supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
|
||||
}
|
||||
|
||||
return $supportsTls12;
|
||||
}
|
||||
|
||||
private static function supportsTls13(): bool
|
||||
{
|
||||
static $supportsTls13 = null;
|
||||
|
||||
if (null === $supportsTls13) {
|
||||
$supportsTls13 = defined('CURL_SSLVERSION_TLSv1_3')
|
||||
&& (\CURL_SSLVERSION_TLSv1_3 & \curl_version()['features']);
|
||||
}
|
||||
|
||||
return $supportsTls13;
|
||||
}
|
||||
|
||||
public function release(EasyHandle $easy): void
|
||||
{
|
||||
$resource = $easy->handle;
|
||||
unset($easy->handle);
|
||||
|
||||
if (\count($this->handles) >= $this->maxHandles) {
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
\curl_close($resource);
|
||||
}
|
||||
} else {
|
||||
// Remove all callback functions as they can hold onto references
|
||||
// and are not cleaned up by curl_reset. Using curl_setopt_array
|
||||
@@ -147,7 +196,7 @@ class CurlFactory implements CurlFactoryInterface
|
||||
'error' => \curl_error($easy->handle),
|
||||
'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME),
|
||||
] + \curl_getinfo($easy->handle);
|
||||
$ctx[self::CURL_VERSION_STR] = \curl_version()['version'];
|
||||
$ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
|
||||
$factory->release($easy);
|
||||
|
||||
// Retry when nothing is present or when curl failed to rewind.
|
||||
@@ -158,6 +207,17 @@ class CurlFactory implements CurlFactoryInterface
|
||||
return self::createRejection($easy, $ctx);
|
||||
}
|
||||
|
||||
private static function getCurlVersion(): string
|
||||
{
|
||||
static $curlVersion = null;
|
||||
|
||||
if (null === $curlVersion) {
|
||||
$curlVersion = \curl_version()['version'];
|
||||
}
|
||||
|
||||
return $curlVersion;
|
||||
}
|
||||
|
||||
private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface
|
||||
{
|
||||
static $connectionErrors = [
|
||||
@@ -194,15 +254,22 @@ class CurlFactory implements CurlFactoryInterface
|
||||
);
|
||||
}
|
||||
|
||||
$uri = $easy->request->getUri();
|
||||
|
||||
$sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
|
||||
|
||||
$message = \sprintf(
|
||||
'cURL error %s: %s (%s)',
|
||||
$ctx['errno'],
|
||||
$ctx['error'],
|
||||
$sanitizedError,
|
||||
'see https://curl.haxx.se/libcurl/c/libcurl-errors.html'
|
||||
);
|
||||
$uriString = (string) $easy->request->getUri();
|
||||
if ($uriString !== '' && false === \strpos($ctx['error'], $uriString)) {
|
||||
$message .= \sprintf(' for %s', $uriString);
|
||||
|
||||
if ('' !== $sanitizedError) {
|
||||
$redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
|
||||
if ($redactedUriString !== '' && false === \strpos($sanitizedError, $redactedUriString)) {
|
||||
$message .= \sprintf(' for %s', $redactedUriString);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a connection exception if it was a specific error code.
|
||||
@@ -213,6 +280,24 @@ class CurlFactory implements CurlFactoryInterface
|
||||
return P\Create::rejectionFor($error);
|
||||
}
|
||||
|
||||
private static function sanitizeCurlError(string $error, UriInterface $uri): string
|
||||
{
|
||||
if ('' === $error) {
|
||||
return $error;
|
||||
}
|
||||
|
||||
$baseUri = $uri->withQuery('')->withFragment('');
|
||||
$baseUriString = $baseUri->__toString();
|
||||
|
||||
if ('' === $baseUriString) {
|
||||
return $error;
|
||||
}
|
||||
|
||||
$redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
|
||||
|
||||
return str_replace($baseUriString, $redactedUriString, $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
@@ -232,10 +317,11 @@ class CurlFactory implements CurlFactoryInterface
|
||||
}
|
||||
|
||||
$version = $easy->request->getProtocolVersion();
|
||||
if ($version == 1.1) {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
|
||||
} elseif ($version == 2.0) {
|
||||
|
||||
if ('2' === $version || '2.0' === $version) {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
|
||||
} elseif ('1.1' === $version) {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
|
||||
} else {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0;
|
||||
}
|
||||
@@ -390,8 +476,10 @@ class CurlFactory implements CurlFactoryInterface
|
||||
// The empty string enables all available decoders and implicitly
|
||||
// sets a matching 'Accept-Encoding' header.
|
||||
$conf[\CURLOPT_ENCODING] = '';
|
||||
// But as the user did not specify any acceptable encodings we need
|
||||
// to overwrite this implicit header with an empty one.
|
||||
// But as the user did not specify any encoding preference,
|
||||
// let's leave it up to server by preventing curl from sending
|
||||
// the header, which will be interpreted as 'Accept-Encoding: *'.
|
||||
// https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
|
||||
$conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
|
||||
}
|
||||
}
|
||||
@@ -455,23 +543,35 @@ class CurlFactory implements CurlFactoryInterface
|
||||
}
|
||||
|
||||
if (isset($options['crypto_method'])) {
|
||||
if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
|
||||
if (!defined('CURL_SSLVERSION_TLSv1_0')) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.0 not supported by your version of cURL');
|
||||
$protocolVersion = $easy->request->getProtocolVersion();
|
||||
|
||||
// If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
|
||||
if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
|
||||
if (
|
||||
\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']
|
||||
|| \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']
|
||||
|| \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']
|
||||
) {
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
|
||||
} elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
|
||||
if (!self::supportsTls13()) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
|
||||
}
|
||||
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
|
||||
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
|
||||
if (!defined('CURL_SSLVERSION_TLSv1_1')) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.1 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
|
||||
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
|
||||
if (!defined('CURL_SSLVERSION_TLSv1_2')) {
|
||||
if (!self::supportsTls12()) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
|
||||
} elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
|
||||
if (!defined('CURL_SSLVERSION_TLSv1_3')) {
|
||||
if (!self::supportsTls13()) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
|
||||
@@ -631,7 +731,10 @@ class CurlFactory implements CurlFactoryInterface
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->handles as $id => $handle) {
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
\curl_close($handle);
|
||||
}
|
||||
|
||||
unset($this->handles[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace GuzzleHttp\Handler;
|
||||
|
||||
use Closure;
|
||||
use GuzzleHttp\Promise as P;
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
@@ -159,6 +160,9 @@ class CurlMultiHandler
|
||||
}
|
||||
}
|
||||
|
||||
// Run curl_multi_exec in the queue to enable other async tasks to run
|
||||
P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
|
||||
|
||||
// Step through the task queue which may add additional requests.
|
||||
P\Utils::queue()->run();
|
||||
|
||||
@@ -169,11 +173,24 @@ class CurlMultiHandler
|
||||
}
|
||||
|
||||
while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
|
||||
// Prevent busy looping for slow HTTP requests.
|
||||
\curl_multi_select($this->_mh, $this->selectTimeout);
|
||||
}
|
||||
|
||||
$this->processMessages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs \curl_multi_exec() inside the event loop, to prevent busy looping
|
||||
*/
|
||||
private function tickInQueue(): void
|
||||
{
|
||||
if (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
|
||||
\curl_multi_select($this->_mh, 0);
|
||||
P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs until all outstanding connections have completed.
|
||||
*/
|
||||
@@ -223,7 +240,10 @@ class CurlMultiHandler
|
||||
$handle = $this->handles[$id]['easy']->handle;
|
||||
unset($this->delays[$id], $this->handles[$id]);
|
||||
\curl_multi_remove_handle($this->_mh, $handle);
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
\curl_close($handle);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,21 +52,21 @@ class MockHandler implements \Countable
|
||||
* @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
|
||||
* @param callable|null $onRejected Callback to invoke when the return value is rejected.
|
||||
*/
|
||||
public static function createWithMiddleware(array $queue = null, callable $onFulfilled = null, callable $onRejected = null): HandlerStack
|
||||
public static function createWithMiddleware(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null): HandlerStack
|
||||
{
|
||||
return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
|
||||
}
|
||||
|
||||
/**
|
||||
* The passed in value must be an array of
|
||||
* {@see \Psr\Http\Message\ResponseInterface} objects, Exceptions,
|
||||
* {@see ResponseInterface} objects, Exceptions,
|
||||
* callables, or Promises.
|
||||
*
|
||||
* @param array<int, mixed>|null $queue The parameters to be passed to the append function, as an indexed array.
|
||||
* @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
|
||||
* @param callable|null $onRejected Callback to invoke when the return value is rejected.
|
||||
*/
|
||||
public function __construct(array $queue = null, callable $onFulfilled = null, callable $onRejected = null)
|
||||
public function __construct(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null)
|
||||
{
|
||||
$this->onFulfilled = $onFulfilled;
|
||||
$this->onRejected = $onRejected;
|
||||
@@ -200,7 +200,7 @@ class MockHandler implements \Countable
|
||||
private function invokeStats(
|
||||
RequestInterface $request,
|
||||
array $options,
|
||||
ResponseInterface $response = null,
|
||||
?ResponseInterface $response = null,
|
||||
$reason = null
|
||||
): void {
|
||||
if (isset($options['on_stats'])) {
|
||||
|
||||
@@ -17,10 +17,10 @@ class Proxy
|
||||
* Sends synchronous requests to a specific handler while sending all other
|
||||
* requests to another handler.
|
||||
*
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for normal responses
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $sync Handler used for synchronous responses.
|
||||
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for normal responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $sync Handler used for synchronous responses.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
|
||||
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
|
||||
*/
|
||||
public static function wrapSync(callable $default, callable $sync): callable
|
||||
{
|
||||
@@ -37,10 +37,10 @@ class Proxy
|
||||
* performance benefits of curl while still supporting true streaming
|
||||
* through the StreamHandler.
|
||||
*
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for non-streaming responses
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $streaming Handler used for streaming responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for non-streaming responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $streaming Handler used for streaming responses
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
|
||||
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
|
||||
*/
|
||||
public static function wrapStreaming(callable $default, callable $streaming): callable
|
||||
{
|
||||
|
||||
@@ -40,6 +40,12 @@ class StreamHandler
|
||||
\usleep($options['delay'] * 1000);
|
||||
}
|
||||
|
||||
$protocolVersion = $request->getProtocolVersion();
|
||||
|
||||
if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
|
||||
throw new ConnectException(sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);
|
||||
}
|
||||
|
||||
$startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
|
||||
|
||||
try {
|
||||
@@ -47,8 +53,14 @@ class StreamHandler
|
||||
$request = $request->withoutHeader('Expect');
|
||||
|
||||
// Append a content-length header if body size is zero to match
|
||||
// cURL's behavior.
|
||||
if (0 === $request->getBody()->getSize()) {
|
||||
// the behavior of `CurlHandler`
|
||||
if (
|
||||
(
|
||||
0 === \strcasecmp('PUT', $request->getMethod())
|
||||
|| 0 === \strcasecmp('POST', $request->getMethod())
|
||||
)
|
||||
&& 0 === $request->getBody()->getSize()
|
||||
) {
|
||||
$request = $request->withHeader('Content-Length', '0');
|
||||
}
|
||||
|
||||
@@ -83,8 +95,8 @@ class StreamHandler
|
||||
array $options,
|
||||
RequestInterface $request,
|
||||
?float $startTime,
|
||||
ResponseInterface $response = null,
|
||||
\Throwable $error = null
|
||||
?ResponseInterface $response = null,
|
||||
?\Throwable $error = null
|
||||
): void {
|
||||
if (isset($options['on_stats'])) {
|
||||
$stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []);
|
||||
@@ -273,7 +285,7 @@ class StreamHandler
|
||||
|
||||
// HTTP/1.1 streams using the PHP stream wrapper require a
|
||||
// Connection: close header
|
||||
if ($request->getProtocolVersion() == '1.1'
|
||||
if ($request->getProtocolVersion() === '1.1'
|
||||
&& !$request->hasHeader('Connection')
|
||||
) {
|
||||
$request = $request->withHeader('Connection', 'close');
|
||||
@@ -321,8 +333,15 @@ class StreamHandler
|
||||
);
|
||||
|
||||
return $this->createResource(
|
||||
function () use ($uri, &$http_response_header, $contextResource, $context, $options, $request) {
|
||||
function () use ($uri, $contextResource, $context, $options, $request) {
|
||||
$resource = @\fopen((string) $uri, 'r', false, $contextResource);
|
||||
|
||||
// See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable
|
||||
if (function_exists('http_get_last_response_headers')) {
|
||||
/** @var array|null */
|
||||
$http_response_header = \http_get_last_response_headers();
|
||||
}
|
||||
|
||||
$this->lastHeaders = $http_response_header ?? [];
|
||||
|
||||
if (false === $resource) {
|
||||
|
||||
@@ -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');
|
||||
@@ -58,7 +58,7 @@ class HandlerStack
|
||||
/**
|
||||
* @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler.
|
||||
*/
|
||||
public function __construct(callable $handler = null)
|
||||
public function __construct(?callable $handler = null)
|
||||
{
|
||||
$this->handler = $handler;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = [];
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ final class Middleware
|
||||
*
|
||||
* @return callable(callable): callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function httpErrors(BodySummarizerInterface $bodySummarizer = null): callable
|
||||
public static function httpErrors(?BodySummarizerInterface $bodySummarizer = null): callable
|
||||
{
|
||||
return static function (callable $handler) use ($bodySummarizer): callable {
|
||||
return static function ($request, array $options) use ($handler, $bodySummarizer) {
|
||||
@@ -132,7 +132,7 @@ final class Middleware
|
||||
*
|
||||
* @return callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function tap(callable $before = null, callable $after = null): callable
|
||||
public static function tap(?callable $before = null, ?callable $after = null): callable
|
||||
{
|
||||
return static function (callable $handler) use ($before, $after): callable {
|
||||
return static function (RequestInterface $request, array $options) use ($handler, $before, $after) {
|
||||
@@ -176,7 +176,7 @@ final class Middleware
|
||||
*
|
||||
* @return callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function retry(callable $decider, callable $delay = null): callable
|
||||
public static function retry(callable $decider, ?callable $delay = null): callable
|
||||
{
|
||||
return static function (callable $handler) use ($decider, $delay): RetryMiddleware {
|
||||
return new RetryMiddleware($decider, $handler, $delay);
|
||||
@@ -187,12 +187,12 @@ final class Middleware
|
||||
* Middleware that logs requests, responses, and errors using a message
|
||||
* formatter.
|
||||
*
|
||||
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
|
||||
*
|
||||
* @param LoggerInterface $logger Logs messages.
|
||||
* @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings.
|
||||
* @param string $logLevel Level at which to log requests.
|
||||
*
|
||||
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
|
||||
*
|
||||
* @return callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info'): callable
|
||||
|
||||
@@ -86,7 +86,7 @@ class Pool implements PromisorInterface
|
||||
* @param ClientInterface $client Client used to send the requests
|
||||
* @param array|\Iterator $requests Requests to send concurrently.
|
||||
* @param array $options Passes through the options available in
|
||||
* {@see \GuzzleHttp\Pool::__construct}
|
||||
* {@see Pool::__construct}
|
||||
*
|
||||
* @return array Returns an array containing the response or an exception
|
||||
* in the same order that the requests were sent.
|
||||
|
||||
@@ -76,8 +76,8 @@ class PrepareBodyMiddleware
|
||||
|
||||
$expect = $options['expect'] ?? null;
|
||||
|
||||
// Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0
|
||||
if ($expect === false || $request->getProtocolVersion() < 1.1) {
|
||||
// Return if disabled or using HTTP/1.0
|
||||
if ($expect === false || $request->getProtocolVersion() === '1.0') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ final class RequestOptions
|
||||
* Specifies whether or not cookies are used in a request or what cookie
|
||||
* jar to use or what cookies to send. This option only works if your
|
||||
* handler has the `cookie` middleware. Valid values are `false` and
|
||||
* an instance of {@see \GuzzleHttp\Cookie\CookieJarInterface}.
|
||||
* an instance of {@see Cookie\CookieJarInterface}.
|
||||
*/
|
||||
public const COOKIES = 'cookies';
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class RetryMiddleware
|
||||
* and returns the number of
|
||||
* milliseconds to delay.
|
||||
*/
|
||||
public function __construct(callable $decider, callable $nextHandler, callable $delay = null)
|
||||
public function __construct(callable $decider, callable $nextHandler, ?callable $delay = null)
|
||||
{
|
||||
$this->decider = $decider;
|
||||
$this->nextHandler = $nextHandler;
|
||||
@@ -110,7 +110,7 @@ class RetryMiddleware
|
||||
};
|
||||
}
|
||||
|
||||
private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null): PromiseInterface
|
||||
private function doRetry(RequestInterface $request, array $options, ?ResponseInterface $response = null): PromiseInterface
|
||||
{
|
||||
$options['delay'] = ($this->delay)(++$options['retries'], $response, $request);
|
||||
|
||||
|
||||
@@ -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 = []
|
||||
) {
|
||||
|
||||
@@ -71,7 +71,7 @@ final class Utils
|
||||
return \STDOUT;
|
||||
}
|
||||
|
||||
return \GuzzleHttp\Psr7\Utils::tryFopen('php://output', 'w');
|
||||
return Psr7\Utils::tryFopen('php://output', 'w');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ final class Utils
|
||||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*/
|
||||
@@ -87,7 +87,7 @@ final class Utils
|
||||
{
|
||||
$handler = null;
|
||||
|
||||
if (\defined('CURLOPT_CUSTOMREQUEST')) {
|
||||
if (\defined('CURLOPT_CUSTOMREQUEST') && \function_exists('curl_version') && version_compare(curl_version()['version'], '7.21.2') >= 0) {
|
||||
if (\function_exists('curl_multi_exec') && \function_exists('curl_exec')) {
|
||||
$handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
|
||||
} elseif (\function_exists('curl_exec')) {
|
||||
|
||||
@@ -50,7 +50,7 @@ function debug_resource($value = null)
|
||||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,41 @@
|
||||
# CHANGELOG
|
||||
|
||||
|
||||
## 2.3.0 - 2025-08-22
|
||||
|
||||
### Added
|
||||
|
||||
- PHP 8.5 support
|
||||
|
||||
|
||||
## 2.2.0 - 2025-03-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Revert "Allow an empty EachPromise to be resolved by running the queue"
|
||||
|
||||
|
||||
## 2.1.0 - 2025-03-27
|
||||
|
||||
### Added
|
||||
|
||||
- Allow an empty EachPromise to be resolved by running the queue
|
||||
|
||||
|
||||
## 2.0.4 - 2024-10-17
|
||||
|
||||
### Fixed
|
||||
|
||||
- Once settled, don't allow further rejection of additional promises
|
||||
|
||||
|
||||
## 2.0.3 - 2024-07-18
|
||||
|
||||
### Changed
|
||||
|
||||
- PHP 8.4 support
|
||||
|
||||
|
||||
## 2.0.2 - 2023-12-03
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -39,9 +39,9 @@ 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 |
|
||||
|---------|---------------------|--------------|
|
||||
| 1.x | Security fixes only | >=5.5,<8.3 |
|
||||
| 2.x | Latest | >=7.2.5,<8.6 |
|
||||
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
|
||||
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
@@ -84,8 +84,8 @@ final class Coroutine implements PromiseInterface
|
||||
}
|
||||
|
||||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null
|
||||
): PromiseInterface {
|
||||
return $this->result->then($onFulfilled, $onRejected);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ final class Each
|
||||
*/
|
||||
public static function of(
|
||||
$iterable,
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null
|
||||
): PromiseInterface {
|
||||
return (new EachPromise($iterable, [
|
||||
'fulfilled' => $onFulfilled,
|
||||
@@ -46,8 +46,8 @@ final class Each
|
||||
public static function ofLimit(
|
||||
$iterable,
|
||||
$concurrency,
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null
|
||||
): PromiseInterface {
|
||||
return (new EachPromise($iterable, [
|
||||
'fulfilled' => $onFulfilled,
|
||||
@@ -67,7 +67,7 @@ final class Each
|
||||
public static function ofLimitAll(
|
||||
$iterable,
|
||||
$concurrency,
|
||||
callable $onFulfilled = null
|
||||
?callable $onFulfilled = null
|
||||
): PromiseInterface {
|
||||
return self::ofLimit(
|
||||
$iterable,
|
||||
|
||||
@@ -31,8 +31,8 @@ class FulfilledPromise implements PromiseInterface
|
||||
}
|
||||
|
||||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null
|
||||
): PromiseInterface {
|
||||
// Return itself if there is no onFulfilled function.
|
||||
if (!$onFulfilled) {
|
||||
|
||||
@@ -25,16 +25,16 @@ class Promise implements PromiseInterface
|
||||
* @param callable $cancelFn Fn that when invoked cancels the promise.
|
||||
*/
|
||||
public function __construct(
|
||||
callable $waitFn = null,
|
||||
callable $cancelFn = null
|
||||
?callable $waitFn = null,
|
||||
?callable $cancelFn = null
|
||||
) {
|
||||
$this->waitFn = $waitFn;
|
||||
$this->cancelFn = $cancelFn;
|
||||
}
|
||||
|
||||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null
|
||||
): PromiseInterface {
|
||||
if ($this->state === self::PENDING) {
|
||||
$p = new Promise(null, [$this, 'cancel']);
|
||||
|
||||
@@ -27,8 +27,8 @@ interface PromiseInterface
|
||||
* @param callable $onRejected Invoked when the promise is rejected.
|
||||
*/
|
||||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null
|
||||
): PromiseInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,8 +31,8 @@ class RejectedPromise implements PromiseInterface
|
||||
}
|
||||
|
||||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
?callable $onFulfilled = null,
|
||||
?callable $onRejected = null
|
||||
): PromiseInterface {
|
||||
// If there's no onRejected callback then just return self.
|
||||
if (!$onRejected) {
|
||||
|
||||
@@ -18,7 +18,7 @@ class RejectionException extends \RuntimeException
|
||||
* @param mixed $reason Rejection reason.
|
||||
* @param string|null $description Optional description.
|
||||
*/
|
||||
public function __construct($reason, string $description = null)
|
||||
public function __construct($reason, ?string $description = null)
|
||||
{
|
||||
$this->reason = $reason;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ final class Utils
|
||||
*
|
||||
* @param TaskQueueInterface|null $assign Optionally specify a new queue instance.
|
||||
*/
|
||||
public static function queue(TaskQueueInterface $assign = null): TaskQueueInterface
|
||||
public static function queue(?TaskQueueInterface $assign = null): TaskQueueInterface
|
||||
{
|
||||
static $queue;
|
||||
|
||||
@@ -144,8 +144,10 @@ final class Utils
|
||||
$results[$idx] = $value;
|
||||
},
|
||||
function ($reason, $idx, Promise $aggregate): void {
|
||||
if (Is::pending($aggregate)) {
|
||||
$aggregate->reject($reason);
|
||||
}
|
||||
}
|
||||
)->then(function () use (&$results) {
|
||||
ksort($results);
|
||||
|
||||
|
||||
@@ -5,6 +5,43 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 2.8.0 - 2025-08-23
|
||||
|
||||
### Added
|
||||
|
||||
- Allow empty lists as header values
|
||||
|
||||
### Changed
|
||||
|
||||
- PHP 8.5 support
|
||||
|
||||
## 2.7.1 - 2025-03-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed uppercase IPv6 addresses in URI
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve uploaded file error message
|
||||
|
||||
## 2.7.0 - 2024-07-18
|
||||
|
||||
### Added
|
||||
|
||||
- Add `Utils::redactUserInfo()` method
|
||||
- Add ability to encode bools as ints in `Query::build`
|
||||
|
||||
## 2.6.3 - 2024-07-18
|
||||
|
||||
### Fixed
|
||||
|
||||
- Make `StreamWrapper::stream_stat()` return `false` if inner stream's size is `null`
|
||||
|
||||
### Changed
|
||||
|
||||
- PHP 8.4 support
|
||||
|
||||
## 2.6.2 - 2023-12-03
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -24,8 +24,8 @@ composer require guzzlehttp/psr7
|
||||
|
||||
| Version | Status | PHP Version |
|
||||
|---------|---------------------|--------------|
|
||||
| 1.x | Security fixes only | >=5.4,<8.1 |
|
||||
| 2.x | Latest | >=7.2.5,<8.4 |
|
||||
| 1.x | EOL (2024-06-30) | >=5.4,<8.2 |
|
||||
| 2.x | Latest | >=7.2.5,<8.6 |
|
||||
|
||||
|
||||
## AppendStream
|
||||
@@ -436,7 +436,7 @@ will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
|
||||
|
||||
## `GuzzleHttp\Psr7\Query::build`
|
||||
|
||||
`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986): string`
|
||||
`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986, bool $treatBoolsAsInts = true): string`
|
||||
|
||||
Build a query string from an array of key value pairs.
|
||||
|
||||
@@ -498,11 +498,18 @@ a message.
|
||||
|
||||
## `GuzzleHttp\Psr7\Utils::readLine`
|
||||
|
||||
`public static function readLine(StreamInterface $stream, int $maxLength = null): string`
|
||||
`public static function readLine(StreamInterface $stream, ?int $maxLength = null): string`
|
||||
|
||||
Read a line from the stream up to the maximum allowed buffer length.
|
||||
|
||||
|
||||
## `GuzzleHttp\Psr7\Utils::redactUserInfo`
|
||||
|
||||
`public static function redactUserInfo(UriInterface $uri): UriInterface`
|
||||
|
||||
Redact the password in the user info part of a URI.
|
||||
|
||||
|
||||
## `GuzzleHttp\Psr7\Utils::streamFor`
|
||||
|
||||
`public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface`
|
||||
@@ -674,7 +681,7 @@ termed a relative-path reference.
|
||||
|
||||
### `GuzzleHttp\Psr7\Uri::isSameDocumentReference`
|
||||
|
||||
`public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool`
|
||||
`public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool`
|
||||
|
||||
Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its
|
||||
fragment component, identical to the base URI. When no base URI is given, only an empty URI reference
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"http-interop/http-factory-tests": "^0.9",
|
||||
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
|
||||
"http-interop/http-factory-tests": "0.9.0",
|
||||
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
|
||||
},
|
||||
"suggest": {
|
||||
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
||||
|
||||
@@ -33,7 +33,7 @@ final class CachingStream implements StreamInterface
|
||||
*/
|
||||
public function __construct(
|
||||
StreamInterface $stream,
|
||||
StreamInterface $target = null
|
||||
?StreamInterface $target = null
|
||||
) {
|
||||
$this->remoteStream = $stream;
|
||||
$this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+'));
|
||||
|
||||
@@ -27,10 +27,10 @@ final class HttpFactory implements RequestFactoryInterface, ResponseFactoryInter
|
||||
{
|
||||
public function createUploadedFile(
|
||||
StreamInterface $stream,
|
||||
int $size = null,
|
||||
?int $size = null,
|
||||
int $error = \UPLOAD_ERR_OK,
|
||||
string $clientFilename = null,
|
||||
string $clientMediaType = null
|
||||
?string $clientFilename = null,
|
||||
?string $clientMediaType = null
|
||||
): UploadedFileInterface {
|
||||
if ($size === null) {
|
||||
$size = $stream->getSize();
|
||||
|
||||
@@ -174,10 +174,6 @@ trait MessageTrait
|
||||
return $this->trimAndValidateHeaderValues([$value]);
|
||||
}
|
||||
|
||||
if (count($value) === 0) {
|
||||
throw new \InvalidArgumentException('Header value can not be an empty array.');
|
||||
}
|
||||
|
||||
return $this->trimAndValidateHeaderValues($value);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ final class MultipartStream implements StreamInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $elements = [], string $boundary = null)
|
||||
public function __construct(array $elements = [], ?string $boundary = null)
|
||||
{
|
||||
$this->boundary = $boundary ?: bin2hex(random_bytes(20));
|
||||
$this->stream = $this->createStream($elements);
|
||||
|
||||
@@ -64,11 +64,14 @@ final class Query
|
||||
* encountered (like `http_build_query()` would).
|
||||
*
|
||||
* @param array $params Query string parameters.
|
||||
* @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
|
||||
* to encode using RFC3986, or PHP_QUERY_RFC1738
|
||||
* to encode using RFC1738.
|
||||
* @param int|false $encoding Set to false to not encode,
|
||||
* PHP_QUERY_RFC3986 to encode using
|
||||
* RFC3986, or PHP_QUERY_RFC1738 to
|
||||
* encode using RFC1738.
|
||||
* @param bool $treatBoolsAsInts Set to true to encode as 0/1, and
|
||||
* false as false/true.
|
||||
*/
|
||||
public static function build(array $params, $encoding = PHP_QUERY_RFC3986): string
|
||||
public static function build(array $params, $encoding = PHP_QUERY_RFC3986, bool $treatBoolsAsInts = true): string
|
||||
{
|
||||
if (!$params) {
|
||||
return '';
|
||||
@@ -86,12 +89,14 @@ final class Query
|
||||
throw new \InvalidArgumentException('Invalid type');
|
||||
}
|
||||
|
||||
$castBool = $treatBoolsAsInts ? static function ($v) { return (int) $v; } : static function ($v) { return $v ? 'true' : 'false'; };
|
||||
|
||||
$qs = '';
|
||||
foreach ($params as $k => $v) {
|
||||
$k = $encoder((string) $k);
|
||||
if (!is_array($v)) {
|
||||
$qs .= $k;
|
||||
$v = is_bool($v) ? (int) $v : $v;
|
||||
$v = is_bool($v) ? $castBool($v) : $v;
|
||||
if ($v !== null) {
|
||||
$qs .= '='.$encoder((string) $v);
|
||||
}
|
||||
@@ -99,7 +104,7 @@ final class Query
|
||||
} else {
|
||||
foreach ($v as $vv) {
|
||||
$qs .= $k;
|
||||
$vv = is_bool($vv) ? (int) $vv : $vv;
|
||||
$vv = is_bool($vv) ? $castBool($vv) : $vv;
|
||||
if ($vv !== null) {
|
||||
$qs .= '='.$encoder((string) $vv);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ class Response implements ResponseInterface
|
||||
array $headers = [],
|
||||
$body = null,
|
||||
string $version = '1.1',
|
||||
string $reason = null
|
||||
?string $reason = null
|
||||
) {
|
||||
$this->assertStatusCodeRange($status);
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ final class StreamWrapper
|
||||
}
|
||||
}
|
||||
|
||||
public function stream_open(string $path, string $mode, int $options, string &$opened_path = null): bool
|
||||
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path = null): bool
|
||||
{
|
||||
$options = stream_context_get_options($this->context);
|
||||
|
||||
@@ -136,10 +136,14 @@ final class StreamWrapper
|
||||
* ctime: int,
|
||||
* blksize: int,
|
||||
* blocks: int
|
||||
* }
|
||||
* }|false
|
||||
*/
|
||||
public function stream_stat(): array
|
||||
public function stream_stat()
|
||||
{
|
||||
if ($this->stream->getSize() === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static $modeMap = [
|
||||
'r' => 33060,
|
||||
'rb' => 33060,
|
||||
|
||||
@@ -11,15 +11,15 @@ use RuntimeException;
|
||||
|
||||
class UploadedFile implements UploadedFileInterface
|
||||
{
|
||||
private const ERRORS = [
|
||||
UPLOAD_ERR_OK,
|
||||
UPLOAD_ERR_INI_SIZE,
|
||||
UPLOAD_ERR_FORM_SIZE,
|
||||
UPLOAD_ERR_PARTIAL,
|
||||
UPLOAD_ERR_NO_FILE,
|
||||
UPLOAD_ERR_NO_TMP_DIR,
|
||||
UPLOAD_ERR_CANT_WRITE,
|
||||
UPLOAD_ERR_EXTENSION,
|
||||
private const ERROR_MAP = [
|
||||
UPLOAD_ERR_OK => 'UPLOAD_ERR_OK',
|
||||
UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE',
|
||||
UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE',
|
||||
UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL',
|
||||
UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE',
|
||||
UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR',
|
||||
UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE',
|
||||
UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -64,8 +64,8 @@ class UploadedFile implements UploadedFileInterface
|
||||
$streamOrFile,
|
||||
?int $size,
|
||||
int $errorStatus,
|
||||
string $clientFilename = null,
|
||||
string $clientMediaType = null
|
||||
?string $clientFilename = null,
|
||||
?string $clientMediaType = null
|
||||
) {
|
||||
$this->setError($errorStatus);
|
||||
$this->size = $size;
|
||||
@@ -104,7 +104,7 @@ class UploadedFile implements UploadedFileInterface
|
||||
*/
|
||||
private function setError(int $error): void
|
||||
{
|
||||
if (false === in_array($error, UploadedFile::ERRORS, true)) {
|
||||
if (!isset(UploadedFile::ERROR_MAP[$error])) {
|
||||
throw new InvalidArgumentException(
|
||||
'Invalid error status for UploadedFile'
|
||||
);
|
||||
@@ -137,7 +137,7 @@ class UploadedFile implements UploadedFileInterface
|
||||
private function validateActive(): void
|
||||
{
|
||||
if (false === $this->isOk()) {
|
||||
throw new RuntimeException('Cannot retrieve stream due to upload error');
|
||||
throw new RuntimeException(\sprintf('Cannot retrieve stream due to upload error (%s)', self::ERROR_MAP[$this->error]));
|
||||
}
|
||||
|
||||
if ($this->isMoved()) {
|
||||
|
||||
@@ -107,7 +107,7 @@ class Uri implements UriInterface, \JsonSerializable
|
||||
{
|
||||
// If IPv6
|
||||
$prefix = '';
|
||||
if (preg_match('%^(.*://\[[0-9:a-f]+\])(.*?)$%', $url, $matches)) {
|
||||
if (preg_match('%^(.*://\[[0-9:a-fA-F]+\])(.*?)$%', $url, $matches)) {
|
||||
/** @var array{0:string, 1:string, 2:string} $matches */
|
||||
$prefix = $matches[1];
|
||||
$url = $matches[2];
|
||||
@@ -279,7 +279,7 @@ class Uri implements UriInterface, \JsonSerializable
|
||||
*
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4
|
||||
*/
|
||||
public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool
|
||||
public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool
|
||||
{
|
||||
if ($base !== null) {
|
||||
$uri = UriResolver::resolve($base, $uri);
|
||||
|
||||
@@ -231,7 +231,7 @@ final class Utils
|
||||
* @param StreamInterface $stream Stream to read from
|
||||
* @param int|null $maxLength Maximum buffer length
|
||||
*/
|
||||
public static function readLine(StreamInterface $stream, int $maxLength = null): string
|
||||
public static function readLine(StreamInterface $stream, ?int $maxLength = null): string
|
||||
{
|
||||
$buffer = '';
|
||||
$size = 0;
|
||||
@@ -250,6 +250,20 @@ final class Utils
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redact the password in the user info part of a URI.
|
||||
*/
|
||||
public static function redactUserInfo(UriInterface $uri): UriInterface
|
||||
{
|
||||
$userInfo = $uri->getUserInfo();
|
||||
|
||||
if (false !== ($pos = \strpos($userInfo, ':'))) {
|
||||
return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new stream based on the input type.
|
||||
*
|
||||
@@ -383,7 +397,7 @@ final class Utils
|
||||
restore_error_handler();
|
||||
|
||||
if ($ex) {
|
||||
/** @var $ex \RuntimeException */
|
||||
/** @var \RuntimeException $ex */
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
@@ -430,7 +444,7 @@ final class Utils
|
||||
restore_error_handler();
|
||||
|
||||
if ($ex) {
|
||||
/** @var $ex \RuntimeException */
|
||||
/** @var \RuntimeException $ex */
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2020 Alex Bilbie <hello@alexbilbie.com>
|
||||
Copyright (c) 2013-2023 Alex Bilbie <hello@alexbilbie.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -24,14 +24,15 @@ This package is compliant with [PSR-1][], [PSR-2][], [PSR-4][], and [PSR-7][]. I
|
||||
|
||||
We support the following versions of PHP:
|
||||
|
||||
* PHP 8.4
|
||||
* PHP 8.3
|
||||
* PHP 8.2
|
||||
* PHP 8.1
|
||||
* PHP 8.0
|
||||
* PHP 7.4
|
||||
* PHP 7.3
|
||||
* PHP 7.2
|
||||
* PHP 7.1
|
||||
* PHP 7.0
|
||||
* PHP 5.6
|
||||
|
||||
## Provider Clients
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
"sort-packages": true
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0 || ^8.0",
|
||||
"guzzlehttp/guzzle": "^6.0 || ^7.0",
|
||||
"paragonie/random_compat": "^1 || ^2 || ^9.99"
|
||||
"php": "^7.1 || >=8.0.0 <8.5.0",
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "^6.5.8 || ^7.4.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.3.5",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.1",
|
||||
"phpunit/phpunit": "^5.7 || ^6.0 || ^9.5",
|
||||
"squizlabs/php_codesniffer": "^2.3 || ^3.0"
|
||||
"php-parallel-lint/php-parallel-lint": "^1.4",
|
||||
"phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
|
||||
"squizlabs/php_codesniffer": "^3.11"
|
||||
},
|
||||
"keywords": [
|
||||
"oauth",
|
||||
@@ -49,10 +49,5 @@
|
||||
"psr-4": {
|
||||
"League\\OAuth2\\Client\\Test\\": "test/src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-2.x": "2.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace League\OAuth2\Client\Provider;
|
||||
use GuzzleHttp\Client as HttpClient;
|
||||
use GuzzleHttp\ClientInterface as HttpClientInterface;
|
||||
use GuzzleHttp\Exception\BadResponseException;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use InvalidArgumentException;
|
||||
use League\OAuth2\Client\Grant\AbstractGrant;
|
||||
use League\OAuth2\Client\Grant\GrantFactory;
|
||||
@@ -405,6 +406,7 @@ abstract class AbstractProvider
|
||||
*
|
||||
* @param array $options
|
||||
* @return array Authorization parameters
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function getAuthorizationParameters(array $options)
|
||||
{
|
||||
@@ -476,6 +478,7 @@ abstract class AbstractProvider
|
||||
*
|
||||
* @param array $options
|
||||
* @return string Authorization URL
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getAuthorizationUrl(array $options = [])
|
||||
{
|
||||
@@ -492,10 +495,11 @@ abstract class AbstractProvider
|
||||
* @param array $options
|
||||
* @param callable|null $redirectHandler
|
||||
* @return mixed
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function authorize(
|
||||
array $options = [],
|
||||
callable $redirectHandler = null
|
||||
?callable $redirectHandler = null
|
||||
) {
|
||||
$url = $this->getAuthorizationUrl($options);
|
||||
if ($redirectHandler) {
|
||||
@@ -613,13 +617,20 @@ abstract class AbstractProvider
|
||||
*
|
||||
* @param mixed $grant
|
||||
* @param array<string, mixed> $options
|
||||
* @throws IdentityProviderException
|
||||
* @return AccessTokenInterface
|
||||
* @throws IdentityProviderException
|
||||
* @throws UnexpectedValueException
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function getAccessToken($grant, array $options = [])
|
||||
{
|
||||
$grant = $this->verifyGrant($grant);
|
||||
|
||||
if (isset($options['scope']) && is_array($options['scope'])) {
|
||||
$separator = $this->getScopeSeparator();
|
||||
$options['scope'] = implode($separator, $options['scope']);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
@@ -700,6 +711,7 @@ abstract class AbstractProvider
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function getResponse(RequestInterface $request)
|
||||
{
|
||||
@@ -710,8 +722,10 @@ abstract class AbstractProvider
|
||||
* Sends a request and returns the parsed response.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @throws IdentityProviderException
|
||||
* @return mixed
|
||||
* @throws IdentityProviderException
|
||||
* @throws UnexpectedValueException
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function getParsedResponse(RequestInterface $request)
|
||||
{
|
||||
@@ -757,7 +771,7 @@ abstract class AbstractProvider
|
||||
*/
|
||||
protected function getContentType(ResponseInterface $response)
|
||||
{
|
||||
return join(';', (array) $response->getHeader('content-type'));
|
||||
return implode(';', $response->getHeader('content-type'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -815,7 +829,7 @@ abstract class AbstractProvider
|
||||
* Custom mapping of expiration, etc should be done here. Always call the
|
||||
* parent method when overloading this method.
|
||||
*
|
||||
* @param mixed $result
|
||||
* @param array<string, mixed> $result
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareAccessTokenResponse(array $result)
|
||||
@@ -859,6 +873,9 @@ abstract class AbstractProvider
|
||||
*
|
||||
* @param AccessToken $token
|
||||
* @return ResourceOwnerInterface
|
||||
* @throws IdentityProviderException
|
||||
* @throws UnexpectedValueException
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function getResourceOwner(AccessToken $token)
|
||||
{
|
||||
@@ -872,6 +889,9 @@ abstract class AbstractProvider
|
||||
*
|
||||
* @param AccessToken $token
|
||||
* @return mixed
|
||||
* @throws IdentityProviderException
|
||||
* @throws UnexpectedValueException
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
protected function fetchResourceOwnerDetails(AccessToken $token)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ use RuntimeException;
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc6749#section-1.4 Access Token (RFC 6749, §1.4)
|
||||
*/
|
||||
class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInterface
|
||||
class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInterface, SettableRefreshTokenInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
@@ -118,7 +118,7 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter
|
||||
} elseif (!empty($options['expires'])) {
|
||||
// Some providers supply the seconds until expiration rather than
|
||||
// the exact timestamp. Take a best guess at which we received.
|
||||
$expires = $options['expires'];
|
||||
$expires = (int) $options['expires'];
|
||||
|
||||
if (!$this->isExpirationTimestamp($expires)) {
|
||||
$expires += $this->getTimeNow();
|
||||
@@ -169,6 +169,14 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter
|
||||
return $this->refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setRefreshToken($refreshToken)
|
||||
{
|
||||
$this->refreshToken = $refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@@ -196,7 +204,7 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter
|
||||
throw new RuntimeException('"expires" is not set on the token');
|
||||
}
|
||||
|
||||
return $expires < time();
|
||||
return $expires < $this->getTimeNow();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) )
|
||||
|
||||
php -dphar.readonly=0 "$basedir/other/build_phar.php" $*
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"random",
|
||||
"polyfill",
|
||||
"pseudorandom"
|
||||
],
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/paragonie/random_compat/issues",
|
||||
"email": "info@paragonie.com",
|
||||
"source": "https://github.com/paragonie/random_compat"
|
||||
},
|
||||
"require": {
|
||||
"php": ">= 7"
|
||||
},
|
||||
"require-dev": {
|
||||
"vimeo/psalm": "^1",
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm
|
||||
pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p
|
||||
+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -1,11 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v2.0.22 (MingW32)
|
||||
|
||||
iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip
|
||||
QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg
|
||||
1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW
|
||||
NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA
|
||||
NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV
|
||||
JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74=
|
||||
=B6+8
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* @version 2.99.99
|
||||
* @released 2018-06-06
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
// NOP
|
||||
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
$dist = dirname(__DIR__).'/dist';
|
||||
if (!is_dir($dist)) {
|
||||
mkdir($dist, 0755);
|
||||
}
|
||||
if (file_exists($dist.'/random_compat.phar')) {
|
||||
unlink($dist.'/random_compat.phar');
|
||||
}
|
||||
$phar = new Phar(
|
||||
$dist.'/random_compat.phar',
|
||||
FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME,
|
||||
'random_compat.phar'
|
||||
);
|
||||
rename(
|
||||
dirname(__DIR__).'/lib/random.php',
|
||||
dirname(__DIR__).'/lib/index.php'
|
||||
);
|
||||
$phar->buildFromDirectory(dirname(__DIR__).'/lib');
|
||||
rename(
|
||||
dirname(__DIR__).'/lib/index.php',
|
||||
dirname(__DIR__).'/lib/random.php'
|
||||
);
|
||||
|
||||
/**
|
||||
* If we pass an (optional) path to a private key as a second argument, we will
|
||||
* sign the Phar with OpenSSL.
|
||||
*
|
||||
* If you leave this out, it will produce an unsigned .phar!
|
||||
*/
|
||||
if ($argc > 1) {
|
||||
if (!@is_readable($argv[1])) {
|
||||
echo 'Could not read the private key file:', $argv[1], "\n";
|
||||
exit(255);
|
||||
}
|
||||
$pkeyFile = file_get_contents($argv[1]);
|
||||
|
||||
$private = openssl_get_privatekey($pkeyFile);
|
||||
if ($private !== false) {
|
||||
$pkey = '';
|
||||
openssl_pkey_export($private, $pkey);
|
||||
$phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey);
|
||||
|
||||
/**
|
||||
* Save the corresponding public key to the file
|
||||
*/
|
||||
if (!@is_readable($dist.'/random_compat.phar.pubkey')) {
|
||||
$details = openssl_pkey_get_details($private);
|
||||
file_put_contents(
|
||||
$dist.'/random_compat.phar.pubkey',
|
||||
$details['key']
|
||||
);
|
||||
}
|
||||
} else {
|
||||
echo 'An error occurred reading the private key from OpenSSL.', "\n";
|
||||
exit(255);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once 'lib/byte_safe_strings.php';
|
||||
require_once 'lib/cast_to_int.php';
|
||||
require_once 'lib/error_polyfill.php';
|
||||
require_once 'other/ide_stubs/libsodium.php';
|
||||
require_once 'lib/random.php';
|
||||
|
||||
$int = random_int(0, 65536);
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
autoloader="psalm-autoload.php"
|
||||
stopOnFirstError="false"
|
||||
useDocblockTypes="true"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="lib" />
|
||||
</projectFiles>
|
||||
<issueHandlers>
|
||||
<RedundantConditionGivenDocblockType errorLevel="info" />
|
||||
<UnresolvableInclude errorLevel="info" />
|
||||
<DuplicateClass errorLevel="info" />
|
||||
<InvalidOperand errorLevel="info" />
|
||||
<UndefinedConstant errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
<InvalidReturnType errorLevel="info" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
@@ -17,10 +17,5 @@ Included files
|
||||
==============
|
||||
- ``OS/Guess.php``
|
||||
- ``PEAR.php``
|
||||
- ``PEAR/Error.php``
|
||||
- ``PEAR/ErrorStack.php``
|
||||
- ``System.php``
|
||||
|
||||
|
||||
``PEAR/Error.php`` is a dummy file that only includes ``PEAR.php``,
|
||||
to make autoloaders work without problems.
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"": "src/"
|
||||
}
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"src/"
|
||||
@@ -23,6 +23,7 @@
|
||||
},
|
||||
"type": "library",
|
||||
"require": {
|
||||
"php": ">=5.4",
|
||||
"pear/console_getopt": "~1.4",
|
||||
"pear/pear_exception": "~1.0"
|
||||
},
|
||||
|
||||
@@ -245,7 +245,7 @@ class OS_Guess
|
||||
return array();
|
||||
}
|
||||
if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
|
||||
return $this-_parseFeaturesHeaderFile($features_header_file);
|
||||
return $this->_parseFeaturesHeaderFile($features_header_file);
|
||||
} // no cpp
|
||||
|
||||
return $this->_fromGlibCTest();
|
||||
|
||||
@@ -49,7 +49,9 @@ $GLOBALS['_PEAR_destructor_object_list'] = array();
|
||||
$GLOBALS['_PEAR_shutdown_funcs'] = array();
|
||||
$GLOBALS['_PEAR_error_handler_stack'] = array();
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
if(function_exists('ini_set')) {
|
||||
@ini_set('track_errors', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for other PEAR classes. Provides rudimentary
|
||||
@@ -219,7 +221,7 @@ class PEAR
|
||||
);
|
||||
}
|
||||
return call_user_func_array(
|
||||
array(get_class(), '_' . $method),
|
||||
array(__CLASS__, '_' . $method),
|
||||
array_merge(array($this), $arguments)
|
||||
);
|
||||
}
|
||||
@@ -232,7 +234,7 @@ class PEAR
|
||||
);
|
||||
}
|
||||
return call_user_func_array(
|
||||
array(get_class(), '_' . $method),
|
||||
array(__CLASS__, '_' . $method),
|
||||
array_merge(array(null), $arguments)
|
||||
);
|
||||
}
|
||||
@@ -859,6 +861,7 @@ class PEAR_Error
|
||||
var $message = '';
|
||||
var $userinfo = '';
|
||||
var $backtrace = null;
|
||||
var $callback = null;
|
||||
|
||||
/**
|
||||
* PEAR_Error constructor
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Dummy file to make autoloaders work
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PEAR
|
||||
* @package PEAR
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
*/
|
||||
require_once __DIR__ . '/../PEAR.php';
|
||||
?>
|
||||
@@ -3,6 +3,9 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
Please also have a look at our
|
||||
[API and deprecation policy](docs/API-and-deprecation-policy.md).
|
||||
|
||||
## x.y.z
|
||||
|
||||
### Added
|
||||
@@ -15,84 +18,123 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
### Fixed
|
||||
|
||||
## 7.3.0: Add support for PHP 8.4 and CSS custom properties
|
||||
|
||||
### Added
|
||||
|
||||
- Add support for PHP 8.4 (#1278)
|
||||
- Support CSS custom properties (variables) (#1336)
|
||||
- Support `:root` pseudo-class (#1306)
|
||||
- Add CSS selectors exclusion feature (#1236)
|
||||
|
||||
### Changed
|
||||
|
||||
- Require `sabberworm/php-css-parser:^8.7.0` (#1355)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Preserve case of CSS custom property (variable) names (#1332)
|
||||
|
||||
### Documentation
|
||||
|
||||
- Add an API and deprecation policy (#1323)
|
||||
|
||||
## 7.2.0: Add support for Symfony 7
|
||||
|
||||
### Added
|
||||
|
||||
- Add support for Symfony 7 (#1243)
|
||||
|
||||
## 7.1.0: Add support for PHP 8.3
|
||||
|
||||
### Added
|
||||
|
||||
- Add support for PHP 8.3 (#1218)
|
||||
|
||||
### Changed
|
||||
|
||||
- Disable HTML formatting by default (#1214)
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Add support for PHP 8.2 (#1155)
|
||||
|
||||
### Changed
|
||||
|
||||
- Throw exception with invalid CSS in debug mode (#1142)
|
||||
- Only support up to 69 atomic expressions in a selector (#1113)
|
||||
- Require `sabberworm/php-css-parser:^8.4.0` (#1134)
|
||||
- Upgrade to PHPUnit 9 (#1112)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 7.3 will be removed in Emogrifier 8.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for Symfony 3.x and 5.3 (#1120, #1162)
|
||||
- Drop support for PHP 7.2 (#1111)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Bump the minimum Symfony 4.4 version to avoid PHP deprecation warnings (#1187)
|
||||
|
||||
## 6.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Test with Symfony 6-dev (#1109)
|
||||
- Add support for PHP 8.1 (#1103)
|
||||
- Add a dedicated class for caching (#1097)
|
||||
- Allow installation together with Symfony 6 (#1065)
|
||||
- Support more file types in the `.editorconfig` (#1035)
|
||||
- Set `align` attribute of `<th>` elements with `CssToAttributeConverter` (#1008)
|
||||
- Set `align` attribute of `<th>` elements with `CssToAttributeConverter`
|
||||
(#1008)
|
||||
|
||||
### Changed
|
||||
|
||||
- Use `sabberworm/php-css-parser` to parse the CSS (#1015)
|
||||
- Also check the unit test code with Psalm (#1003)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 7.2 will be removed in Emogrifier 7.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove a redundant CSS data cache (#1018)
|
||||
- Drop support for Symfony 5.1 and 5.2 (#972, #1104)
|
||||
- Drop support for PHP 7.1 (#967)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Allow `@import` after ignored invalid `@charset` (@1081)
|
||||
- Allow line feeds within `<html>` tag (#987)
|
||||
|
||||
## 5.0.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Switch the default branch from `master` to `main` (#951)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Ignore `http-equiv` `Content-Type` in `<body>` (#961)
|
||||
- Allow "Content-Type" in content (#959)
|
||||
|
||||
## 5.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Add an `.editorconfig` file (#940)
|
||||
- Support PHP 8.0 (#926)
|
||||
- Run the CI build once a week (#933)
|
||||
- Move more development tools to PHIVE (#894, #907)
|
||||
|
||||
### Changed
|
||||
|
||||
- Automatically add a backslash for global functions (#909)
|
||||
- Update the development tools (#898, #895)
|
||||
- Upgrade to PHPUnit 7.5 (#888)
|
||||
@@ -101,14 +143,17 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- Make use of PHP 7.1 language features (#883)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 7.1 will be removed in Emogrifier 6.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for Symfony 4.3 and 5.0 (#936)
|
||||
- Stop checking `tests/` with Psalm (#885)
|
||||
- Drop support for PHP 7.0 (#880)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix a nonsensical code example in the README (#920, #935)
|
||||
- Remove `!important` from `style` attributes also when uppercase, mixed case or
|
||||
having whitespace after `!` (#911)
|
||||
@@ -122,35 +167,43 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
## 4.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Extract and inject `@font-face` rules into head (#870)
|
||||
- Test tag omission in conformant supplied HTML (#868)
|
||||
- Check for missing return type hint annotations in the code sniffs (#860)
|
||||
- Support `:only-of-type` (with a type) (#849, #856)
|
||||
- Configuration setting methods now all return `$this` to allow chaining (#824, #854)
|
||||
- Configuration setting methods now all return `$this` to allow chaining
|
||||
(#824, #854)
|
||||
- Disable php-cs-fixer Yoda conditions (#791, #794)
|
||||
- Check the code with psalm (#537, #779)
|
||||
- Composer script to run tests with `--stop-on-failure` (#782)
|
||||
- Test universal selector with combinators (#776)
|
||||
|
||||
### Changed
|
||||
- Normalize DOCTYPE declaration according to polyglot markup recommendation (#866)
|
||||
|
||||
- Normalize DOCTYPE declaration according to polyglot markup recommendation
|
||||
(#866)
|
||||
- Upgrade to V2 of the PHP setup GitHub action (#861)
|
||||
- Move the development tools to PHIVE (#850, #851)
|
||||
- Switch the parallel linting to a maintained fork (#842)
|
||||
- Move continuous integration from Travis CI to GitHub actions (#832, #834, #838, #839, #840, #841, #843, #846, #849)
|
||||
- Move continuous integration from Travis CI to GitHub actions
|
||||
(#832, #834, #838, #839, #840, #841, #843, #846, #849)
|
||||
- Clean up the folder structure and autoloading configuration (#529, #785)
|
||||
- Use `self` as the return type for `fromHtml` (#784)
|
||||
- Make use of PHP 7.0 language features (#777)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 7.0 will be removed in Emogrifier 5.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for Symfony versions that have reached their end of life (#847)
|
||||
- Drop the `Emogrifier` class (#774)
|
||||
- Drop support for PHP 5.6 (#773)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Allow `:last-of-type` etc. without type, without causing exception (#875)
|
||||
- Make sure to use the Composer-installed development tools (#862, #865)
|
||||
- Add missing `<head>` element when there's a `<header>` element (#844, #853)
|
||||
@@ -161,22 +214,28 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
## 3.1.0
|
||||
|
||||
### Added
|
||||
|
||||
- Add support for PHP 7.4 (#821, #829)
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade to Symfony 5.0 (#820)
|
||||
|
||||
## 3.0.0
|
||||
|
||||
### Added
|
||||
- Test and document excluding entire subtree with `addExcludedSelector()` (#347, #768)
|
||||
|
||||
- Test and document excluding entire subtree with `addExcludedSelector()`
|
||||
(#347, #768)
|
||||
- Test that rules with `:optional` or `:required` are copied to the `<style>`
|
||||
element (#748, #765)
|
||||
- Test that rules with `:only-of-type` are copied to the `<style>` element (#748, #760)
|
||||
- Test that rules with `:only-of-type` are copied to the `<style>` element
|
||||
(#748, #760)
|
||||
- Support `:last-of-type` (#748, #758)
|
||||
- Support `:first-of-type` (#748, #757)
|
||||
- Support `:empty` (#748, #756)
|
||||
- Test that rules with `:any-link` are copied to the `<style>` element (#748, #755)
|
||||
- Test that rules with `:any-link` are copied to the `<style>` element
|
||||
(#748, #755)
|
||||
- Support and test `:only-child` (#747, #754)
|
||||
- Support and test `:nth-last-of-type` (#747, #751)
|
||||
- Support and test `:nth-last-child` (#747, #750)
|
||||
@@ -195,6 +254,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- Add tests for `:nth-child` and `:nth-of-type` (#71, #698)
|
||||
|
||||
### Changed
|
||||
|
||||
- Relax the dependency on `symfony/css-selector` (#762)
|
||||
- Rename `HtmlPruner::removeInvisibleNodes` to
|
||||
`HtmlPruner::removeElementsWithDisplayNone` (#717, #718)
|
||||
@@ -204,14 +264,17 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- Update the development dependencies (#691)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 5.6 will be removed in Emogrifier 4.0.
|
||||
- Deprecate the `Emogrifier` class (#701)
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop `enableCssToHtmlMapping` and `disableInvisibleNodeRemoval` (#692)
|
||||
- Drop support for PHP 5.5 (#690)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix PhpStorm code inspection warnings (#729, #770)
|
||||
- Uppercase type combined with class or ID in selector (#590, #769)
|
||||
- Dynamic pseudo-class combined with static one (rules copied to `<style>`
|
||||
@@ -226,22 +289,27 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
## 2.2.0
|
||||
|
||||
### Added
|
||||
|
||||
- Add a `HtmlPruner` class (#679)
|
||||
- Add `AbstractHtmlProcessor::fromDomDocument` (#676)
|
||||
- Add `AbstractHtmlProcessor::fromHtml` (#675)
|
||||
|
||||
### Changed
|
||||
|
||||
- Make the closures static (#674)
|
||||
- Keep `<wbr>` elements by default with `CssInliner` (#665)
|
||||
- Make the `CssInliner` inherit `AbstractHtmlProcessor` (#660)
|
||||
- Separate `CssInliner::inlineCss` and the rendering (#654)
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop the removal of unprocessable tags from `CssInliner` (#685)
|
||||
- Drop the removal of invisible nodes from `CssInliner` (#684)
|
||||
|
||||
### Fixed
|
||||
- Remove opening `<body>` tag from `body` content when element has attribute(s) (#677, #683)
|
||||
|
||||
- Remove opening `<body>` tag from `body` content when element has attribute(s)
|
||||
(#677, #683)
|
||||
- Keep development files out of the Composer packages (#678)
|
||||
- Call all static methods statically in `CssConcatenator` (#670)
|
||||
- Support all HTML5 self-closing tags, including `<embed>`, `<source>`,
|
||||
@@ -252,14 +320,17 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
## 2.1.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Add a test that a missing document type gets added (#641)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Keep the `style` element the `head` (#642)
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Added
|
||||
|
||||
- PHP 7.3 support (#638)
|
||||
- Allow PHP 7.3 in `composer.json`
|
||||
- Test in Travis for PHP 7.3
|
||||
@@ -276,17 +347,20 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- Validate the composer.json on Travis (#476)
|
||||
|
||||
### Changed
|
||||
|
||||
- Mark the work-in-progress classes as `@internal` (#640)
|
||||
- Remove the unprocessable tags from the DOM, not from the raw HTML (#627)
|
||||
- Reject empty HTML in `setHtml()` (#622)
|
||||
- Stop passing the DOM document around (#618)
|
||||
- Improve performance by using explicit namespaces for PHP functions (#573, #576)
|
||||
- Improve performance by using explicit namespaces for PHP functions
|
||||
(#573, #576)
|
||||
- Add type hint checking to the code sniffs (#566)
|
||||
- Check the code with PHPMD (#561)
|
||||
- Add the cyclomatic complexity to the checked code sniffs (#558)
|
||||
- Use the Symfony CSS selector component (#540)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 5.5 will be removed in Emogrifier 3.0.
|
||||
- Support for PHP 5.6 will be removed in Emogrifier 4.0.
|
||||
- The removal of invisible nodes will be removed in Emogrifier 3.0. (#473)
|
||||
@@ -300,16 +374,19 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
version 3.0 and removed for version 4.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop the `@version` PHPDoc annotations (#637)
|
||||
- Drop the destructors (#619)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add required XML PHP extension to `composer.json` (#614)
|
||||
- Add required DOM PHP extension to `composer.json` (#595)
|
||||
- Escape hyphens in regular expressions (#588)
|
||||
- Fix Travis for PHP 5.x (#589)
|
||||
- Allow CSS between empty `@media` rule and another `@media` rule (#534)
|
||||
- Allow additional whitespace in media-query-list of disallowed `@media` rules (#532)
|
||||
- Allow additional whitespace in media-query-list of disallowed `@media` rules (
|
||||
#532)
|
||||
- Allow multiple minified `@import` rules in the CSS without error (note:
|
||||
`@import`s are currently ignored, #527)
|
||||
- Style property ordering when multiple mixed individual and shorthand
|
||||
@@ -325,8 +402,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
## 2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Support for CSS :not() selector (#431)
|
||||
- Automatically remove !important annotations from final inline style declarations (#420)
|
||||
- Automatically remove !important annotations from final inline style
|
||||
declarations (#420)
|
||||
- Automatically move `<style>` block from `<head>` to `<body>` (#396)
|
||||
- PHP 7.2 support (#398)
|
||||
- Allow PHP 7.2 in `composer.json`, cleaner PHP version constraint
|
||||
@@ -334,19 +413,23 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- Debug mode. Throw debug exceptions only if debug is active. (#392)
|
||||
|
||||
### Changed
|
||||
|
||||
- Test with latest and oldest dependencies on Travis (#463)
|
||||
- Always enable the debug mode in the tests (#448)
|
||||
- Optimize the string operations (#430)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 5.5 will be removed in Emogrifier 3.0.
|
||||
- Support for PHP 5.6 will be removed in Emogrifier 4.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for PHP 5.4 (#422)
|
||||
- Drop support for HHVM (#386)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Handle invalid/unrecognized selectors in media query blocks (#442)
|
||||
- Throw (the correct) exception for invalid excluded selectors (#437)
|
||||
- emogrifyBody must not encode umlaut entities (#414)
|
||||
@@ -359,19 +442,23 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
## 1.2.0 (2017-03-02)
|
||||
|
||||
### Added
|
||||
|
||||
- Handling invalid xPath expression warnings (#361)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 5.5 will be removed in Emogrifier 3.0.
|
||||
- Support for PHP 5.4 will be removed in Emogrifier 2.0.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Allow colon (`:`) and semi-colon (`;`) when using the `*=` selector (#371)
|
||||
- Ignore "auto" width and height (#365)
|
||||
|
||||
## 1.1.0 (2016-09-18)
|
||||
|
||||
### Added
|
||||
|
||||
- Add support for PHP 7.1 (#342)
|
||||
- Support the attr|=value selector (#337)
|
||||
- Support the attr*=value selector (#330)
|
||||
@@ -381,13 +468,17 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- Add CSS to HTML attribute mapper (#288)
|
||||
|
||||
### Changed
|
||||
- Remove composer dependency from PHP mbstring extension (Actual code dependency were removed a lot of time ago) (#295)
|
||||
|
||||
- Remove composer dependency from PHP mbstring extension (Actual code dependency
|
||||
were removed a lot of time ago) (#295)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 5.5 will be removed in Emogrifier 3.0.
|
||||
- Support for PHP 5.4 will be removed in Emogrifier 2.0.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Method emogrifyBodyContent() doesn't keeps utf8 umlauts (#349)
|
||||
- Ignore value with words more than one in the attribute selector (#327)
|
||||
- Ignore spaces around the > in the direct child selector (#322)
|
||||
@@ -399,6 +490,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
## 1.0.0 (2015-10-15)
|
||||
|
||||
### Added
|
||||
|
||||
- Add branch alias (#231)
|
||||
- Remove media queries which do not impact the document (#217)
|
||||
- Allow elements to be excluded from emogrification (#215)
|
||||
@@ -415,19 +507,23 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
and nth-of-type)
|
||||
|
||||
### Changed
|
||||
|
||||
- Make HTML5 the default document type (#245)
|
||||
- Make copyCssWithMediaToStyleNode private (#218)
|
||||
- Stop encoding umlauts and dollar signs (#170)
|
||||
- Convert the classes to namespaces (#41)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Support for PHP 5.4 will be removed in Emogrifier 2.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for PHP 5.3 (#114)
|
||||
- Support for character sets other than UTF-8 was removed.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix failing tests on Windows due to line endings (#263)
|
||||
- Parsing CSS declaration blocks (#261)
|
||||
- Fix first-child and last-child selectors (#257)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# Emogrifier
|
||||
|
||||
[](https://github.com/MyIntervals/emogrifier/actions/)
|
||||
[](https://github.com/MyIntervals/emogrifier/actions/)
|
||||
[](https://packagist.org/packages/pelago/emogrifier)
|
||||
[](https://packagist.org/packages/pelago/emogrifier)
|
||||
[](https://packagist.org/packages/pelago/emogrifier)
|
||||
[](https://coveralls.io/github/MyIntervals/emogrifier?branch=main)
|
||||
|
||||
_n. e•mog•ri•fi•er [\ē-'mä-grƏ-,fī-Ər\] - a utility for changing completely the
|
||||
nature or appearance of HTML email, esp. in a particularly fantastic or bizarre
|
||||
@@ -31,6 +32,7 @@ into inline style attributes in your HTML code.
|
||||
- [Usage](#usage)
|
||||
- [Supported CSS selectors](#supported-css-selectors)
|
||||
- [Caveats](#caveats)
|
||||
- [Contributing](#contributing)
|
||||
- [Steps to release a new version](#steps-to-release-a-new-version)
|
||||
- [Maintainers](#maintainers)
|
||||
|
||||
@@ -157,6 +159,58 @@ $visualHtml = CssToAttributeConverter::fromDomDocument($domDocument)
|
||||
->convertCssToVisualAttributes()->render();
|
||||
```
|
||||
|
||||
### Evaluating CSS custom properties (variables)
|
||||
|
||||
The `CssVariableEvaluator` class can be used to apply the values of CSS
|
||||
variables defined in inline style attributes to inline style properties which
|
||||
use them.
|
||||
|
||||
For example, the following CSS defines and uses a custom property:
|
||||
|
||||
```css
|
||||
:root {
|
||||
--text-color: green;
|
||||
}
|
||||
|
||||
p {
|
||||
color: var(--text-color);
|
||||
}
|
||||
```
|
||||
|
||||
After `CssInliner` has inlined that CSS on the (contrived) HTML
|
||||
`<html><body><p></p></body></html>`, it will look like this:
|
||||
|
||||
```html
|
||||
|
||||
<html style="--text-color: green;">
|
||||
<body>
|
||||
<p style="color: var(--text-color);">
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
The `CssVariableEvaluator` method `evaluateVariables` will apply the value of
|
||||
`--text-color` so that the paragraph `style` attribute becomes `color: green;`.
|
||||
|
||||
It can be used like this:
|
||||
|
||||
```php
|
||||
use Pelago\Emogrifier\HtmlProcessor\CssVariableEvaluator;
|
||||
|
||||
…
|
||||
|
||||
$evaluatedHtml = CssVariableEvaluator::fromHtml($html)
|
||||
->evaluateVariables()->render();
|
||||
```
|
||||
|
||||
You can also have the ` CssVariableEvaluator ` work on a `DOMDocument`:
|
||||
|
||||
```php
|
||||
$evaluatedHtml = CssVariableEvaluator::fromDomDocument($domDocument)
|
||||
->evaluateVariables()->render();
|
||||
```
|
||||
|
||||
### Removing redundant content and attributes from the HTML
|
||||
|
||||
The `HtmlPruner` class can reduce the size of the HTML by removing elements with
|
||||
@@ -174,11 +228,11 @@ $prunedHtml = HtmlPruner::fromHtml($html)->removeElementsWithDisplayNone()
|
||||
->removeRedundantClasses($classesToKeep)->render();
|
||||
```
|
||||
|
||||
The `removeRedundantClasses` method accepts a whitelist of names of classes that
|
||||
should be retained. If this is a post-processing step after inlining CSS, you
|
||||
can alternatively use `removeRedundantClassesAfterCssInlined`, passing it the
|
||||
`CssInliner` instance that has inlined the CSS (and having the `HtmlPruner` work
|
||||
on the `DOMDocument`). This will use information from the `CssInliner` to
|
||||
The `removeRedundantClasses` method accepts an allowlist of names of classes
|
||||
that should be retained. If this is a post-processing step after inlining CSS,
|
||||
you can alternatively use `removeRedundantClassesAfterCssInlined`, passing it
|
||||
the `CssInliner` instance that has inlined the CSS (and having the `HtmlPruner`
|
||||
work on the `DOMDocument`). This will use information from the `CssInliner` to
|
||||
determine which classes are still required (namely, those used in uninlinable
|
||||
rules that have been copied to a `<style>` element):
|
||||
|
||||
@@ -238,6 +292,23 @@ calling the `inlineCss` method:
|
||||
$cssInliner->addExcludedSelector('.message-preview');
|
||||
$cssInliner->addExcludedSelector('.message-preview *');
|
||||
```
|
||||
* `->addExcludedCssSelector(string $selector)` - Contrary to
|
||||
`addExcludedSelector`, which excludes HTML nodes, this method excludes CSS
|
||||
selectors from being inlined. This is for example useful if you don't want
|
||||
your CSS reset rules to be inlined on each HTML node (e.g.
|
||||
`* { margin: 0; padding: 0; font-size: 100% }`).
|
||||
Note that these selectors must precisely match the selectors you wish to
|
||||
exclude.
|
||||
Meaning that excluding `.example` will not exclude `p .example`.
|
||||
```php
|
||||
$cssInliner->addExcludedCssSelector('*');
|
||||
$cssInliner->addExcludedCssSelector('form');
|
||||
```
|
||||
* `->removeExcludedCssSelector(string $selector)` - Removes previously added
|
||||
excluded selectors, if any.
|
||||
```php
|
||||
$cssInliner->removeExcludedCssSelector('form');
|
||||
```
|
||||
|
||||
### Migrating from the dropped `Emogrifier` class to the `CssInliner` class
|
||||
|
||||
@@ -286,11 +357,11 @@ $html = CssToAttributeConverter::fromDomDocument($domDocument)
|
||||
Emogrifier currently supports the following
|
||||
[CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors):
|
||||
|
||||
* [type](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors)
|
||||
* [class](https://developer.mozilla.org/en-US/docs/Web/CSS/Class_selectors)
|
||||
* [ID](https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors)
|
||||
* [universal](https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors)
|
||||
* [attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors):
|
||||
* [type](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors)
|
||||
* [class](https://developer.mozilla.org/en-US/docs/Web/CSS/Class_selectors)
|
||||
* [ID](https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors)
|
||||
* [universal](https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors)
|
||||
* [attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors):
|
||||
* presence
|
||||
* exact value match
|
||||
* value with `~` (one word within a whitespace-separated list of words)
|
||||
@@ -298,11 +369,11 @@ Emogrifier currently supports the following
|
||||
* value with `^` (prefix match)
|
||||
* value with `$` (suffix match)
|
||||
* value with `*` (substring match)
|
||||
* [adjacent](https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors)
|
||||
* [general sibling](https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator)
|
||||
* [child](https://developer.mozilla.org/en-US/docs/Web/CSS/Child_selectors)
|
||||
* [descendant](https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_selectors)
|
||||
* [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes):
|
||||
* [adjacent](https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors)
|
||||
* [general sibling](https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator)
|
||||
* [child](https://developer.mozilla.org/en-US/docs/Web/CSS/Child_selectors)
|
||||
* [descendant](https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_selectors)
|
||||
* [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes):
|
||||
* [empty](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty)
|
||||
* [first-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-child)
|
||||
* [first-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-of-type)
|
||||
@@ -320,11 +391,13 @@ Emogrifier currently supports the following
|
||||
* [only-child](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-child)
|
||||
* [only-of-type](https://developer.mozilla.org/en-US/docs/Web/CSS/:only-of-type)
|
||||
(with a type)
|
||||
* [root](https://developer.mozilla.org/en-US/docs/Web/CSS/:root)
|
||||
|
||||
The following selectors are not implemented yet:
|
||||
|
||||
* [case-insensitive attribute value](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors#case-insensitive)
|
||||
* static [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)
|
||||
* [case-insensitive attribute value](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors#case-insensitive)
|
||||
* static
|
||||
[pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)
|
||||
not listed above as supported – rules involving them will nonetheless be
|
||||
preserved and copied to a `<style>` element in the HTML – including (but not
|
||||
necessarily limited to) the following:
|
||||
@@ -345,16 +418,17 @@ The following selectors are not implemented yet:
|
||||
Rules involving the following selectors cannot be applied as inline styles.
|
||||
They will, however, be preserved and copied to a `<style>` element in the HTML:
|
||||
|
||||
* dynamic [pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)
|
||||
* dynamic
|
||||
[pseudo-classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)
|
||||
(such as `:hover`)
|
||||
* [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)
|
||||
* [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)
|
||||
(such as `::after`)
|
||||
|
||||
## Caveats
|
||||
|
||||
* Emogrifier requires the HTML and the CSS to be UTF-8. Encodings like
|
||||
ISO8859-1 or ISO8859-15 are not supported.
|
||||
* Emogrifier preserves all valuable `@media` rules. Media queries can be very
|
||||
* Emogrifier preserves all applicable `@media` rules. Media queries can be very
|
||||
useful in responsive email design. See
|
||||
[media query support](https://litmus.com/help/email-clients/media-query-support/).
|
||||
However, in order for them to be effective, you may need to add `!important`
|
||||
@@ -374,11 +448,15 @@ They will, however, be preserved and copied to a `<style>` element in the HTML:
|
||||
}
|
||||
}
|
||||
```
|
||||
Any CSS custom properties (variables) defined in `@media` rules cannot be
|
||||
applied to CSS property values that have been inlined and evaluated. However,
|
||||
`@media` rules using custom properties (with `var()`) would still be able to
|
||||
obtain their values (from the inlined definitions or `@media` rules) in email
|
||||
clients that support custom properties.
|
||||
* Emogrifier cannot inline CSS rules involving selectors with pseudo-elements
|
||||
(such as `::after`) or dynamic pseudo-classes (such as `:hover`) – it is
|
||||
impossible. However, such rules will be preserved and copied to a `<style>`
|
||||
element, as for `@media` rules. The same caveat about the possible need for
|
||||
the `!important` directive also applies with pseudo-classes.
|
||||
element, as for `@media` rules, with the same caveats applying.
|
||||
* Emogrifier will grab existing inline style attributes _and_ will
|
||||
grab `<style>` blocks from your HTML, but it will not grab CSS files
|
||||
referenced in `<link>` elements or `@import` rules (though it will leave them
|
||||
@@ -402,20 +480,32 @@ They will, however, be preserved and copied to a `<style>` element in the HTML:
|
||||
self-closing tags will lose their slash. To keep your HTML valid, it is
|
||||
recommended to use HTML5 instead of one of the XHTML variants.
|
||||
|
||||
## API and deprecation policy
|
||||
|
||||
Please have a look at our
|
||||
[API and deprecation policy](docs/API-and-deprecation-policy.md).
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions in the form of bug reports, feature requests, or pull requests are
|
||||
more than welcome. :pray: Please have a look at our
|
||||
[contribution guidelines](CONTRIBUTING.md) to learn more about how to
|
||||
contribute to Emogrifier.
|
||||
|
||||
## Steps to release a new version
|
||||
|
||||
1. In the [composer.json](composer.json), update the `branch-alias` entry to
|
||||
point to the release _after_ the upcoming release.
|
||||
2. In the [CHANGELOG.md](CHANGELOG.md), create a new section with subheadings
|
||||
1. In the [CHANGELOG.md](CHANGELOG.md), create a new section with subheadings
|
||||
for changes _after_ the upcoming release, set the version number for the
|
||||
upcoming release, and remove any empty sections.
|
||||
3. Create a pull request "Prepare release of version x.y.z" with those
|
||||
changes.
|
||||
4. Have the pull request reviewed and merged.
|
||||
5. Tag the new release.
|
||||
6. In the [Releases tab](https://github.com/MyIntervals/emogrifier/releases),
|
||||
1. Update the target milestone in the Dependabot configuration.
|
||||
1. Create a pull request "Prepare release of version x.y.z" with those changes.
|
||||
1. Have the pull request reviewed and merged.
|
||||
1. Tag the new release.
|
||||
1. In the [Releases tab](https://github.com/MyIntervals/emogrifier/releases),
|
||||
create a new release and copy the change log entries to the new release.
|
||||
7. Post about the new release on social media.
|
||||
1. Post about the new release on social media.
|
||||
|
||||
## Maintainers
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Jake Hotson",
|
||||
"email": "jake@qzdesign.co.uk"
|
||||
"email": "jake.github@qzdesign.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Cameron Brooks"
|
||||
@@ -37,15 +37,19 @@
|
||||
"source": "https://github.com/MyIntervals/emogrifier"
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
|
||||
"php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"sabberworm/php-css-parser": "^8.4.0",
|
||||
"sabberworm/php-css-parser": "^8.7.0",
|
||||
"symfony/css-selector": "^4.4.23 || ^5.4.0 || ^6.0.0 || ^7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-parallel-lint/php-parallel-lint": "1.3.2",
|
||||
"phpunit/phpunit": "9.6.11",
|
||||
"php-parallel-lint/php-parallel-lint": "1.4.0",
|
||||
"phpstan/extension-installer": "1.4.3",
|
||||
"phpstan/phpstan": "1.12.7",
|
||||
"phpstan/phpstan-phpunit": "1.4.0",
|
||||
"phpstan/phpstan-strict-rules": "1.6.1",
|
||||
"phpunit/phpunit": "9.6.21",
|
||||
"rawr/cross-data-providers": "2.4.0"
|
||||
},
|
||||
"prefer-stable": true,
|
||||
@@ -60,6 +64,9 @@
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"phpstan/extension-installer": true
|
||||
},
|
||||
"preferred-install": {
|
||||
"*": "dist"
|
||||
},
|
||||
@@ -80,28 +87,26 @@
|
||||
"@ci:tests"
|
||||
],
|
||||
"ci:php:fixer": "\"./.phive/php-cs-fixer\" --config=config/php-cs-fixer.php fix --dry-run -v --show-progress=dots config/ src/ tests/",
|
||||
"ci:php:lint": "\"./vendor/bin/parallel-lint\" config src tests",
|
||||
"ci:php:lint": "parallel-lint config src tests",
|
||||
"ci:php:md": "\"./.phive/phpmd\" src text config/phpmd.xml",
|
||||
"ci:php:psalm": "\"./.phive/psalm\" --show-info=false",
|
||||
"ci:php:sniff": "\"./.phive/phpcs\" config src tests",
|
||||
"ci:php:stan": "phpstan --no-progress --error-format=github",
|
||||
"ci:static": [
|
||||
"@ci:composer:normalize",
|
||||
"@ci:php:lint",
|
||||
"@ci:php:sniff",
|
||||
"@ci:php:fixer",
|
||||
"@ci:php:md",
|
||||
"@ci:php:psalm"
|
||||
"@ci:php:stan"
|
||||
],
|
||||
"ci:tests": [
|
||||
"@ci:tests:unit"
|
||||
],
|
||||
"ci:tests:sof": "@php \"./vendor/bin/phpunit\" --stop-on-failure --do-not-cache-result",
|
||||
"ci:tests:unit": "@php \"./vendor/bin/phpunit\" --do-not-cache-result",
|
||||
"ci:tests:coverage": "phpunit --do-not-cache-result --coverage-clover=coverage.xml",
|
||||
"ci:tests:sof": "phpunit --stop-on-failure --do-not-cache-result",
|
||||
"ci:tests:unit": "phpunit --do-not-cache-result",
|
||||
"composer:normalize": "\"./.phive/composer-normalize\" --no-check-lock",
|
||||
"php:fix": "\"./.phive/php-cs-fixer\" --config=config/php-cs-fixer.php fix config/ src/ tests/",
|
||||
"php:version": "@php -v | grep -Po 'PHP\\s++\\K(?:\\d++\\.)*+\\d++(?:-\\w++)?+'",
|
||||
"psalm:baseline": "\"./.phive/psalm\" --set-baseline=psalm.baseline.xml",
|
||||
"psalm:cc": "\"./.phive/psalm\" --clear-cache"
|
||||
"phpstan:baseline": "phpstan --generate-baseline --allow-empty-baseline"
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"ci": "Runs all dynamic and static code checks.",
|
||||
@@ -110,16 +115,15 @@
|
||||
"ci:php:fixer": "Checks the code style with PHP CS Fixer.",
|
||||
"ci:php:lint": "Lints the PHP files for syntax errors.",
|
||||
"ci:php:md": "Checks the code complexity with PHPMD.",
|
||||
"ci:php:psalm": "Checks the types with Psalm.",
|
||||
"ci:php:sniff": "Checks the code style with PHP_CodeSniffer.",
|
||||
"ci:php:stan": "Checks the PHP types using PHPStan.",
|
||||
"ci:static": "Runs all static code analysis checks for the code and the composer.json.",
|
||||
"ci:tests": "Runs all dynamic tests (i.e., currently, the unit tests).",
|
||||
"ci:tests:coverage": "Runs the unit tests with code coverage.",
|
||||
"ci:tests:sof": "Runs the unit tests and stops at the first failure.",
|
||||
"ci:tests:unit": "Runs all unit tests.",
|
||||
"composer:normalize": "Reformats and sorts the composer.json file.",
|
||||
"php:fix": "Reformats the code with php-cs-fixer.",
|
||||
"php:version": "Outputs the installed PHP version.",
|
||||
"psalm:baseline": "Updates the Psalm baseline file to match the code.",
|
||||
"psalm:cc": "Clears the Psalm cache."
|
||||
"phpstan:baseline": "Updates the PHPStan baseline file to match the code."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Pelago\Emogrifier\Caching;
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class SimpleStringCache
|
||||
final class SimpleStringCache
|
||||
{
|
||||
/**
|
||||
* @var array<string, string>
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Pelago\Emogrifier\Css;
|
||||
|
||||
use Pelago\Emogrifier\Utilities\Preg;
|
||||
use Sabberworm\CSS\CSSList\AtRuleBlockList as CssAtRuleBlockList;
|
||||
use Sabberworm\CSS\CSSList\Document as SabberwormCssDocument;
|
||||
use Sabberworm\CSS\Parser as CssParser;
|
||||
@@ -21,7 +22,7 @@ use Sabberworm\CSS\Settings as ParserSettings;
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CssDocument
|
||||
final class CssDocument
|
||||
{
|
||||
/**
|
||||
* @var SabberwormCssDocument
|
||||
@@ -61,7 +62,8 @@ class CssDocument
|
||||
*/
|
||||
private function hasNestedAtRule(string $css): bool
|
||||
{
|
||||
return \preg_match('/@(?:media|supports|(?:-webkit-|-moz-|-ms-|-o-)?+(keyframes|document))\\b/', $css) === 1;
|
||||
return (new Preg())
|
||||
->match('/@(?:media|supports|(?:-webkit-|-moz-|-ms-|-o-)?+(keyframes|document))\\b/', $css) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +142,8 @@ class CssDocument
|
||||
$allowedMediaTypes
|
||||
);
|
||||
$mediaTypesMatcher = \implode('|', $escapedAllowedMediaTypes);
|
||||
$isAllowed = \preg_match('/^\\s*+(?:only\\s++)?+(?:' . $mediaTypesMatcher . ')/i', $mediaType) > 0;
|
||||
$isAllowed
|
||||
= (new Preg())->match('/^\\s*+(?:only\\s++)?+(?:' . $mediaTypesMatcher . ')/i', $mediaType) !== 0;
|
||||
} else {
|
||||
$isAllowed = true;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user