This commit is contained in:
2025-03-21 20:24:43 +01:00
parent 224398df90
commit f34c9162d4
12427 changed files with 5329941 additions and 373384 deletions

View File

@@ -2,6 +2,24 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitb31aa05dff4ca49df03ed75531f10ba8::getLoader();
return ComposerAutoloaderInita3df77b4b522885b715a8fd38a5db444::getLoader();

View File

@@ -37,26 +37,84 @@ namespace Composer\Autoload;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
private $apcuPrefix;
/**
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return string[]
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
@@ -66,28 +124,47 @@ class ClassLoader
return array();
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
public function addClassMap(array $classMap)
{
@@ -102,9 +179,11 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
@@ -147,11 +226,13 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
@@ -195,8 +276,10 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
@@ -211,10 +294,12 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
@@ -234,6 +319,8 @@ class ClassLoader
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
@@ -256,6 +343,8 @@ class ClassLoader
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
@@ -276,6 +365,8 @@ class ClassLoader
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
@@ -296,33 +387,55 @@ class ClassLoader
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
@@ -367,6 +480,21 @@ class ClassLoader
return $file;
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
@@ -432,14 +560,26 @@ class ClassLoader
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

View File

@@ -0,0 +1,359 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
return $installed;
}
}

View File

@@ -2,11 +2,12 @@
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Clue\\StreamFilter\\CallbackFilter' => $vendorDir . '/clue/stream-filter/src/CallbackFilter.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'Http\\Client\\Curl\\Client' => $vendorDir . '/php-http/curl-client/src/Client.php',
'Http\\Client\\Curl\\CurlPromise' => $vendorDir . '/php-http/curl-client/src/CurlPromise.php',
'Http\\Client\\Curl\\MultiRunner' => $vendorDir . '/php-http/curl-client/src/MultiRunner.php',
@@ -34,7 +35,9 @@ return array(
'Http\\Discovery\\HttpClientDiscovery' => $vendorDir . '/php-http/discovery/src/HttpClientDiscovery.php',
'Http\\Discovery\\MessageFactoryDiscovery' => $vendorDir . '/php-http/discovery/src/MessageFactoryDiscovery.php',
'Http\\Discovery\\NotFoundException' => $vendorDir . '/php-http/discovery/src/NotFoundException.php',
'Http\\Discovery\\Psr17Factory' => $vendorDir . '/php-http/discovery/src/Psr17Factory.php',
'Http\\Discovery\\Psr17FactoryDiscovery' => $vendorDir . '/php-http/discovery/src/Psr17FactoryDiscovery.php',
'Http\\Discovery\\Psr18Client' => $vendorDir . '/php-http/discovery/src/Psr18Client.php',
'Http\\Discovery\\Psr18ClientDiscovery' => $vendorDir . '/php-http/discovery/src/Psr18ClientDiscovery.php',
'Http\\Discovery\\Strategy\\CommonClassesStrategy' => $vendorDir . '/php-http/discovery/src/Strategy/CommonClassesStrategy.php',
'Http\\Discovery\\Strategy\\CommonPsr17ClassesStrategy' => $vendorDir . '/php-http/discovery/src/Strategy/CommonPsr17ClassesStrategy.php',

View File

@@ -2,7 +2,7 @@
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,18 +2,18 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Symfony\\Component\\OptionsResolver\\' => array($vendorDir . '/symfony/options-resolver'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'),
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
'Paynow\\Tests\\' => array($vendorDir . '/pay-now/paynow-php-sdk/tests'),
'Paynow\\' => array($vendorDir . '/pay-now/paynow-php-sdk/src/Paynow'),
'Nyholm\\Psr7\\' => array($vendorDir . '/nyholm/psr7/src'),
'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'),
'Http\\Message\\' => array($vendorDir . '/php-http/message/src', $vendorDir . '/php-http/message-factory/src'),
'Http\\Message\\' => array($vendorDir . '/php-http/message-factory/src', $vendorDir . '/php-http/message/src'),
'Http\\Discovery\\' => array($vendorDir . '/php-http/discovery/src'),
'Http\\Client\\Curl\\' => array($vendorDir . '/php-http/curl-client/src'),
'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'),

View File

@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitb31aa05dff4ca49df03ed75531f10ba8
class ComposerAutoloaderInita3df77b4b522885b715a8fd38a5db444
{
private static $loader;
@@ -22,52 +22,29 @@ class ComposerAutoloaderInitb31aa05dff4ca49df03ed75531f10ba8
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitb31aa05dff4ca49df03ed75531f10ba8', 'loadClassLoader'), true, false);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitb31aa05dff4ca49df03ed75531f10ba8', 'loadClassLoader'));
require __DIR__ . '/platform_check.php';
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
spl_autoload_register(array('ComposerAutoloaderInita3df77b4b522885b715a8fd38a5db444', 'loadClassLoader'), true, false);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInita3df77b4b522885b715a8fd38a5db444', 'loadClassLoader'));
call_user_func(\Composer\Autoload\ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInita3df77b4b522885b715a8fd38a5db444::getInitializer($loader));
$loader->register(false);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequireb31aa05dff4ca49df03ed75531f10ba8($fileIdentifier, $file);
$filesToLoad = \Composer\Autoload\ComposerStaticInita3df77b4b522885b715a8fd38a5db444::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequireb31aa05dff4ca49df03ed75531f10ba8($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8
class ComposerStaticInita3df77b4b522885b715a8fd38a5db444
{
public static $files = array (
'9c67151ae59aff4788964ce8eb2a0f43' => __DIR__ . '/..' . '/clue/stream-filter/src/functions_include.php',
@@ -48,8 +48,8 @@ class ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8
),
'Psr\\Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-factory/src',
1 => __DIR__ . '/..' . '/psr/http-message/src',
0 => __DIR__ . '/..' . '/psr/http-message/src',
1 => __DIR__ . '/..' . '/psr/http-factory/src',
),
'Psr\\Http\\Client\\' =>
array (
@@ -73,8 +73,8 @@ class ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8
),
'Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/php-http/message/src',
1 => __DIR__ . '/..' . '/php-http/message-factory/src',
0 => __DIR__ . '/..' . '/php-http/message-factory/src',
1 => __DIR__ . '/..' . '/php-http/message/src',
),
'Http\\Discovery\\' =>
array (
@@ -96,6 +96,7 @@ class ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8
public static $classMap = array (
'Clue\\StreamFilter\\CallbackFilter' => __DIR__ . '/..' . '/clue/stream-filter/src/CallbackFilter.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'Http\\Client\\Curl\\Client' => __DIR__ . '/..' . '/php-http/curl-client/src/Client.php',
'Http\\Client\\Curl\\CurlPromise' => __DIR__ . '/..' . '/php-http/curl-client/src/CurlPromise.php',
'Http\\Client\\Curl\\MultiRunner' => __DIR__ . '/..' . '/php-http/curl-client/src/MultiRunner.php',
@@ -123,7 +124,9 @@ class ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8
'Http\\Discovery\\HttpClientDiscovery' => __DIR__ . '/..' . '/php-http/discovery/src/HttpClientDiscovery.php',
'Http\\Discovery\\MessageFactoryDiscovery' => __DIR__ . '/..' . '/php-http/discovery/src/MessageFactoryDiscovery.php',
'Http\\Discovery\\NotFoundException' => __DIR__ . '/..' . '/php-http/discovery/src/NotFoundException.php',
'Http\\Discovery\\Psr17Factory' => __DIR__ . '/..' . '/php-http/discovery/src/Psr17Factory.php',
'Http\\Discovery\\Psr17FactoryDiscovery' => __DIR__ . '/..' . '/php-http/discovery/src/Psr17FactoryDiscovery.php',
'Http\\Discovery\\Psr18Client' => __DIR__ . '/..' . '/php-http/discovery/src/Psr18Client.php',
'Http\\Discovery\\Psr18ClientDiscovery' => __DIR__ . '/..' . '/php-http/discovery/src/Psr18ClientDiscovery.php',
'Http\\Discovery\\Strategy\\CommonClassesStrategy' => __DIR__ . '/..' . '/php-http/discovery/src/Strategy/CommonClassesStrategy.php',
'Http\\Discovery\\Strategy\\CommonPsr17ClassesStrategy' => __DIR__ . '/..' . '/php-http/discovery/src/Strategy/CommonPsr17ClassesStrategy.php',
@@ -272,9 +275,9 @@ class ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitb31aa05dff4ca49df03ed75531f10ba8::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInita3df77b4b522885b715a8fd38a5db444::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInita3df77b4b522885b715a8fd38a5db444::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInita3df77b4b522885b715a8fd38a5db444::$classMap;
}, null, ClassLoader::class);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,181 @@
<?php return array(
'root' => array(
'name' => 'pay-now/paynow-prestashop',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'ae162451919441e986928aafb1996fab693c0159',
'type' => 'prestashop-module',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => false,
),
'versions' => array(
'clue/stream-filter' => array(
'pretty_version' => 'v1.6.0',
'version' => '1.6.0.0',
'reference' => 'd6169430c7731d8509da7aecd0af756a5747b78e',
'type' => 'library',
'install_path' => __DIR__ . '/../clue/stream-filter',
'aliases' => array(),
'dev_requirement' => false,
),
'nyholm/psr7' => array(
'pretty_version' => '1.6.1',
'version' => '1.6.1.0',
'reference' => 'e874c8c4286a1e010fb4f385f3a55ac56a05cc93',
'type' => 'library',
'install_path' => __DIR__ . '/../nyholm/psr7',
'aliases' => array(),
'dev_requirement' => false,
),
'pay-now/paynow-php-sdk' => array(
'pretty_version' => '2.2.2',
'version' => '2.2.2.0',
'reference' => '33432ca177e937f3f5c6abb9f36c7f979baec67d',
'type' => 'library',
'install_path' => __DIR__ . '/../pay-now/paynow-php-sdk',
'aliases' => array(),
'dev_requirement' => false,
),
'pay-now/paynow-prestashop' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'ae162451919441e986928aafb1996fab693c0159',
'type' => 'prestashop-module',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'php-http/async-client-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '*',
1 => '1.0',
),
),
'php-http/client-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '*',
1 => '1.0',
),
),
'php-http/curl-client' => array(
'pretty_version' => '2.3.0',
'version' => '2.3.0.0',
'reference' => 'f7352c0796549949900d28fe991e19c90572386a',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/curl-client',
'aliases' => array(),
'dev_requirement' => false,
),
'php-http/discovery' => array(
'pretty_version' => '1.19.1',
'version' => '1.19.1.0',
'reference' => '57f3de01d32085fea20865f9b16fb0e69347c39e',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/../php-http/discovery',
'aliases' => array(),
'dev_requirement' => false,
),
'php-http/httplug' => array(
'pretty_version' => '2.4.0',
'version' => '2.4.0.0',
'reference' => '625ad742c360c8ac580fcc647a1541d29e257f67',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/httplug',
'aliases' => array(),
'dev_requirement' => false,
),
'php-http/message' => array(
'pretty_version' => '1.14.0',
'version' => '1.14.0.0',
'reference' => '2ccee04a28c3d98eb3f2b85ce1e2fcff70c0e63b',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/message',
'aliases' => array(),
'dev_requirement' => false,
),
'php-http/message-factory' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'reference' => '4d8778e1c7d405cbb471574821c1ff5b68cc8f57',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/message-factory',
'aliases' => array(),
'dev_requirement' => false,
),
'php-http/message-factory-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0',
),
),
'php-http/promise' => array(
'pretty_version' => '1.2.0',
'version' => '1.2.0.0',
'reference' => 'ef4905bfb492ff389eb7f12e26925a0f20073050',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/promise',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-client' => array(
'pretty_version' => '1.0.3',
'version' => '1.0.3.0',
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-client',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-client-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '*',
1 => '1.0',
),
),
'psr/http-factory' => array(
'pretty_version' => '1.0.2',
'version' => '1.0.2.0',
'reference' => 'e616d01114759c4c489f93b099585439f795fe35',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-factory-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '*',
1 => '1.0',
),
),
'psr/http-message' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-message-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '*',
1 => '1.0',
),
),
'symfony/options-resolver' => array(
'pretty_version' => 'v3.4.47',
'version' => '3.4.47.0',
'reference' => 'c7efc97a47b2ebaabc19d5b6c6b50f5c37c92744',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/options-resolver',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

View File

@@ -0,0 +1,26 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 70100)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
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
);
}

View File

@@ -27,6 +27,7 @@
"symfony/error-handler": "^4.4"
},
"provide": {
"php-http/message-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0",
"psr/http-factory-implementation": "1.0"
},
@@ -42,7 +43,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "1.6-dev"
}
}
}

View File

@@ -0,0 +1,41 @@
parameters:
ignoreErrors:
-
message: "#^Result of && is always false\\.$#"
count: 1
path: src/Response.php
-
message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#"
count: 1
path: src/Response.php
-
message: "#^Result of && is always false\\.$#"
count: 1
path: src/ServerRequest.php
-
message: "#^Strict comparison using \\!\\=\\= between null and null will always evaluate to false\\.$#"
count: 1
path: src/ServerRequest.php
-
message: "#^Parameter \\#1 \\$callback of function set_error_handler expects \\(callable\\(int, string, string, int\\)\\: bool\\)\\|null, 'var_dump' given\\.$#"
count: 1
path: src/Stream.php
-
message: "#^Result of && is always false\\.$#"
count: 1
path: src/Stream.php
-
message: "#^Result of && is always false\\.$#"
count: 2
path: src/UploadedFile.php
-
message: "#^Strict comparison using \\=\\=\\= between false and true will always evaluate to false\\.$#"
count: 2
path: src/UploadedFile.php

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.30.0@d0bc6e25d89f649e4f36a534f330f8bb4643dd69">
<file src="src/Stream.php">
<NoValue occurrences="1">
<code>return \trigger_error((string) $e, \E_USER_ERROR);</code>
</NoValue>
</file>
</files>

View File

@@ -36,12 +36,16 @@ trait MessageTrait
public function withProtocolVersion($version): self
{
if (!\is_scalar($version)) {
throw new \InvalidArgumentException('Protocol version must be a string');
}
if ($this->protocol === $version) {
return $this;
}
$new = clone $this;
$new->protocol = $version;
$new->protocol = (string) $version;
return $new;
}
@@ -58,6 +62,10 @@ trait MessageTrait
public function getHeader($header): array
{
if (!\is_string($header)) {
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string');
}
$header = \strtr($header, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
if (!isset($this->headerNames[$header])) {
return [];
@@ -91,7 +99,7 @@ trait MessageTrait
public function withAddedHeader($header, $value): self
{
if (!\is_string($header) || '' === $header) {
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string.');
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string');
}
$new = clone $this;
@@ -102,6 +110,10 @@ trait MessageTrait
public function withoutHeader($header): self
{
if (!\is_string($header)) {
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string');
}
$normalized = \strtr($header, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
if (!isset($this->headerNames[$normalized])) {
return $this;
@@ -175,28 +187,28 @@ trait MessageTrait
*/
private function validateAndTrimHeader($header, $values): array
{
if (!\is_string($header) || 1 !== \preg_match("@^[!#$%&'*+.^_`|~0-9A-Za-z-]+$@", $header)) {
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string.');
if (!\is_string($header) || 1 !== \preg_match("@^[!#$%&'*+.^_`|~0-9A-Za-z-]+$@D", $header)) {
throw new \InvalidArgumentException('Header name must be an RFC 7230 compatible string');
}
if (!\is_array($values)) {
// This is simple, just one value.
if ((!\is_numeric($values) && !\is_string($values)) || 1 !== \preg_match("@^[ \t\x21-\x7E\x80-\xFF]*$@", (string) $values)) {
throw new \InvalidArgumentException('Header values must be RFC 7230 compatible strings.');
throw new \InvalidArgumentException('Header values must be RFC 7230 compatible strings');
}
return [\trim((string) $values, " \t")];
}
if (empty($values)) {
throw new \InvalidArgumentException('Header values must be a string or an array of strings, empty array given.');
throw new \InvalidArgumentException('Header values must be a string or an array of strings, empty array given');
}
// Assert Non empty array
$returnValues = [];
foreach ($values as $v) {
if ((!\is_numeric($v) && !\is_string($v)) || 1 !== \preg_match("@^[ \t\x21-\x7E\x80-\xFF]*$@", (string) $v)) {
throw new \InvalidArgumentException('Header values must be RFC 7230 compatible strings.');
if ((!\is_numeric($v) && !\is_string($v)) || 1 !== \preg_match("@^[ \t\x21-\x7E\x80-\xFF]*$@D", (string) $v)) {
throw new \InvalidArgumentException('Header values must be RFC 7230 compatible strings');
}
$returnValues[] = \trim((string) $v, " \t");

View File

@@ -42,6 +42,10 @@ trait RequestTrait
public function withRequestTarget($requestTarget): self
{
if (!\is_string($requestTarget)) {
throw new \InvalidArgumentException('Request target must be a string');
}
if (\preg_match('#\s#', $requestTarget)) {
throw new \InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
}

View File

@@ -56,6 +56,7 @@ class ServerRequest implements ServerRequestInterface
$this->uri = $uri;
$this->setHeaders($headers);
$this->protocol = $version;
\parse_str($uri->getQuery(), $this->queryParams);
if (!$this->hasHeader('Host')) {
$this->updateHostFromUri();
@@ -77,6 +78,9 @@ class ServerRequest implements ServerRequestInterface
return $this->uploadedFiles;
}
/**
* @return static
*/
public function withUploadedFiles(array $uploadedFiles)
{
$new = clone $this;
@@ -90,6 +94,9 @@ class ServerRequest implements ServerRequestInterface
return $this->cookieParams;
}
/**
* @return static
*/
public function withCookieParams(array $cookies)
{
$new = clone $this;
@@ -103,6 +110,9 @@ class ServerRequest implements ServerRequestInterface
return $this->queryParams;
}
/**
* @return static
*/
public function withQueryParams(array $query)
{
$new = clone $this;
@@ -111,11 +121,17 @@ class ServerRequest implements ServerRequestInterface
return $new;
}
/**
* @return array|object|null
*/
public function getParsedBody()
{
return $this->parsedBody;
}
/**
* @return static
*/
public function withParsedBody($data)
{
if (!\is_array($data) && !\is_object($data) && null !== $data) {
@@ -138,6 +154,10 @@ class ServerRequest implements ServerRequestInterface
*/
public function getAttribute($attribute, $default = null)
{
if (!\is_string($attribute)) {
throw new \InvalidArgumentException('Attribute name must be a string');
}
if (false === \array_key_exists($attribute, $this->attributes)) {
return $default;
}
@@ -147,6 +167,10 @@ class ServerRequest implements ServerRequestInterface
public function withAttribute($attribute, $value): self
{
if (!\is_string($attribute)) {
throw new \InvalidArgumentException('Attribute name must be a string');
}
$new = clone $this;
$new->attributes[$attribute] = $value;
@@ -155,6 +179,10 @@ class ServerRequest implements ServerRequestInterface
public function withoutAttribute($attribute): self
{
if (!\is_string($attribute)) {
throw new \InvalidArgumentException('Attribute name must be a string');
}
if (false === \array_key_exists($attribute, $this->attributes)) {
return $this;
}

View File

@@ -51,8 +51,20 @@ class Stream implements StreamInterface
],
];
private function __construct()
/**
* @param resource $body
*/
public function __construct($body)
{
if (!\is_resource($body)) {
throw new \InvalidArgumentException('First argument to Stream::__construct() must be resource');
}
$this->stream = $body;
$meta = \stream_get_meta_data($this->stream);
$this->seekable = $meta['seekable'] && 0 === \fseek($this->stream, 0, \SEEK_CUR);
$this->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]);
$this->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]);
}
/**
@@ -71,21 +83,15 @@ class Stream implements StreamInterface
if (\is_string($body)) {
$resource = \fopen('php://temp', 'rw+');
\fwrite($resource, $body);
\fseek($resource, 0);
$body = $resource;
}
if (\is_resource($body)) {
$new = new self();
$new->stream = $body;
$meta = \stream_get_meta_data($new->stream);
$new->seekable = $meta['seekable'] && 0 === \fseek($new->stream, 0, \SEEK_CUR);
$new->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]);
$new->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]);
return $new;
if (!\is_resource($body)) {
throw new \InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface');
}
throw new \InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface.');
return new self($body);
}
/**
@@ -291,6 +297,10 @@ class Stream implements StreamInterface
*/
public function getMetadata($key = null)
{
if (null !== $key && !\is_string($key)) {
throw new \InvalidArgumentException('Metadata key must be a string');
}
if (!isset($this->stream)) {
return $key ? null : [];
}

View File

@@ -58,7 +58,7 @@ class UploadedFile implements UploadedFileInterface
public function __construct($streamOrFile, $size, $errorStatus, $clientFilename = null, $clientMediaType = null)
{
if (false === \is_int($errorStatus) || !isset(self::ERRORS[$errorStatus])) {
throw new \InvalidArgumentException('Upload file error status must be an integer value and one of the "UPLOAD_ERR_*" constants.');
throw new \InvalidArgumentException('Upload file error status must be an integer value and one of the "UPLOAD_ERR_*" constants');
}
if (false === \is_int($size)) {

View File

@@ -25,6 +25,8 @@ class Uri implements UriInterface
private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
private const CHAR_GEN_DELIMS = ':\/\?#\[\]@';
/** @var string Uri scheme. */
private $scheme = '';
@@ -112,7 +114,20 @@ class Uri implements UriInterface
public function getPath(): string
{
return $this->path;
$path = $this->path;
if ('' !== $path && '/' !== $path[0]) {
if ('' !== $this->host) {
// If the path is rootless and an authority is present, the path MUST be prefixed by "/"
$path = '/' . $path;
}
} elseif (isset($path[1]) && '/' === $path[1]) {
// If the path is starting with more than one "/", the
// starting slashes MUST be reduced to one.
$path = '/' . \ltrim($path, '/');
}
return $path;
}
public function getQuery(): string
@@ -144,9 +159,17 @@ class Uri implements UriInterface
public function withUserInfo($user, $password = null): self
{
$info = $user;
if (!\is_string($user)) {
throw new \InvalidArgumentException('User must be a string');
}
$info = \preg_replace_callback('/[' . self::CHAR_GEN_DELIMS . self::CHAR_SUB_DELIMS . ']++/', [__CLASS__, 'rawurlencodeMatchZero'], $user);
if (null !== $password && '' !== $password) {
$info .= ':' . $password;
if (!\is_string($password)) {
throw new \InvalidArgumentException('Password must be a string');
}
$info .= ':' . \preg_replace_callback('/[' . self::CHAR_GEN_DELIMS . self::CHAR_SUB_DELIMS . ']++/', [__CLASS__, 'rawurlencodeMatchZero'], $password);
}
if ($this->userInfo === $info) {
@@ -280,7 +303,7 @@ class Uri implements UriInterface
}
$port = (int) $port;
if (0 > $port || 0xffff < $port) {
if (0 > $port || 0xFFFF < $port) {
throw new \InvalidArgumentException(\sprintf('Invalid port: %d. Must be between 0 and 65535', $port));
}

View File

@@ -1,7 +1,7 @@
{
"name": "pay-now/paynow-php-sdk",
"description": "PHP client library for accessing Paynow API",
"version": "2.2.1",
"version": "2.2.2",
"keywords": [
"paynow",
"mbank",
@@ -21,9 +21,9 @@
"prefer-stable": true,
"require": {
"php": ">=7.1",
"psr/http-message": "^1.0",
"php-http/client-implementation": "^1.0",
"php-http/message-factory": "^1.0",
"psr/http-message": "^1.0 || ^2.0",
"php-http/client-implementation": "^1.0 || ^2.0",
"php-http/message-factory": "^1.0 || ^2.0",
"php-http/discovery": "^1.12",
"php-http/httplug": "^2.2"
},

View File

@@ -0,0 +1,61 @@
<?php
namespace Paynow\Model\PaymentMethods;
class SavedInstrument
{
private $name;
private $expirationDate;
private $brand;
private $image;
private $token;
/**
* @var SavedInstrument\Status
*/
private $status;
public function __construct($name, $expirationDate, $brand, $image, $token, $status)
{
$this->name = $name;
$this->expirationDate = $expirationDate;
$this->brand = $brand;
$this->image = $image;
$this->token = $token;
$this->status = $status;
}
public function getName()
{
return $this->name;
}
public function getExpirationDate()
{
return $this->expirationDate;
}
public function getBrand()
{
return $this->brand;
}
public function getImage()
{
return $this->image;
}
public function getToken()
{
return $this->token;
}
public function getStatus()
{
return $this->status;
}
public function isExpired(): bool
{
return in_array($this->status, [SavedInstrument\Status::EXPIRED_CARD, SavedInstrument\Status::EXPIRED_TOKEN]);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Paynow\Model\PaymentMethods\SavedInstrument;
class Status
{
public const ACTIVE = 'ACTIVE';
public const EXPIRED_CARD = 'EXPIRED_CARD';
public const EXPIRED_TOKEN = 'EXPIRED_TOKEN';
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -7,5 +7,6 @@ class Type
public const BLIK = 'BLIK';
public const CARD = 'CARD';
public const GOOGLE_PAY = 'GOOGLE_PAY';
public const APPLE_PAY = 'APPLE_PAY';
public const PBL = 'PBL';
}

View File

@@ -51,13 +51,15 @@ class Payment extends Service
*
* @param string|null $currency
* @param int|null $amount
*
* @throws PaynowException
* @param bool $applePayEnabled
* @return PaymentMethods
* @throws PaynowException
*/
public function getPaymentMethods(?string $currency = null, ?int $amount = 0): PaymentMethods
public function getPaymentMethods(?string $currency = null, ?int $amount = 0, bool $applePayEnabled = true): PaymentMethods
{
$parameters = [];
$parameters = [
'applePayEnabled' => $applePayEnabled,
];
if (! empty($currency)) {
$parameters['currency'] = $currency;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Paynow\Util;
class ClientExternalIdCalculator
{
public static function calculate(string $clientId, string $secretKey): string
{
return bin2hex(hash_hmac('sha256', $clientId, $secretKey, true));
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Paynow\Tests\Util;
use Paynow\Model\PaymentMethods\SavedInstrument;
use Paynow\Model\PaymentMethods\SavedInstrument\Status as SavedInstrumentStatus;
use Paynow\Tests\TestCase;
class SavedInstrumentTest extends TestCase
{
/**
* @dataProvider dataProvider
*/
public function testIsExpired($status, $isExpired)
{
// given + when
$savedInstrument = new SavedInstrument('test', strtotime('+1 month'), 'VISA', 'test', '1234', $status);
// then
$this->assertEquals($isExpired, $savedInstrument->isExpired());
}
public function dataProvider(): array
{
return [
[SavedInstrumentStatus::ACTIVE, false],
[SavedInstrumentStatus::EXPIRED_CARD, true],
[SavedInstrumentStatus::EXPIRED_TOKEN, true],
];
}
}

View File

@@ -21,7 +21,7 @@
"php-http/httplug": "^2.0",
"php-http/message": "^1.2",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/http-factory-implementation": "^1.0",
"symfony/options-resolver": "^3.4 || ^4.0 || ^5.0 || ^6.0"
},
"require-dev": {
@@ -48,10 +48,5 @@
"scripts": {
"test": "vendor/bin/phpunit",
"test-ci": "vendor/bin/phpunit --coverage-clover build/coverage.xml"
},
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
}
}

View File

@@ -1,8 +1,9 @@
{
"name": "php-http/discovery",
"description": "Finds installed HTTPlug implementations and PSR-7 message factories",
"description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations",
"type": "composer-plugin",
"license": "MIT",
"keywords": ["http", "discovery", "client", "adapter", "message", "factory", "psr7"],
"keywords": ["http", "discovery", "client", "adapter", "message", "factory", "psr7", "psr17"],
"homepage": "http://php-http.org",
"authors": [
{
@@ -10,22 +11,32 @@
"email": "mark.sagikazar@gmail.com"
}
],
"provide": {
"php-http/async-client-implementation": "*",
"php-http/client-implementation": "*",
"psr/http-client-implementation": "*",
"psr/http-factory-implementation": "*",
"psr/http-message-implementation": "*"
},
"require": {
"php": "^7.1 || ^8.0"
"php": "^7.1 || ^8.0",
"composer-plugin-api": "^1.0|^2.0"
},
"require-dev": {
"composer/composer": "^1.0.2|^2.0",
"graham-campbell/phpspec-skip-example-extension": "^5.0",
"php-http/httplug": "^1.0 || ^2.0",
"php-http/message-factory": "^1.0",
"phpspec/phpspec": "^5.1 || ^6.1"
},
"suggest": {
"php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories"
"phpspec/phpspec": "^5.1 || ^6.1 || ^7.3",
"symfony/phpunit-bridge": "^6.2"
},
"autoload": {
"psr-4": {
"Http\\Discovery\\": "src/"
}
},
"exclude-from-classmap": [
"src/Composer/Plugin.php"
]
},
"autoload-dev": {
"psr-4": {
@@ -33,16 +44,19 @@
}
},
"scripts": {
"test": "vendor/bin/phpspec run",
"test": [
"vendor/bin/phpspec run",
"vendor/bin/simple-phpunit --group NothingInstalled"
],
"test-ci": "vendor/bin/phpspec run -c phpspec.ci.yml"
},
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
}
"class": "Http\\Discovery\\Composer\\Plugin",
"plugin-optional": true
},
"conflict": {
"nyholm/psr7": "<1.0"
"nyholm/psr7": "<1.0",
"zendframework/zend-diactoros": "*"
},
"prefer-stable": true,
"minimum-stability": "beta"

View File

@@ -6,6 +6,7 @@ use Http\Discovery\Exception\ClassInstantiationFailedException;
use Http\Discovery\Exception\DiscoveryFailedException;
use Http\Discovery\Exception\NoCandidateFoundException;
use Http\Discovery\Exception\StrategyUnavailableException;
use Http\Discovery\Strategy\DiscoveryStrategy;
/**
* Registry that based find results on class existence.
@@ -19,9 +20,10 @@ abstract class ClassDiscovery
/**
* A list of strategies to find classes.
*
* @var array
* @var DiscoveryStrategy[]
*/
private static $strategies = [
Strategy\GeneratedDiscoveryStrategy::class,
Strategy\CommonClassesStrategy::class,
Strategy\CommonPsr17ClassesStrategy::class,
Strategy\PuliBetaStrategy::class,
@@ -54,10 +56,17 @@ abstract class ClassDiscovery
return $class;
}
static $skipStrategy;
$skipStrategy ?? $skipStrategy = self::safeClassExists(Strategy\GeneratedDiscoveryStrategy::class) ? false : Strategy\GeneratedDiscoveryStrategy::class;
$exceptions = [];
foreach (self::$strategies as $strategy) {
if ($skipStrategy === $strategy) {
continue;
}
try {
$candidates = call_user_func($strategy.'::getCandidates', $type);
$candidates = $strategy::getCandidates($type);
} catch (StrategyUnavailableException $e) {
if (!isset(self::$deprecatedStrategies[$strategy])) {
$exceptions[] = $e;
@@ -122,7 +131,7 @@ abstract class ClassDiscovery
/**
* Set new strategies and clear the cache.
*
* @param array $strategies string array of fully qualified class name to a DiscoveryStrategy
* @param string[] $strategies list of fully qualified class names that implement DiscoveryStrategy
*/
public static function setStrategies(array $strategies)
{
@@ -143,7 +152,7 @@ abstract class ClassDiscovery
/**
* Append a strategy at the end of the strategy queue.
*
* @param string $strategy Fully qualified class name to a DiscoveryStrategy
* @param string $strategy Fully qualified class name of a DiscoveryStrategy
*/
public static function appendStrategy($strategy)
{
@@ -162,9 +171,6 @@ abstract class ClassDiscovery
self::clearCache();
}
/**
* Clear the cache.
*/
public static function clearCache()
{
self::$cache = [];
@@ -173,8 +179,6 @@ abstract class ClassDiscovery
/**
* Evaluates conditions to boolean.
*
* @param mixed $condition
*
* @return bool
*/
protected static function evaluateCondition($condition)
@@ -230,14 +234,13 @@ abstract class ClassDiscovery
}
/**
* We want to do a "safe" version of PHP's "class_exists" because Magento has a bug
* We need a "safe" version of PHP's "class_exists" because Magento has a bug
* (or they call it a "feature"). Magento is throwing an exception if you do class_exists()
* on a class that ends with "Factory" and if that file does not exits.
*
* This function will catch all potential exceptions and make sure it returns a boolean.
* This function catches all potential exceptions and makes sure to always return a boolean.
*
* @param string $class
* @param bool $autoload
*
* @return bool
*/

View File

@@ -0,0 +1,465 @@
<?php
namespace Http\Discovery\Composer;
use Composer\Composer;
use Composer\DependencyResolver\Pool;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Factory;
use Composer\Installer;
use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
use Composer\Json\JsonManipulator;
use Composer\Package\Locker;
use Composer\Package\Version\VersionParser;
use Composer\Package\Version\VersionSelector;
use Composer\Plugin\PluginInterface;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Repository\RepositorySet;
use Composer\Script\Event;
use Composer\Script\ScriptEvents;
use Composer\Util\Filesystem;
use Http\Discovery\ClassDiscovery;
/**
* Auto-installs missing implementations.
*
* When a dependency requires both this package and one of the supported `*-implementation`
* virtual packages, this plugin will auto-install a well-known implementation if none is
* found. The plugin will first look at already installed packages and figure out the
* preferred implementation to install based on the below stickyness rules (or on the first
* listed implementation if no rules match.)
*
* Don't miss updating src/Strategy/Common*Strategy.php when adding a new supported package.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class Plugin implements PluginInterface, EventSubscriberInterface
{
/**
* Describes, for every supported virtual implementation, which packages
* provide said implementation and which extra dependencies each package
* requires to provide the implementation.
*/
private const PROVIDE_RULES = [
'php-http/async-client-implementation' => [
'symfony/http-client:>=6.3' => ['guzzlehttp/promises', 'psr/http-factory-implementation', 'php-http/httplug'],
'symfony/http-client' => ['guzzlehttp/promises', 'php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'],
'php-http/guzzle7-adapter' => [],
'php-http/guzzle6-adapter' => [],
'php-http/curl-client' => [],
'php-http/react-adapter' => [],
],
'php-http/client-implementation' => [
'symfony/http-client:>=6.3' => ['psr/http-factory-implementation', 'php-http/httplug'],
'symfony/http-client' => ['php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'],
'php-http/guzzle7-adapter' => [],
'php-http/guzzle6-adapter' => [],
'php-http/cakephp-adapter' => [],
'php-http/curl-client' => [],
'php-http/react-adapter' => [],
'php-http/buzz-adapter' => [],
'php-http/artax-adapter' => [],
'kriswallsmith/buzz:^1' => [],
],
'psr/http-client-implementation' => [
'symfony/http-client' => ['psr/http-factory-implementation', 'psr/http-client'],
'guzzlehttp/guzzle' => [],
'kriswallsmith/buzz:^1' => [],
],
'psr/http-message-implementation' => [
'php-http/discovery' => ['psr/http-factory-implementation'],
],
'psr/http-factory-implementation' => [
'nyholm/psr7' => [],
'guzzlehttp/psr7:>=2' => [],
'slim/psr7' => [],
'laminas/laminas-diactoros' => [],
'phalcon/cphalcon:^4' => [],
'http-interop/http-factory-guzzle' => [],
'http-interop/http-factory-diactoros' => [],
'http-interop/http-factory-slim' => [],
'httpsoft/http-message' => [],
],
];
/**
* Describes which package should be preferred on the left side
* depending on which one is already installed on the right side.
*/
private const STICKYNESS_RULES = [
'symfony/http-client' => 'symfony/framework-bundle',
'php-http/guzzle7-adapter' => 'guzzlehttp/guzzle:^7',
'php-http/guzzle6-adapter' => 'guzzlehttp/guzzle:^6',
'php-http/guzzle5-adapter' => 'guzzlehttp/guzzle:^5',
'php-http/cakephp-adapter' => 'cakephp/cakephp',
'php-http/react-adapter' => 'react/event-loop',
'php-http/buzz-adapter' => 'kriswallsmith/buzz:^0.15.1',
'php-http/artax-adapter' => 'amphp/artax:^3',
'http-interop/http-factory-guzzle' => 'guzzlehttp/psr7:^1',
'http-interop/http-factory-slim' => 'slim/slim:^3',
];
private const INTERFACE_MAP = [
'php-http/async-client-implementation' => [
'Http\Client\HttpAsyncClient',
],
'php-http/client-implementation' => [
'Http\Client\HttpClient',
],
'psr/http-client-implementation' => [
'Psr\Http\Client\ClientInterface',
],
'psr/http-factory-implementation' => [
'Psr\Http\Message\RequestFactoryInterface',
'Psr\Http\Message\ResponseFactoryInterface',
'Psr\Http\Message\ServerRequestFactoryInterface',
'Psr\Http\Message\StreamFactoryInterface',
'Psr\Http\Message\UploadedFileFactoryInterface',
'Psr\Http\Message\UriFactoryInterface',
],
];
public static function getSubscribedEvents(): array
{
return [
ScriptEvents::PRE_AUTOLOAD_DUMP => 'preAutoloadDump',
ScriptEvents::POST_UPDATE_CMD => 'postUpdate',
];
}
public function activate(Composer $composer, IOInterface $io): void
{
}
public function deactivate(Composer $composer, IOInterface $io)
{
}
public function uninstall(Composer $composer, IOInterface $io)
{
}
public function postUpdate(Event $event)
{
$composer = $event->getComposer();
$repo = $composer->getRepositoryManager()->getLocalRepository();
$requires = [
$composer->getPackage()->getRequires(),
$composer->getPackage()->getDevRequires(),
];
$pinnedAbstractions = [];
$pinned = $composer->getPackage()->getExtra()['discovery'] ?? [];
foreach (self::INTERFACE_MAP as $abstraction => $interfaces) {
foreach (isset($pinned[$abstraction]) ? [] : $interfaces as $interface) {
if (!isset($pinned[$interface])) {
continue 2;
}
}
$pinnedAbstractions[$abstraction] = true;
}
$missingRequires = $this->getMissingRequires($repo, $requires, 'project' === $composer->getPackage()->getType(), $pinnedAbstractions);
$missingRequires = [
'require' => array_fill_keys(array_merge([], ...array_values($missingRequires[0])), '*'),
'require-dev' => array_fill_keys(array_merge([], ...array_values($missingRequires[1])), '*'),
'remove' => array_fill_keys(array_merge([], ...array_values($missingRequires[2])), '*'),
];
if (!$missingRequires = array_filter($missingRequires)) {
return;
}
$composerJsonContents = file_get_contents(Factory::getComposerFile());
$this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages'));
$installer = null;
// Find the composer installer, hack borrowed from symfony/flex
foreach (debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT) as $trace) {
if (isset($trace['object']) && $trace['object'] instanceof Installer) {
$installer = $trace['object'];
break;
}
}
if (!$installer) {
return;
}
$event->stopPropagation();
$dispatcher = $composer->getEventDispatcher();
$disableScripts = !method_exists($dispatcher, 'setRunScripts') || !((array) $dispatcher)["\0*\0runScripts"];
$composer = Factory::create($event->getIO(), null, false, $disableScripts);
/** @var Installer $installer */
$installer = clone $installer;
if (method_exists($installer, 'setAudit')) {
$trace['object']->setAudit(false);
}
// we need a clone of the installer to preserve its configuration state but with our own service objects
$installer->__construct(
$event->getIO(),
$composer->getConfig(),
$composer->getPackage(),
$composer->getDownloadManager(),
$composer->getRepositoryManager(),
$composer->getLocker(),
$composer->getInstallationManager(),
$composer->getEventDispatcher(),
$composer->getAutoloadGenerator()
);
if (method_exists($installer, 'setPlatformRequirementFilter')) {
$installer->setPlatformRequirementFilter(((array) $trace['object'])["\0*\0platformRequirementFilter"]);
}
if (0 !== $installer->run()) {
file_put_contents(Factory::getComposerFile(), $composerJsonContents);
return;
}
$versionSelector = new VersionSelector(ClassDiscovery::safeClassExists(RepositorySet::class) ? new RepositorySet() : new Pool());
$updateComposerJson = false;
foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) {
foreach (['require', 'require-dev'] as $key) {
if (!isset($missingRequires[$key][$package->getName()])) {
continue;
}
$updateComposerJson = true;
$missingRequires[$key][$package->getName()] = $versionSelector->findRecommendedRequireVersion($package);
}
}
if ($updateComposerJson) {
$this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages'));
$this->updateComposerLock($composer, $event->getIO());
}
}
public function getMissingRequires(InstalledRepositoryInterface $repo, array $requires, bool $isProject, array $pinnedAbstractions): array
{
$allPackages = [];
$devPackages = method_exists($repo, 'getDevPackageNames') ? array_fill_keys($repo->getDevPackageNames(), true) : [];
// One must require "php-http/discovery"
// to opt-in for auto-installation of virtual package implementations
if (!isset($requires[0]['php-http/discovery'])) {
$requires = [[], []];
}
foreach ($repo->getPackages() as $package) {
$allPackages[$package->getName()] = true;
if (1 < \count($names = $package->getNames(false))) {
$allPackages += array_fill_keys($names, false);
if (isset($devPackages[$package->getName()])) {
$devPackages += $names;
}
}
if (isset($package->getRequires()['php-http/discovery'])) {
$requires[(int) isset($devPackages[$package->getName()])] += $package->getRequires();
}
}
$missingRequires = [[], [], []];
$versionParser = new VersionParser();
if (ClassDiscovery::safeClassExists(\Phalcon\Http\Message\RequestFactory::class, false)) {
$missingRequires[0]['psr/http-factory-implementation'] = [];
$missingRequires[1]['psr/http-factory-implementation'] = [];
}
foreach ($requires as $dev => $rules) {
$abstractions = [];
$rules = array_intersect_key(self::PROVIDE_RULES, $rules);
while ($rules) {
$abstraction = key($rules);
if (isset($pinnedAbstractions[$abstraction])) {
unset($rules[$abstraction]);
continue;
}
$abstractions[] = $abstraction;
foreach (array_shift($rules) as $candidate => $deps) {
[$candidate, $version] = explode(':', $candidate, 2) + [1 => null];
if (!isset($allPackages[$candidate])) {
continue;
}
if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) {
continue;
}
if ($isProject && !$dev && isset($devPackages[$candidate])) {
$missingRequires[0][$abstraction] = [$candidate];
$missingRequires[2][$abstraction] = [$candidate];
} else {
$missingRequires[$dev][$abstraction] = [];
}
foreach ($deps as $dep) {
if (isset(self::PROVIDE_RULES[$dep])) {
$rules[$dep] = self::PROVIDE_RULES[$dep];
} elseif (!isset($allPackages[$dep])) {
$missingRequires[$dev][$abstraction][] = $dep;
} elseif ($isProject && !$dev && isset($devPackages[$dep])) {
$missingRequires[0][$abstraction][] = $dep;
$missingRequires[2][$abstraction][] = $dep;
}
}
break;
}
}
while ($abstractions) {
$abstraction = array_shift($abstractions);
if (isset($missingRequires[$dev][$abstraction])) {
continue;
}
$candidates = self::PROVIDE_RULES[$abstraction];
foreach ($candidates as $candidate => $deps) {
[$candidate, $version] = explode(':', $candidate, 2) + [1 => null];
if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) {
continue;
}
if (isset($allPackages[$candidate]) && (!$isProject || $dev || !isset($devPackages[$candidate]))) {
continue 2;
}
}
foreach (array_intersect_key(self::STICKYNESS_RULES, $candidates) as $candidate => $stickyRule) {
[$stickyName, $stickyVersion] = explode(':', $stickyRule, 2) + [1 => null];
if (!isset($allPackages[$stickyName]) || ($isProject && !$dev && isset($devPackages[$stickyName]))) {
continue;
}
if (null !== $stickyVersion && !$repo->findPackage($stickyName, $versionParser->parseConstraints($stickyVersion))) {
continue;
}
$candidates = [$candidate => $candidates[$candidate]];
break;
}
$dep = key($candidates);
[$dep] = explode(':', $dep, 2);
$missingRequires[$dev][$abstraction] = [$dep];
if ($isProject && !$dev && isset($devPackages[$dep])) {
$missingRequires[2][$abstraction][] = $dep;
}
}
}
$missingRequires[1] = array_diff_key($missingRequires[1], $missingRequires[0]);
return $missingRequires;
}
public function preAutoloadDump(Event $event)
{
$filesystem = new Filesystem();
// Double realpath() on purpose, see https://bugs.php.net/72738
$vendorDir = $filesystem->normalizePath(realpath(realpath($event->getComposer()->getConfig()->get('vendor-dir'))));
$filesystem->ensureDirectoryExists($vendorDir.'/composer');
$pinned = $event->getComposer()->getPackage()->getExtra()['discovery'] ?? [];
$candidates = [];
$allInterfaces = array_merge(...array_values(self::INTERFACE_MAP));
foreach ($pinned as $abstraction => $class) {
if (isset(self::INTERFACE_MAP[$abstraction])) {
$interfaces = self::INTERFACE_MAP[$abstraction];
} elseif (false !== $k = array_search($abstraction, $allInterfaces, true)) {
$interfaces = [$allInterfaces[$k]];
} else {
throw new \UnexpectedValueException(sprintf('Invalid "extra.discovery" pinned in composer.json: "%s" is not one of ["%s"].', $abstraction, implode('", "', array_keys(self::INTERFACE_MAP))));
}
foreach ($interfaces as $interface) {
$candidates[] = sprintf("case %s: return [['class' => %s]];\n", var_export($interface, true), var_export($class, true));
}
}
$file = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php';
if (!$candidates) {
if (file_exists($file)) {
unlink($file);
}
return;
}
$candidates = implode(' ', $candidates);
$code = <<<EOPHP
<?php
namespace Http\Discovery\Strategy;
class GeneratedDiscoveryStrategy implements DiscoveryStrategy
{
public static function getCandidates(\$type)
{
switch (\$type) {
$candidates
default: return [];
}
}
}
EOPHP
;
if (!file_exists($file) || $code !== file_get_contents($file)) {
file_put_contents($file, $code);
}
$rootPackage = $event->getComposer()->getPackage();
$autoload = $rootPackage->getAutoload();
$autoload['classmap'][] = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php';
$rootPackage->setAutoload($autoload);
}
private function updateComposerJson(array $missingRequires, bool $sortPackages)
{
$file = Factory::getComposerFile();
$contents = file_get_contents($file);
$manipulator = new JsonManipulator($contents);
foreach ($missingRequires as $key => $packages) {
foreach ($packages as $package => $constraint) {
if ('remove' === $key) {
$manipulator->removeSubNode('require-dev', $package);
} else {
$manipulator->addLink($key, $package, $constraint, $sortPackages);
}
}
}
file_put_contents($file, $manipulator->getContents());
}
private function updateComposerLock(Composer $composer, IOInterface $io)
{
$lock = substr(Factory::getComposerFile(), 0, -4).'lock';
$composerJson = file_get_contents(Factory::getComposerFile());
$lockFile = new JsonFile($lock, null, $io);
$locker = ClassDiscovery::safeClassExists(RepositorySet::class)
? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson)
: new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson);
$lockData = $locker->getLockData();
$lockData['content-hash'] = Locker::getContentHash($composerJson);
$lockFile->write($lockData);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -7,6 +7,6 @@ namespace Http\Discovery;
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
interface Exception
interface Exception extends \Throwable
{
}

View File

@@ -9,6 +9,8 @@ use Http\Discovery\Exception\DiscoveryFailedException;
* Finds an HTTP Client.
*
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
*
* @deprecated This will be removed in 2.0. Consider using Psr18ClientDiscovery.
*/
final class HttpClientDiscovery extends ClassDiscovery
{

View File

@@ -26,7 +26,7 @@ final class MessageFactoryDiscovery extends ClassDiscovery
try {
$messageFactory = static::findOneByType(MessageFactory::class);
} catch (DiscoveryFailedException $e) {
throw new NotFoundException('No message factories found. To use Guzzle, Diactoros or Slim Framework factories install php-http/message and the chosen message implementation.', 0, $e);
throw new NotFoundException('No php-http message factories found. Note that the php-http message factories are deprecated in favor of the PSR-17 message factories. To use the legacy Guzzle, Diactoros or Slim Framework factories of php-http, install php-http/message and php-http/message-factory and the chosen message implementation.', 0, $e);
}
return static::instantiateClass($messageFactory);

View File

@@ -0,0 +1,303 @@
<?php
namespace Http\Discovery;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileFactoryInterface;
use Psr\Http\Message\UploadedFileInterface;
use Psr\Http\Message\UriFactoryInterface;
use Psr\Http\Message\UriInterface;
/**
* A generic PSR-17 implementation.
*
* You can create this class with concrete factory instances or let
* it use discovery to find suitable implementations as needed.
*
* This class also provides two additional methods that are not in PSR17,
* to help with creating PSR-7 objects from PHP superglobals:
* - createServerRequestFromGlobals()
* - createUriFromGlobals()
*
* The code in this class is inspired by the "nyholm/psr7", "guzzlehttp/psr7"
* and "symfony/http-foundation" packages, all licenced under MIT.
*
* Copyright (c) 2004-2023 Fabien Potencier <fabien@symfony.com>
* Copyright (c) 2015 Michael Dowling <mtdowling@gmail.com>
* Copyright (c) 2015 Márk Sági-Kazár <mark.sagikazar@gmail.com>
* Copyright (c) 2015 Graham Campbell <hello@gjcampbell.co.uk>
* Copyright (c) 2016 Tobias Schultze <webmaster@tubo-world.de>
* Copyright (c) 2016 George Mponos <gmponos@gmail.com>
* Copyright (c) 2016-2018 Tobias Nyholm <tobias.nyholm@gmail.com>
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class Psr17Factory implements RequestFactoryInterface, ResponseFactoryInterface, ServerRequestFactoryInterface, StreamFactoryInterface, UploadedFileFactoryInterface, UriFactoryInterface
{
private $requestFactory;
private $responseFactory;
private $serverRequestFactory;
private $streamFactory;
private $uploadedFileFactory;
private $uriFactory;
public function __construct(
RequestFactoryInterface $requestFactory = null,
ResponseFactoryInterface $responseFactory = null,
ServerRequestFactoryInterface $serverRequestFactory = null,
StreamFactoryInterface $streamFactory = null,
UploadedFileFactoryInterface $uploadedFileFactory = null,
UriFactoryInterface $uriFactory = null
) {
$this->requestFactory = $requestFactory;
$this->responseFactory = $responseFactory;
$this->serverRequestFactory = $serverRequestFactory;
$this->streamFactory = $streamFactory;
$this->uploadedFileFactory = $uploadedFileFactory;
$this->uriFactory = $uriFactory;
$this->setFactory($requestFactory);
$this->setFactory($responseFactory);
$this->setFactory($serverRequestFactory);
$this->setFactory($streamFactory);
$this->setFactory($uploadedFileFactory);
$this->setFactory($uriFactory);
}
/**
* @param UriInterface|string $uri
*/
public function createRequest(string $method, $uri): RequestInterface
{
$factory = $this->requestFactory ?? $this->setFactory(Psr17FactoryDiscovery::findRequestFactory());
return $factory->createRequest(...\func_get_args());
}
public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
{
$factory = $this->responseFactory ?? $this->setFactory(Psr17FactoryDiscovery::findResponseFactory());
return $factory->createResponse(...\func_get_args());
}
/**
* @param UriInterface|string $uri
*/
public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
{
$factory = $this->serverRequestFactory ?? $this->setFactory(Psr17FactoryDiscovery::findServerRequestFactory());
return $factory->createServerRequest(...\func_get_args());
}
public function createServerRequestFromGlobals(array $server = null, array $get = null, array $post = null, array $cookie = null, array $files = null, StreamInterface $body = null): ServerRequestInterface
{
$server = $server ?? $_SERVER;
$request = $this->createServerRequest($server['REQUEST_METHOD'] ?? 'GET', $this->createUriFromGlobals($server), $server);
return $this->buildServerRequestFromGlobals($request, $server, $files ?? $_FILES)
->withQueryParams($get ?? $_GET)
->withParsedBody($post ?? $_POST)
->withCookieParams($cookie ?? $_COOKIE)
->withBody($body ?? $this->createStreamFromFile('php://input', 'r+'));
}
public function createStream(string $content = ''): StreamInterface
{
$factory = $this->streamFactory ?? $this->setFactory(Psr17FactoryDiscovery::findStreamFactory());
return $factory->createStream($content);
}
public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
{
$factory = $this->streamFactory ?? $this->setFactory(Psr17FactoryDiscovery::findStreamFactory());
return $factory->createStreamFromFile($filename, $mode);
}
/**
* @param resource $resource
*/
public function createStreamFromResource($resource): StreamInterface
{
$factory = $this->streamFactory ?? $this->setFactory(Psr17FactoryDiscovery::findStreamFactory());
return $factory->createStreamFromResource($resource);
}
public function createUploadedFile(StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null): UploadedFileInterface
{
$factory = $this->uploadedFileFactory ?? $this->setFactory(Psr17FactoryDiscovery::findUploadedFileFactory());
return $factory->createUploadedFile(...\func_get_args());
}
public function createUri(string $uri = ''): UriInterface
{
$factory = $this->uriFactory ?? $this->setFactory(Psr17FactoryDiscovery::findUriFactory());
return $factory->createUri(...\func_get_args());
}
public function createUriFromGlobals(array $server = null): UriInterface
{
return $this->buildUriFromGlobals($this->createUri(''), $server ?? $_SERVER);
}
private function setFactory($factory)
{
if (!$this->requestFactory && $factory instanceof RequestFactoryInterface) {
$this->requestFactory = $factory;
}
if (!$this->responseFactory && $factory instanceof ResponseFactoryInterface) {
$this->responseFactory = $factory;
}
if (!$this->serverRequestFactory && $factory instanceof ServerRequestFactoryInterface) {
$this->serverRequestFactory = $factory;
}
if (!$this->streamFactory && $factory instanceof StreamFactoryInterface) {
$this->streamFactory = $factory;
}
if (!$this->uploadedFileFactory && $factory instanceof UploadedFileFactoryInterface) {
$this->uploadedFileFactory = $factory;
}
if (!$this->uriFactory && $factory instanceof UriFactoryInterface) {
$this->uriFactory = $factory;
}
return $factory;
}
private function buildServerRequestFromGlobals(ServerRequestInterface $request, array $server, array $files): ServerRequestInterface
{
$request = $request
->withProtocolVersion(isset($server['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $server['SERVER_PROTOCOL']) : '1.1')
->withUploadedFiles($this->normalizeFiles($files));
$headers = [];
foreach ($server as $k => $v) {
if (0 === strpos($k, 'HTTP_')) {
$k = substr($k, 5);
} elseif (!\in_array($k, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'], true)) {
continue;
}
$k = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $k))));
$headers[$k] = $v;
}
if (!isset($headers['Authorization'])) {
if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
$headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
} elseif (isset($_SERVER['PHP_AUTH_USER'])) {
$headers['Authorization'] = 'Basic '.base64_encode($_SERVER['PHP_AUTH_USER'].':'.($_SERVER['PHP_AUTH_PW'] ?? ''));
} elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
$headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
}
}
foreach ($headers as $k => $v) {
try {
$request = $request->withHeader($k, $v);
} catch (\InvalidArgumentException $e) {
// ignore invalid headers
}
}
return $request;
}
private function buildUriFromGlobals(UriInterface $uri, array $server): UriInterface
{
$uri = $uri->withScheme(!empty($server['HTTPS']) && 'off' !== strtolower($server['HTTPS']) ? 'https' : 'http');
$hasPort = false;
if (isset($server['HTTP_HOST'])) {
$parts = parse_url('http://'.$server['HTTP_HOST']);
$uri = $uri->withHost($parts['host'] ?? 'localhost');
if ($parts['port'] ?? false) {
$hasPort = true;
$uri = $uri->withPort($parts['port']);
}
} else {
$uri = $uri->withHost($server['SERVER_NAME'] ?? $server['SERVER_ADDR'] ?? 'localhost');
}
if (!$hasPort && isset($server['SERVER_PORT'])) {
$uri = $uri->withPort($server['SERVER_PORT']);
}
$hasQuery = false;
if (isset($server['REQUEST_URI'])) {
$requestUriParts = explode('?', $server['REQUEST_URI'], 2);
$uri = $uri->withPath($requestUriParts[0]);
if (isset($requestUriParts[1])) {
$hasQuery = true;
$uri = $uri->withQuery($requestUriParts[1]);
}
}
if (!$hasQuery && isset($server['QUERY_STRING'])) {
$uri = $uri->withQuery($server['QUERY_STRING']);
}
return $uri;
}
private function normalizeFiles(array $files): array
{
foreach ($files as $k => $v) {
if ($v instanceof UploadedFileInterface) {
continue;
}
if (!\is_array($v)) {
unset($files[$k]);
} elseif (!isset($v['tmp_name'])) {
$files[$k] = $this->normalizeFiles($v);
} else {
$files[$k] = $this->createUploadedFileFromSpec($v);
}
}
return $files;
}
/**
* Create and return an UploadedFile instance from a $_FILES specification.
*
* @param array $value $_FILES struct
*
* @return UploadedFileInterface|UploadedFileInterface[]
*/
private function createUploadedFileFromSpec(array $value)
{
if (!is_array($tmpName = $value['tmp_name'])) {
$file = is_file($tmpName) ? $this->createStreamFromFile($tmpName, 'r') : $this->createStream();
return $this->createUploadedFile($file, $value['size'], $value['error'], $value['name'], $value['type']);
}
foreach ($tmpName as $k => $v) {
$tmpName[$k] = $this->createUploadedFileFromSpec([
'tmp_name' => $v,
'size' => $value['size'][$k] ?? null,
'error' => $value['error'][$k] ?? null,
'name' => $value['name'][$k] ?? null,
'type' => $value['type'][$k] ?? null,
]);
}
return $tmpName;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Http\Discovery;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface;
use Psr\Http\Message\UriFactoryInterface;
/**
* A generic PSR-18 and PSR-17 implementation.
*
* You can create this class with concrete client and factory instances
* or let it use discovery to find suitable implementations as needed.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class Psr18Client extends Psr17Factory implements ClientInterface
{
private $client;
public function __construct(
ClientInterface $client = null,
RequestFactoryInterface $requestFactory = null,
ResponseFactoryInterface $responseFactory = null,
ServerRequestFactoryInterface $serverRequestFactory = null,
StreamFactoryInterface $streamFactory = null,
UploadedFileFactoryInterface $uploadedFileFactory = null,
UriFactoryInterface $uriFactory = null
) {
parent::__construct($requestFactory, $responseFactory, $serverRequestFactory, $streamFactory, $uploadedFileFactory, $uriFactory);
$this->client = $client ?? Psr18ClientDiscovery::find();
}
public function sendRequest(RequestInterface $request): ResponseInterface
{
return $this->client->sendRequest($request);
}
}

View File

@@ -12,20 +12,17 @@ use Http\Adapter\Guzzle5\Client as Guzzle5;
use Http\Adapter\Guzzle6\Client as Guzzle6;
use Http\Adapter\Guzzle7\Client as Guzzle7;
use Http\Adapter\React\Client as React;
use Http\Adapter\Zend\Client as Zend;
use Http\Client\Curl\Client as Curl;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Http\Client\Socket\Client as Socket;
use Http\Discovery\ClassDiscovery;
use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Message\MessageFactory;
use Http\Message\MessageFactory\DiactorosMessageFactory;
use Http\Message\MessageFactory\GuzzleMessageFactory;
use Http\Message\MessageFactory\SlimMessageFactory;
use Http\Message\RequestFactory;
use Http\Message\StreamFactory;
use Http\Message\StreamFactory\DiactorosStreamFactory;
use Http\Message\StreamFactory\GuzzleStreamFactory;
@@ -41,12 +38,13 @@ use Psr\Http\Message\RequestFactoryInterface as Psr17RequestFactory;
use Slim\Http\Request as SlimRequest;
use Symfony\Component\HttpClient\HttplugClient as SymfonyHttplug;
use Symfony\Component\HttpClient\Psr18Client as SymfonyPsr18;
use Zend\Diactoros\Request as ZendDiactorosRequest;
/**
* @internal
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*
* Don't miss updating src/Composer/Plugin.php when adding a new supported class.
*/
final class CommonClassesStrategy implements DiscoveryStrategy
{
@@ -57,33 +55,30 @@ final class CommonClassesStrategy implements DiscoveryStrategy
MessageFactory::class => [
['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
['class' => GuzzleMessageFactory::class, 'condition' => [GuzzleRequest::class, GuzzleMessageFactory::class]],
['class' => DiactorosMessageFactory::class, 'condition' => [ZendDiactorosRequest::class, DiactorosMessageFactory::class]],
['class' => DiactorosMessageFactory::class, 'condition' => [DiactorosRequest::class, DiactorosMessageFactory::class]],
['class' => SlimMessageFactory::class, 'condition' => [SlimRequest::class, SlimMessageFactory::class]],
],
StreamFactory::class => [
['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
['class' => GuzzleStreamFactory::class, 'condition' => [GuzzleRequest::class, GuzzleStreamFactory::class]],
['class' => DiactorosStreamFactory::class, 'condition' => [ZendDiactorosRequest::class, DiactorosStreamFactory::class]],
['class' => DiactorosStreamFactory::class, 'condition' => [DiactorosRequest::class, DiactorosStreamFactory::class]],
['class' => SlimStreamFactory::class, 'condition' => [SlimRequest::class, SlimStreamFactory::class]],
],
UriFactory::class => [
['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
['class' => GuzzleUriFactory::class, 'condition' => [GuzzleRequest::class, GuzzleUriFactory::class]],
['class' => DiactorosUriFactory::class, 'condition' => [ZendDiactorosRequest::class, DiactorosUriFactory::class]],
['class' => DiactorosUriFactory::class, 'condition' => [DiactorosRequest::class, DiactorosUriFactory::class]],
['class' => SlimUriFactory::class, 'condition' => [SlimRequest::class, SlimUriFactory::class]],
],
HttpAsyncClient::class => [
['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, Promise::class, RequestFactory::class, [self::class, 'isPsr17FactoryInstalled']]],
['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, Promise::class, [self::class, 'isPsr17FactoryInstalled']]],
['class' => Guzzle7::class, 'condition' => Guzzle7::class],
['class' => Guzzle6::class, 'condition' => Guzzle6::class],
['class' => Curl::class, 'condition' => Curl::class],
['class' => React::class, 'condition' => React::class],
],
HttpClient::class => [
['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, RequestFactory::class, [self::class, 'isPsr17FactoryInstalled']]],
['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, [self::class, 'isPsr17FactoryInstalled']]],
['class' => Guzzle7::class, 'condition' => Guzzle7::class],
['class' => Guzzle6::class, 'condition' => Guzzle6::class],
['class' => Guzzle5::class, 'condition' => Guzzle5::class],
@@ -92,7 +87,6 @@ final class CommonClassesStrategy implements DiscoveryStrategy
['class' => Buzz::class, 'condition' => Buzz::class],
['class' => React::class, 'condition' => React::class],
['class' => Cake::class, 'condition' => Cake::class],
['class' => Zend::class, 'condition' => Zend::class],
['class' => Artax::class, 'condition' => Artax::class],
[
'class' => [self::class, 'buzzInstantiate'],
@@ -115,9 +109,6 @@ final class CommonClassesStrategy implements DiscoveryStrategy
],
];
/**
* {@inheritdoc}
*/
public static function getCandidates($type)
{
if (Psr18Client::class === $type) {
@@ -154,7 +145,7 @@ final class CommonClassesStrategy implements DiscoveryStrategy
public static function buzzInstantiate()
{
return new \Buzz\Client\FileGetContents(MessageFactoryDiscovery::find());
return new \Buzz\Client\FileGetContents(Psr17FactoryDiscovery::findResponseFactory());
}
public static function symfonyPsr18Instantiate()

View File

@@ -13,6 +13,8 @@ use Psr\Http\Message\UriFactoryInterface;
* @internal
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*
* Don't miss updating src/Composer/Plugin.php when adding a new supported class.
*/
final class CommonPsr17ClassesStrategy implements DiscoveryStrategy
{
@@ -23,74 +25,71 @@ final class CommonPsr17ClassesStrategy implements DiscoveryStrategy
RequestFactoryInterface::class => [
'Phalcon\Http\Message\RequestFactory',
'Nyholm\Psr7\Factory\Psr17Factory',
'Zend\Diactoros\RequestFactory',
'GuzzleHttp\Psr7\HttpFactory',
'Http\Factory\Diactoros\RequestFactory',
'Http\Factory\Guzzle\RequestFactory',
'Http\Factory\Slim\RequestFactory',
'Laminas\Diactoros\RequestFactory',
'Slim\Psr7\Factory\RequestFactory',
'HttpSoft\Message\RequestFactory',
],
ResponseFactoryInterface::class => [
'Phalcon\Http\Message\ResponseFactory',
'Nyholm\Psr7\Factory\Psr17Factory',
'Zend\Diactoros\ResponseFactory',
'GuzzleHttp\Psr7\HttpFactory',
'Http\Factory\Diactoros\ResponseFactory',
'Http\Factory\Guzzle\ResponseFactory',
'Http\Factory\Slim\ResponseFactory',
'Laminas\Diactoros\ResponseFactory',
'Slim\Psr7\Factory\ResponseFactory',
'HttpSoft\Message\ResponseFactory',
],
ServerRequestFactoryInterface::class => [
'Phalcon\Http\Message\ServerRequestFactory',
'Nyholm\Psr7\Factory\Psr17Factory',
'Zend\Diactoros\ServerRequestFactory',
'GuzzleHttp\Psr7\HttpFactory',
'Http\Factory\Diactoros\ServerRequestFactory',
'Http\Factory\Guzzle\ServerRequestFactory',
'Http\Factory\Slim\ServerRequestFactory',
'Laminas\Diactoros\ServerRequestFactory',
'Slim\Psr7\Factory\ServerRequestFactory',
'HttpSoft\Message\ServerRequestFactory',
],
StreamFactoryInterface::class => [
'Phalcon\Http\Message\StreamFactory',
'Nyholm\Psr7\Factory\Psr17Factory',
'Zend\Diactoros\StreamFactory',
'GuzzleHttp\Psr7\HttpFactory',
'Http\Factory\Diactoros\StreamFactory',
'Http\Factory\Guzzle\StreamFactory',
'Http\Factory\Slim\StreamFactory',
'Laminas\Diactoros\StreamFactory',
'Slim\Psr7\Factory\StreamFactory',
'HttpSoft\Message\StreamFactory',
],
UploadedFileFactoryInterface::class => [
'Phalcon\Http\Message\UploadedFileFactory',
'Nyholm\Psr7\Factory\Psr17Factory',
'Zend\Diactoros\UploadedFileFactory',
'GuzzleHttp\Psr7\HttpFactory',
'Http\Factory\Diactoros\UploadedFileFactory',
'Http\Factory\Guzzle\UploadedFileFactory',
'Http\Factory\Slim\UploadedFileFactory',
'Laminas\Diactoros\UploadedFileFactory',
'Slim\Psr7\Factory\UploadedFileFactory',
'HttpSoft\Message\UploadedFileFactory',
],
UriFactoryInterface::class => [
'Phalcon\Http\Message\UriFactory',
'Nyholm\Psr7\Factory\Psr17Factory',
'Zend\Diactoros\UriFactory',
'GuzzleHttp\Psr7\HttpFactory',
'Http\Factory\Diactoros\UriFactory',
'Http\Factory\Guzzle\UriFactory',
'Http\Factory\Slim\UriFactory',
'Laminas\Diactoros\UriFactory',
'Slim\Psr7\Factory\UriFactory',
'HttpSoft\Message\UriFactory',
],
];
/**
* {@inheritdoc}
*/
public static function getCandidates($type)
{
$candidates = [];

View File

@@ -13,9 +13,6 @@ use Http\Mock\Client as Mock;
*/
final class MockClientStrategy implements DiscoveryStrategy
{
/**
* {@inheritdoc}
*/
public static function getCandidates($type)
{
if (is_a(HttpClient::class, $type, true) || is_a(HttpAsyncClient::class, $type, true)) {

View File

@@ -11,6 +11,7 @@ use Puli\GeneratedPuliFactory;
* Find candidates using Puli.
*
* @internal
*
* @final
*
* @author David de Boer <david@ddeboer.nl>
@@ -71,9 +72,6 @@ class PuliBetaStrategy implements DiscoveryStrategy
return self::$puliDiscovery;
}
/**
* {@inheritdoc}
*/
public static function getCandidates($type)
{
$returnData = [];

View File

@@ -22,16 +22,11 @@
"php": "^7.1 || ^8.0",
"php-http/promise": "^1.1",
"psr/http-client": "^1.0",
"psr/http-message": "^1.0"
"psr/http-message": "^1.0 || ^2.0"
},
"require-dev": {
"friends-of-phpspec/phpspec-code-coverage": "^4.1",
"phpspec/phpspec": "^5.1 || ^6.0"
},
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
"friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0",
"phpspec/phpspec": "^5.1 || ^6.0 || ^7.0"
},
"autoload": {
"psr-4": {

View File

@@ -9,6 +9,8 @@ use Psr\Http\Client\ClientInterface;
*
* Provide the Httplug HttpClient interface for BC.
* You should typehint Psr\Http\Client\ClientInterface in new code
*
* @deprecated since version 2.4, use Psr\Http\Client\ClientInterface instead; see https://www.php-fig.org/psr/psr-18/
*/
interface HttpClient extends ClientInterface
{

View File

@@ -0,0 +1 @@
Please see http://docs.php-http.org/en/latest/development/contributing.html

View File

@@ -1,4 +1,4 @@
Copyright (c) 2015 PHP HTTP Team <team@php-http.org>
Copyright (c) 2015-2016 PHP HTTP Team <team@php-http.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -12,7 +12,7 @@
],
"require": {
"php": ">=5.4",
"psr/http-message": "^1.0"
"psr/http-message": "^1.0 || ^2.0"
},
"autoload": {
"psr-4": {
@@ -21,7 +21,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
"dev-master": "1.x-dev"
}
}
}

View File

@@ -1,5 +1,6 @@
{
"version": "1.0",
"name": "php-http/message-factory",
"binding-types": {
"Http\\Message\\MessageFactory": {
"description": "PSR-7 Message Factory",

View File

@@ -6,6 +6,8 @@ namespace Http\Message;
* Factory for PSR-7 Request and Response.
*
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
*
* @deprecated since version 1.1, use Psr\Http\Message\RequestFactoryInterface and Psr\Http\Message\ResponseFactoryInterface instead.
*/
interface MessageFactory extends RequestFactory, ResponseFactory
{

View File

@@ -10,6 +10,8 @@ use Psr\Http\Message\StreamInterface;
* Factory for PSR-7 Request.
*
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
*
* @deprecated since version 1.1, use Psr\Http\Message\RequestFactoryInterface instead.
*/
interface RequestFactory
{

View File

@@ -11,6 +11,8 @@ use Psr\Http\Message\StreamInterface;
* This factory contract can be reused in Message and Server Message factories.
*
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
*
* @deprecated since version 1.1, use Psr\Http\Message\ResponseFactoryInterface instead.
*/
interface ResponseFactory
{

View File

@@ -8,6 +8,8 @@ use Psr\Http\Message\StreamInterface;
* Factory for PSR-7 Stream.
*
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
*
* @deprecated since version 1.1, use Psr\Http\Message\StreamFactoryInterface instead.
*/
interface StreamFactory
{
@@ -18,8 +20,8 @@ interface StreamFactory
*
* @return StreamInterface
*
* @throws \InvalidArgumentException If the stream body is invalid.
* @throws \RuntimeException If creating the stream from $body fails.
* @throws \InvalidArgumentException if the stream body is invalid
* @throws \RuntimeException if creating the stream from $body fails
*/
public function createStream($body = null);
}

View File

@@ -8,6 +8,8 @@ use Psr\Http\Message\UriInterface;
* Factory for PSR-7 URI.
*
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
*
* @deprecated since version 1.1, use Psr\Http\Message\UriFactoryInterface instead.
*/
interface UriFactory
{
@@ -18,7 +20,7 @@ interface UriFactory
*
* @return UriInterface
*
* @throws \InvalidArgumentException If the $uri argument can not be converted into a valid URI.
* @throws \InvalidArgumentException if the $uri argument can not be converted into a valid URI
*/
public function createUri($uri);
}

View File

@@ -18,7 +18,7 @@
"php": "^7.1 || ^8.0",
"clue/stream-filter": "^1.5",
"php-http/message-factory": "^1.0.2",
"psr/http-message": "^1.0"
"psr/http-message": "^1.0 || ^2.0"
},
"provide": {
"php-http/message-factory-implementation": "1.0"
@@ -43,11 +43,6 @@
"ergebnis/composer-normalize": true
}
},
"extra": {
"branch-alias": {
"dev-master": "1.10-dev"
}
},
"autoload": {
"psr-4": {
"Http\\Message\\": "src/"

View File

@@ -3,7 +3,6 @@
namespace Http\Message\Authentication;
use Http\Message\Authentication;
use InvalidArgumentException;
use Psr\Http\Message\RequestInterface;
/**
@@ -38,7 +37,7 @@ final class Wsse implements Authentication
$this->username = $username;
$this->password = $password;
if (false === in_array($hashAlgorithm, hash_algos())) {
throw new InvalidArgumentException(sprintf('Unaccepted hashing algorithm: %s', $hashAlgorithm));
throw new \InvalidArgumentException(sprintf('Unaccepted hashing algorithm: %s', $hashAlgorithm));
}
$this->hashAlgorithm = $hashAlgorithm;
}

View File

@@ -399,8 +399,6 @@ final class Cookie
*
* This does not compare the values, only name, domain and path.
*
* @param Cookie $cookie
*
* @return bool
*/
public function match(self $cookie)

View File

@@ -10,7 +10,7 @@ namespace Http\Message;
final class CookieJar implements \Countable, \IteratorAggregate
{
/**
* @var \SplObjectStorage<object, mixed>
* @var \SplObjectStorage<Cookie, mixed>
*/
private $cookies;

View File

@@ -17,7 +17,7 @@ abstract class FilteredStream implements StreamInterface
rewind as private doRewind;
seek as private doSeek;
}
const BUFFER_SIZE = 8192;
public const BUFFER_SIZE = 8192;
/**
* @var callable

View File

@@ -2,10 +2,11 @@
namespace Http\Message\UriFactory;
use function GuzzleHttp\Psr7\uri_for;
use GuzzleHttp\Psr7\Utils;
use Http\Message\UriFactory;
use function GuzzleHttp\Psr7\uri_for;
/**
* Creates Guzzle URI.
*

View File

@@ -18,8 +18,8 @@
"php" : "^7.1 || ^8.0"
},
"require-dev": {
"friends-of-phpspec/phpspec-code-coverage" : "^4.3.2",
"phpspec/phpspec": "^5.1.2 || ^6.2"
"friends-of-phpspec/phpspec-code-coverage" : "^4.3.2 || ^6.3",
"phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4"
},
"autoload": {
"psr-4": {
@@ -29,10 +29,5 @@
"scripts": {
"test": "vendor/bin/phpspec run",
"test-ci": "vendor/bin/phpspec run -c phpspec.yml.ci"
},
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
}
}

View File

@@ -0,0 +1,6 @@
parameters:
level: max
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false
paths:
- src

View File

@@ -6,16 +6,20 @@ namespace Http\Promise;
* A promise already fulfilled.
*
* @author Joel Wurtz <joel.wurtz@gmail.com>
*
* @template-covariant T
*
* @implements Promise<T>
*/
final class FulfilledPromise implements Promise
{
/**
* @var mixed
* @var T
*/
private $result;
/**
* @param $result
* @param T $result
*/
public function __construct($result)
{

View File

@@ -12,6 +12,8 @@ namespace Http\Promise;
*
* @author Joel Wurtz <joel.wurtz@gmail.com>
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
*
* @template-covariant T
*/
interface Promise
{
@@ -36,10 +38,12 @@ interface Promise
* If you do not care about one of the cases, you can set the corresponding callable to null
* The callback will be called when the value arrived and never more than once.
*
* @param callable|null $onFulfilled called when a response will be available
* @param callable|null $onRejected called when an exception occurs
* @param callable(T): V|null $onFulfilled called when a response will be available
* @param callable(\Exception): V|null $onRejected called when an exception occurs
*
* @return Promise a new resolved promise with value of the executed callback (onFulfilled / onRejected)
* @return Promise<V> a new resolved promise with value of the executed callback (onFulfilled / onRejected)
*
* @template V
*/
public function then(callable $onFulfilled = null, callable $onRejected = null);
@@ -61,7 +65,7 @@ interface Promise
*
* @param bool $unwrap Whether to return resolved value / throw reason or not
*
* @return mixed Resolved value, null if $unwrap is set to false
* @return T Resolved value, null if $unwrap is set to false
*
* @throws \Exception the rejection reason if $unwrap is set to true and the request failed
*/

View File

@@ -6,6 +6,10 @@ namespace Http\Promise;
* A rejected promise.
*
* @author Joel Wurtz <joel.wurtz@gmail.com>
*
* @template-covariant T
*
* @implements Promise<T>
*/
final class RejectedPromise implements Promise
{
@@ -14,9 +18,6 @@ final class RejectedPromise implements Promise
*/
private $exception;
/**
* @param \Exception $exception
*/
public function __construct(\Exception $exception)
{
$this->exception = $exception;

View File

@@ -7,12 +7,15 @@
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
"homepage": "https://www.php-fig.org/"
}
],
"support": {
"source": "https://github.com/php-fig/http-client"
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0"
"psr/http-message": "^1.0 || ^2.0"
},
"autoload": {
"psr-4": {

View File

@@ -15,12 +15,12 @@
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
"homepage": "https://www.php-fig.org/"
}
],
"require": {
"php": ">=7.0.0",
"psr/http-message": "^1.0"
"psr/http-message": "^1.0 || ^2.0"
},
"autoload": {
"psr-4": {