This commit is contained in:
Hanson.xyz Dev
2026-01-04 17:50:08 -06:00
parent 7e45ce0756
commit acc8ac87a0
4131 changed files with 232562 additions and 250244 deletions
@@ -9,7 +9,7 @@ final class BodySummarizer implements \YoastSEO_Vendor\GuzzleHttp\BodySummarizer
* @var int|null
*/
private $truncateAt;
public function __construct(int $truncateAt = null)
public function __construct(?int $truncateAt = null)
{
$this->truncateAt = $truncateAt;
}
@@ -49,7 +49,7 @@ class Client implements \YoastSEO_Vendor\GuzzleHttp\ClientInterface, \YoastSEO_V
*
* @param array $config Client configuration settings.
*
* @see \GuzzleHttp\RequestOptions for a list of available request options.
* @see RequestOptions for a list of available request options.
*/
public function __construct(array $config = [])
{
@@ -178,7 +178,7 @@ class Client implements \YoastSEO_Vendor\GuzzleHttp\ClientInterface, \YoastSEO_V
*
* @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
*/
public function getConfig(string $option = null)
public function getConfig(?string $option = null)
{
return $option === null ? $this->config : $this->config[$option] ?? null;
}
@@ -74,5 +74,5 @@ interface ClientInterface
*
* @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0.
*/
public function getConfig(string $option = null);
public function getConfig(?string $option = null);
}
@@ -86,7 +86,7 @@ class CookieJar implements \YoastSEO_Vendor\GuzzleHttp\Cookie\CookieJarInterface
return $cookie->toArray();
}, $this->getIterator()->getArrayCopy());
}
public function clear(string $domain = null, string $path = null, string $name = null) : void
public function clear(?string $domain = null, ?string $path = null, ?string $name = null) : void
{
if (!$domain) {
$this->cookies = [];
@@ -58,7 +58,7 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate
* @param string|null $path Clears cookies matching a domain and path
* @param string|null $name Clears cookies matching a domain, path, and name
*/
public function clear(string $domain = null, string $path = null, string $name = null) : void;
public function clear(?string $domain = null, ?string $path = null, ?string $name = null) : void;
/**
* Discard all sessions cookies.
*
@@ -46,6 +46,10 @@ class SetCookie
if (\is_numeric($value)) {
$data[$search] = (int) $value;
}
} elseif ($search === 'Secure' || $search === 'Discard' || $search === 'HttpOnly') {
if ($value) {
$data[$search] = \true;
}
} else {
$data[$search] = $value;
}
@@ -9,7 +9,7 @@ use YoastSEO_Vendor\Psr\Http\Message\ResponseInterface;
*/
class BadResponseException extends \YoastSEO_Vendor\GuzzleHttp\Exception\RequestException
{
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response, \Throwable $previous = null, array $handlerContext = [])
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response, ?\Throwable $previous = null, array $handlerContext = [])
{
parent::__construct($message, $request, $response, $previous, $handlerContext);
}
@@ -19,7 +19,7 @@ class ConnectException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
* @var array
*/
private $handlerContext;
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \Throwable $previous = null, array $handlerContext = [])
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\Throwable $previous = null, array $handlerContext = [])
{
parent::__construct($message, 0, $previous);
$this->request = $request;
@@ -7,7 +7,6 @@ use YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface;
use YoastSEO_Vendor\Psr\Http\Client\RequestExceptionInterface;
use YoastSEO_Vendor\Psr\Http\Message\RequestInterface;
use YoastSEO_Vendor\Psr\Http\Message\ResponseInterface;
use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
/**
* HTTP Request exception
*/
@@ -25,7 +24,7 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
* @var array
*/
private $handlerContext;
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $previous = null, array $handlerContext = [])
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $previous = null, array $handlerContext = [])
{
// Set the code of the exception if the response is set and not future.
$code = $response ? $response->getStatusCode() : 0;
@@ -50,7 +49,7 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
* @param array $handlerContext Optional handler context
* @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer
*/
public static function create(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $previous = null, array $handlerContext = [], \YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : self
public static function create(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $previous = null, array $handlerContext = [], ?\YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : self
{
if (!$response) {
return new self('Error completing request', $request, null, $previous, $handlerContext);
@@ -66,8 +65,7 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
$label = 'Unsuccessful request';
$className = __CLASS__;
}
$uri = $request->getUri();
$uri = static::obfuscateUri($uri);
$uri = \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri());
// Client Error: `GET /` resulted in a `404 Not Found` response:
// <html> ... (truncated)
$message = \sprintf('%s: `%s %s` resulted in a `%s %s` response', $label, $request->getMethod(), $uri->__toString(), $response->getStatusCode(), $response->getReasonPhrase());
@@ -77,17 +75,6 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
}
return new $className($message, $request, $response, $previous, $handlerContext);
}
/**
* Obfuscates URI if there is a username and a password present
*/
private static function obfuscateUri(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri) : \YoastSEO_Vendor\Psr\Http\Message\UriInterface
{
$userInfo = $uri->getUserInfo();
if (\false !== ($pos = \strpos($userInfo, ':'))) {
return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
}
return $uri;
}
/**
* Get the request that caused the exception
*/
@@ -11,6 +11,7 @@ use YoastSEO_Vendor\GuzzleHttp\Psr7\LazyOpenStream;
use YoastSEO_Vendor\GuzzleHttp\TransferStats;
use YoastSEO_Vendor\GuzzleHttp\Utils;
use YoastSEO_Vendor\Psr\Http\Message\RequestInterface;
use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
/**
* Creates curl resources from a request
*
@@ -40,6 +41,14 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
}
public function create(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options) : \YoastSEO_Vendor\GuzzleHttp\Handler\EasyHandle
{
$protocolVersion = $request->getProtocolVersion();
if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
if (!self::supportsHttp2()) {
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
}
} elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException(\sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
}
if (isset($options['curl']['body_as_string'])) {
$options['_body_as_string'] = $options['curl']['body_as_string'];
unset($options['curl']['body_as_string']);
@@ -61,12 +70,38 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
\curl_setopt_array($easy->handle, $conf);
return $easy;
}
private static function supportsHttp2() : bool
{
static $supportsHttp2 = null;
if (null === $supportsHttp2) {
$supportsHttp2 = self::supportsTls12() && \defined('CURL_VERSION_HTTP2') && \CURL_VERSION_HTTP2 & \curl_version()['features'];
}
return $supportsHttp2;
}
private static function supportsTls12() : bool
{
static $supportsTls12 = null;
if (null === $supportsTls12) {
$supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
}
return $supportsTls12;
}
private static function supportsTls13() : bool
{
static $supportsTls13 = null;
if (null === $supportsTls13) {
$supportsTls13 = \defined('CURL_SSLVERSION_TLSv1_3') && \CURL_SSLVERSION_TLSv1_3 & \curl_version()['features'];
}
return $supportsTls13;
}
public function release(\YoastSEO_Vendor\GuzzleHttp\Handler\EasyHandle $easy) : void
{
$resource = $easy->handle;
unset($easy->handle);
if (\count($this->handles) >= $this->maxHandles) {
\curl_close($resource);
if (\PHP_VERSION_ID < 80000) {
\curl_close($resource);
}
} else {
// Remove all callback functions as they can hold onto references
// and are not cleaned up by curl_reset. Using curl_setopt_array
@@ -118,7 +153,7 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
{
// Get error information and release the handle to the factory.
$ctx = ['errno' => $easy->errno, 'error' => \curl_error($easy->handle), 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME)] + \curl_getinfo($easy->handle);
$ctx[self::CURL_VERSION_STR] = \curl_version()['version'];
$ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
$factory->release($easy);
// Retry when nothing is present or when curl failed to rewind.
if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
@@ -126,6 +161,14 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
}
return self::createRejection($easy, $ctx);
}
private static function getCurlVersion() : string
{
static $curlVersion = null;
if (null === $curlVersion) {
$curlVersion = \curl_version()['version'];
}
return $curlVersion;
}
private static function createRejection(\YoastSEO_Vendor\GuzzleHttp\Handler\EasyHandle $easy, array $ctx) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
static $connectionErrors = [\CURLE_OPERATION_TIMEOUTED => \true, \CURLE_COULDNT_RESOLVE_HOST => \true, \CURLE_COULDNT_CONNECT => \true, \CURLE_SSL_CONNECT_ERROR => \true, \CURLE_GOT_NOTHING => \true];
@@ -137,15 +180,32 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
if ($easy->onHeadersException) {
return \YoastSEO_Vendor\GuzzleHttp\Promise\Create::rejectionFor(new \YoastSEO_Vendor\GuzzleHttp\Exception\RequestException('An error was encountered during the on_headers event', $easy->request, $easy->response, $easy->onHeadersException, $ctx));
}
$message = \sprintf('cURL error %s: %s (%s)', $ctx['errno'], $ctx['error'], 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html');
$uriString = (string) $easy->request->getUri();
if ($uriString !== '' && \false === \strpos($ctx['error'], $uriString)) {
$message .= \sprintf(' for %s', $uriString);
$uri = $easy->request->getUri();
$sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
$message = \sprintf('cURL error %s: %s (%s)', $ctx['errno'], $sanitizedError, 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html');
if ('' !== $sanitizedError) {
$redactedUriString = \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
if ($redactedUriString !== '' && \false === \strpos($sanitizedError, $redactedUriString)) {
$message .= \sprintf(' for %s', $redactedUriString);
}
}
// Create a connection exception if it was a specific error code.
$error = isset($connectionErrors[$easy->errno]) ? new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException($message, $easy->request, null, $ctx) : new \YoastSEO_Vendor\GuzzleHttp\Exception\RequestException($message, $easy->request, $easy->response, null, $ctx);
return \YoastSEO_Vendor\GuzzleHttp\Promise\Create::rejectionFor($error);
}
private static function sanitizeCurlError(string $error, \YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri) : string
{
if ('' === $error) {
return $error;
}
$baseUri = $uri->withQuery('')->withFragment('');
$baseUriString = $baseUri->__toString();
if ('' === $baseUriString) {
return $error;
}
$redactedUriString = \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
return \str_replace($baseUriString, $redactedUriString, $error);
}
/**
* @return array<int|string, mixed>
*/
@@ -156,10 +216,10 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
$conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
}
$version = $easy->request->getProtocolVersion();
if ($version == 1.1) {
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
} elseif ($version == 2.0) {
if ('2' === $version || '2.0' === $version) {
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
} elseif ('1.1' === $version) {
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
} else {
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0;
}
@@ -285,8 +345,10 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
// The empty string enables all available decoders and implicitly
// sets a matching 'Accept-Encoding' header.
$conf[\CURLOPT_ENCODING] = '';
// But as the user did not specify any acceptable encodings we need
// to overwrite this implicit header with an empty one.
// But as the user did not specify any encoding preference,
// let's leave it up to server by preventing curl from sending
// the header, which will be interpreted as 'Accept-Encoding: *'.
// https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
$conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
}
}
@@ -343,23 +405,30 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
}
}
if (isset($options['crypto_method'])) {
if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
if (!\defined('CURL_SSLVERSION_TLSv1_0')) {
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.0 not supported by your version of cURL');
$protocolVersion = $easy->request->getProtocolVersion();
// If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
} elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
if (!self::supportsTls13()) {
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
}
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
} else {
throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
}
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
if (!\defined('CURL_SSLVERSION_TLSv1_1')) {
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.1 not supported by your version of cURL');
}
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
if (!\defined('CURL_SSLVERSION_TLSv1_2')) {
if (!self::supportsTls12()) {
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
}
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
} elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
if (!\defined('CURL_SSLVERSION_TLSv1_3')) {
if (!self::supportsTls13()) {
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
}
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
@@ -489,7 +558,9 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
public function __destruct()
{
foreach ($this->handles as $id => $handle) {
\curl_close($handle);
if (\PHP_VERSION_ID < 80000) {
\curl_close($handle);
}
unset($this->handles[$id]);
}
}
@@ -2,6 +2,7 @@
namespace YoastSEO_Vendor\GuzzleHttp\Handler;
use Closure;
use YoastSEO_Vendor\GuzzleHttp\Promise as P;
use YoastSEO_Vendor\GuzzleHttp\Promise\Promise;
use YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
@@ -129,6 +130,8 @@ class CurlMultiHandler
}
}
}
// Run curl_multi_exec in the queue to enable other async tasks to run
\YoastSEO_Vendor\GuzzleHttp\Promise\Utils::queue()->add(\Closure::fromCallable([$this, 'tickInQueue']));
// Step through the task queue which may add additional requests.
\YoastSEO_Vendor\GuzzleHttp\Promise\Utils::queue()->run();
if ($this->active && \curl_multi_select($this->_mh, $this->selectTimeout) === -1) {
@@ -137,9 +140,21 @@ class CurlMultiHandler
\usleep(250);
}
while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
// Prevent busy looping for slow HTTP requests.
\curl_multi_select($this->_mh, $this->selectTimeout);
}
$this->processMessages();
}
/**
* Runs \curl_multi_exec() inside the event loop, to prevent busy looping
*/
private function tickInQueue() : void
{
if (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
\curl_multi_select($this->_mh, 0);
\YoastSEO_Vendor\GuzzleHttp\Promise\Utils::queue()->add(\Closure::fromCallable([$this, 'tickInQueue']));
}
}
/**
* Runs until all outstanding connections have completed.
*/
@@ -184,7 +199,9 @@ class CurlMultiHandler
$handle = $this->handles[$id]['easy']->handle;
unset($this->delays[$id], $this->handles[$id]);
\curl_multi_remove_handle($this->_mh, $handle);
\curl_close($handle);
if (\PHP_VERSION_ID < 80000) {
\curl_close($handle);
}
return \true;
}
private function processMessages() : void
@@ -46,20 +46,20 @@ class MockHandler implements \Countable
* @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
* @param callable|null $onRejected Callback to invoke when the return value is rejected.
*/
public static function createWithMiddleware(array $queue = null, callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\HandlerStack
public static function createWithMiddleware(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\HandlerStack
{
return \YoastSEO_Vendor\GuzzleHttp\HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
}
/**
* The passed in value must be an array of
* {@see \Psr\Http\Message\ResponseInterface} objects, Exceptions,
* {@see ResponseInterface} objects, Exceptions,
* callables, or Promises.
*
* @param array<int, mixed>|null $queue The parameters to be passed to the append function, as an indexed array.
* @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
* @param callable|null $onRejected Callback to invoke when the return value is rejected.
*/
public function __construct(array $queue = null, callable $onFulfilled = null, callable $onRejected = null)
public function __construct(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null)
{
$this->onFulfilled = $onFulfilled;
$this->onRejected = $onRejected;
@@ -163,7 +163,7 @@ class MockHandler implements \Countable
/**
* @param mixed $reason Promise or reason.
*/
private function invokeStats(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, $reason = null) : void
private function invokeStats(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, $reason = null) : void
{
if (isset($options['on_stats'])) {
$transferTime = $options['transfer_time'] ?? 0;
@@ -16,10 +16,10 @@ class Proxy
* Sends synchronous requests to a specific handler while sending all other
* requests to another handler.
*
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for normal responses
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $sync Handler used for synchronous responses.
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for normal responses
* @param callable(RequestInterface, array): PromiseInterface $sync Handler used for synchronous responses.
*
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
*/
public static function wrapSync(callable $default, callable $sync) : callable
{
@@ -35,10 +35,10 @@ class Proxy
* performance benefits of curl while still supporting true streaming
* through the StreamHandler.
*
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for non-streaming responses
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $streaming Handler used for streaming responses
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for non-streaming responses
* @param callable(RequestInterface, array): PromiseInterface $streaming Handler used for streaming responses
*
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
*/
public static function wrapStreaming(callable $default, callable $streaming) : callable
{
@@ -37,13 +37,17 @@ class StreamHandler
if (isset($options['delay'])) {
\usleep($options['delay'] * 1000);
}
$protocolVersion = $request->getProtocolVersion();
if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException(\sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);
}
$startTime = isset($options['on_stats']) ? \YoastSEO_Vendor\GuzzleHttp\Utils::currentTime() : null;
try {
// Does not support the expect header.
$request = $request->withoutHeader('Expect');
// Append a content-length header if body size is zero to match
// cURL's behavior.
if (0 === $request->getBody()->getSize()) {
// the behavior of `CurlHandler`
if ((0 === \strcasecmp('PUT', $request->getMethod()) || 0 === \strcasecmp('POST', $request->getMethod())) && 0 === $request->getBody()->getSize()) {
$request = $request->withHeader('Content-Length', '0');
}
return $this->createResponse($request, $options, $this->createStream($request, $options), $startTime);
@@ -62,7 +66,7 @@ class StreamHandler
return \YoastSEO_Vendor\GuzzleHttp\Promise\Create::rejectionFor($e);
}
}
private function invokeStats(array $options, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?float $startTime, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $error = null) : void
private function invokeStats(array $options, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?float $startTime, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $error = null) : void
{
if (isset($options['on_stats'])) {
$stats = new \YoastSEO_Vendor\GuzzleHttp\TransferStats($request, $response, \YoastSEO_Vendor\GuzzleHttp\Utils::currentTime() - $startTime, $error, []);
@@ -210,7 +214,7 @@ class StreamHandler
}
// HTTP/1.1 streams using the PHP stream wrapper require a
// Connection: close header
if ($request->getProtocolVersion() == '1.1' && !$request->hasHeader('Connection')) {
if ($request->getProtocolVersion() === '1.1' && !$request->hasHeader('Connection')) {
$request = $request->withHeader('Connection', 'close');
}
// Ensure SSL is verified by default
@@ -244,8 +248,13 @@ class StreamHandler
$contextResource = $this->createResource(static function () use($context, $params) {
return \stream_context_create($context, $params);
});
return $this->createResource(function () use($uri, &$http_response_header, $contextResource, $context, $options, $request) {
return $this->createResource(function () use($uri, $contextResource, $context, $options, $request) {
$resource = @\fopen((string) $uri, 'r', \false, $contextResource);
// See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable
if (\function_exists('YoastSEO_Vendor\\http_get_last_response_headers')) {
/** @var array|null */
$http_response_header = \YoastSEO_Vendor\http_get_last_response_headers();
}
$this->lastHeaders = $http_response_header ?? [];
if (\false === $resource) {
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException(\sprintf('Connection refused for URI %s', $uri), $request, null, $context);
@@ -40,7 +40,7 @@ class HandlerStack
* handler is provided, the best handler for your
* system will be utilized.
*/
public static function create(callable $handler = null) : self
public static function create(?callable $handler = null) : self
{
$stack = new self($handler ?: \YoastSEO_Vendor\GuzzleHttp\Utils::chooseHandler());
$stack->push(\YoastSEO_Vendor\GuzzleHttp\Middleware::httpErrors(), 'http_errors');
@@ -52,7 +52,7 @@ class HandlerStack
/**
* @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler.
*/
public function __construct(callable $handler = null)
public function __construct(?callable $handler = null)
{
$this->handler = $handler;
}
@@ -115,7 +115,7 @@ class HandlerStack
* @param callable(callable): callable $middleware Middleware function
* @param string $name Name to register for this middleware.
*/
public function unshift(callable $middleware, string $name = null) : void
public function unshift(callable $middleware, ?string $name = null) : void
{
\array_unshift($this->stack, [$middleware, $name]);
$this->cached = null;
@@ -64,7 +64,7 @@ class MessageFormatter implements \YoastSEO_Vendor\GuzzleHttp\MessageFormatterIn
* @param ResponseInterface|null $response Response that was received
* @param \Throwable|null $error Exception that was received
*/
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $error = null) : string
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $error = null) : string
{
$cache = [];
/** @var string */
@@ -13,5 +13,5 @@ interface MessageFormatterInterface
* @param ResponseInterface|null $response Response that was received
* @param \Throwable|null $error Exception that was received
*/
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $error = null) : string;
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $error = null) : string;
}
@@ -48,7 +48,7 @@ final class Middleware
*
* @return callable(callable): callable Returns a function that accepts the next handler.
*/
public static function httpErrors(\YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : callable
public static function httpErrors(?\YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : callable
{
return static function (callable $handler) use($bodySummarizer) : callable {
return static function ($request, array $options) use($handler, $bodySummarizer) {
@@ -104,7 +104,7 @@ final class Middleware
*
* @return callable Returns a function that accepts the next handler.
*/
public static function tap(callable $before = null, callable $after = null) : callable
public static function tap(?callable $before = null, ?callable $after = null) : callable
{
return static function (callable $handler) use($before, $after) : callable {
return static function (\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options) use($handler, $before, $after) {
@@ -145,7 +145,7 @@ final class Middleware
*
* @return callable Returns a function that accepts the next handler.
*/
public static function retry(callable $decider, callable $delay = null) : callable
public static function retry(callable $decider, ?callable $delay = null) : callable
{
return static function (callable $handler) use($decider, $delay) : RetryMiddleware {
return new \YoastSEO_Vendor\GuzzleHttp\RetryMiddleware($decider, $handler, $delay);
@@ -155,12 +155,12 @@ final class Middleware
* Middleware that logs requests, responses, and errors using a message
* formatter.
*
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
*
* @param LoggerInterface $logger Logs messages.
* @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings.
* @param string $logLevel Level at which to log requests.
*
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
*
* @return callable Returns a function that accepts the next handler.
*/
public static function log(\YoastSEO_Vendor\Psr\Log\LoggerInterface $logger, $formatter, string $logLevel = 'info') : callable
@@ -79,7 +79,7 @@ class Pool implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromisorInterface
* @param ClientInterface $client Client used to send the requests
* @param array|\Iterator $requests Requests to send concurrently.
* @param array $options Passes through the options available in
* {@see \GuzzleHttp\Pool::__construct}
* {@see Pool::__construct}
*
* @return array Returns an array containing the response or an exception
* in the same order that the requests were sent.
@@ -62,8 +62,8 @@ class PrepareBodyMiddleware
return;
}
$expect = $options['expect'] ?? null;
// Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0
if ($expect === \false || $request->getProtocolVersion() < 1.1) {
// Return if disabled or using HTTP/1.0
if ($expect === \false || $request->getProtocolVersion() === '1.0') {
return;
}
// The expect header is unconditionally enabled
@@ -57,7 +57,7 @@ final class RequestOptions
* Specifies whether or not cookies are used in a request or what cookie
* jar to use or what cookies to send. This option only works if your
* handler has the `cookie` middleware. Valid values are `false` and
* an instance of {@see \GuzzleHttp\Cookie\CookieJarInterface}.
* an instance of {@see Cookie\CookieJarInterface}.
*/
public const COOKIES = 'cookies';
/**
@@ -36,7 +36,7 @@ class RetryMiddleware
* and returns the number of
* milliseconds to delay.
*/
public function __construct(callable $decider, callable $nextHandler, callable $delay = null)
public function __construct(callable $decider, callable $nextHandler, ?callable $delay = null)
{
$this->decider = $decider;
$this->nextHandler = $nextHandler;
@@ -83,7 +83,7 @@ class RetryMiddleware
return $this->doRetry($req, $options);
};
}
private function doRetry(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
private function doRetry(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
$options['delay'] = ($this->delay)(++$options['retries'], $response, $request);
return $this($request, $options);
@@ -38,7 +38,7 @@ final class TransferStats
* @param mixed $handlerErrorData Handler error data.
* @param array $handlerStats Handler specific stats.
*/
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, float $transferTime = null, $handlerErrorData = null, array $handlerStats = [])
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?float $transferTime = null, $handlerErrorData = null, array $handlerStats = [])
{
$this->request = $request;
$this->response = $response;
@@ -71,14 +71,14 @@ final class Utils
*
* The returned handler is not wrapped by any default middlewares.
*
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
*
* @throws \RuntimeException if no viable Handler is available.
*/
public static function chooseHandler() : callable
{
$handler = null;
if (\defined('CURLOPT_CUSTOMREQUEST')) {
if (\defined('CURLOPT_CUSTOMREQUEST') && \function_exists('curl_version') && \version_compare(\curl_version()['version'], '7.21.2') >= 0) {
if (\function_exists('curl_multi_exec') && \function_exists('curl_exec')) {
$handler = \YoastSEO_Vendor\GuzzleHttp\Handler\Proxy::wrapSync(new \YoastSEO_Vendor\GuzzleHttp\Handler\CurlMultiHandler(), new \YoastSEO_Vendor\GuzzleHttp\Handler\CurlHandler());
} elseif (\function_exists('curl_exec')) {
@@ -47,7 +47,7 @@ function debug_resource($value = null)
*
* The returned handler is not wrapped by any default middlewares.
*
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
*
* @throws \RuntimeException if no viable Handler is available.
*
@@ -76,7 +76,7 @@ final class Coroutine implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInte
{
return new self($generatorFn);
}
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
return $this->result->then($onFulfilled, $onRejected);
}
@@ -20,7 +20,7 @@ final class Each
*
* @param mixed $iterable Iterator or array to iterate over.
*/
public static function of($iterable, callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
public static function of($iterable, ?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
return (new \YoastSEO_Vendor\GuzzleHttp\Promise\EachPromise($iterable, ['fulfilled' => $onFulfilled, 'rejected' => $onRejected]))->promise();
}
@@ -35,7 +35,7 @@ final class Each
* @param mixed $iterable
* @param int|callable $concurrency
*/
public static function ofLimit($iterable, $concurrency, callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
public static function ofLimit($iterable, $concurrency, ?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
return (new \YoastSEO_Vendor\GuzzleHttp\Promise\EachPromise($iterable, ['fulfilled' => $onFulfilled, 'rejected' => $onRejected, 'concurrency' => $concurrency]))->promise();
}
@@ -47,7 +47,7 @@ final class Each
* @param mixed $iterable
* @param int|callable $concurrency
*/
public static function ofLimitAll($iterable, $concurrency, callable $onFulfilled = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
public static function ofLimitAll($iterable, $concurrency, ?callable $onFulfilled = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
return self::ofLimit($iterable, $concurrency, $onFulfilled, function ($reason, $idx, \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface $aggregate) : void {
$aggregate->reject($reason);
@@ -24,7 +24,7 @@ class FulfilledPromise implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInt
}
$this->value = $value;
}
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
// Return itself if there is no onFulfilled function.
if (!$onFulfilled) {
@@ -22,12 +22,12 @@ class Promise implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
* @param callable $waitFn Fn that when invoked resolves the promise.
* @param callable $cancelFn Fn that when invoked cancels the promise.
*/
public function __construct(callable $waitFn = null, callable $cancelFn = null)
public function __construct(?callable $waitFn = null, ?callable $cancelFn = null)
{
$this->waitFn = $waitFn;
$this->cancelFn = $cancelFn;
}
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
if ($this->state === self::PENDING) {
$p = new \YoastSEO_Vendor\GuzzleHttp\Promise\Promise(null, [$this, 'cancel']);
@@ -24,7 +24,7 @@ interface PromiseInterface
* @param callable $onFulfilled Invoked when the promise fulfills.
* @param callable $onRejected Invoked when the promise is rejected.
*/
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
/**
* Appends a rejection handler callback to the promise, and returns a new
* promise resolving to the return value of the callback if it is called,
@@ -24,7 +24,7 @@ class RejectedPromise implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInte
}
$this->reason = $reason;
}
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
{
// If there's no onRejected callback then just return self.
if (!$onRejected) {
@@ -16,7 +16,7 @@ class RejectionException extends \RuntimeException
* @param mixed $reason Rejection reason.
* @param string|null $description Optional description.
*/
public function __construct($reason, string $description = null)
public function __construct($reason, ?string $description = null)
{
$this->reason = $reason;
$message = 'The promise was rejected';
@@ -20,7 +20,7 @@ final class Utils
*
* @param TaskQueueInterface|null $assign Optionally specify a new queue instance.
*/
public static function queue(\YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface $assign = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface
public static function queue(?\YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface $assign = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface
{
static $queue;
if ($assign) {
@@ -127,7 +127,9 @@ final class Utils
$promise = \YoastSEO_Vendor\GuzzleHttp\Promise\Each::of($promises, function ($value, $idx) use(&$results) : void {
$results[$idx] = $value;
}, function ($reason, $idx, \YoastSEO_Vendor\GuzzleHttp\Promise\Promise $aggregate) : void {
$aggregate->reject($reason);
if (\YoastSEO_Vendor\GuzzleHttp\Promise\Is::pending($aggregate)) {
$aggregate->reject($reason);
}
})->then(function () use(&$results) {
\ksort($results);
return $results;
@@ -25,7 +25,7 @@ final class CachingStream implements \YoastSEO_Vendor\Psr\Http\Message\StreamInt
* @param StreamInterface $stream Stream to cache. The cursor is assumed to be at the beginning of the stream.
* @param StreamInterface $target Optionally specify where data is cached
*/
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, \YoastSEO_Vendor\Psr\Http\Message\StreamInterface $target = null)
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, ?\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $target = null)
{
$this->remoteStream = $stream;
$this->stream = $target ?: new \YoastSEO_Vendor\GuzzleHttp\Psr7\Stream(\YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'r+'));
@@ -23,7 +23,7 @@ use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
*/
final class HttpFactory implements \YoastSEO_Vendor\Psr\Http\Message\RequestFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\ResponseFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\ServerRequestFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\StreamFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\UploadedFileFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\UriFactoryInterface
{
public function createUploadedFile(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null) : \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface
public function createUploadedFile(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, ?int $size = null, int $error = \UPLOAD_ERR_OK, ?string $clientFilename = null, ?string $clientMediaType = null) : \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface
{
if ($size === null) {
$size = $stream->getSize();
@@ -138,9 +138,6 @@ trait MessageTrait
if (!\is_array($value)) {
return $this->trimAndValidateHeaderValues([$value]);
}
if (\count($value) === 0) {
throw new \InvalidArgumentException('Header value can not be an empty array.');
}
return $this->trimAndValidateHeaderValues($value);
}
/**
@@ -27,7 +27,7 @@ final class MultipartStream implements \YoastSEO_Vendor\Psr\Http\Message\StreamI
*
* @throws \InvalidArgumentException
*/
public function __construct(array $elements = [], string $boundary = null)
public function __construct(array $elements = [], ?string $boundary = null)
{
$this->boundary = $boundary ?: \bin2hex(\random_bytes(20));
$this->stream = $this->createStream($elements);
@@ -57,12 +57,15 @@ final class Query
* string. This function does not modify the provided keys when an array is
* encountered (like `http_build_query()` would).
*
* @param array $params Query string parameters.
* @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
* to encode using RFC3986, or PHP_QUERY_RFC1738
* to encode using RFC1738.
* @param array $params Query string parameters.
* @param int|false $encoding Set to false to not encode,
* PHP_QUERY_RFC3986 to encode using
* RFC3986, or PHP_QUERY_RFC1738 to
* encode using RFC1738.
* @param bool $treatBoolsAsInts Set to true to encode as 0/1, and
* false as false/true.
*/
public static function build(array $params, $encoding = \PHP_QUERY_RFC3986) : string
public static function build(array $params, $encoding = \PHP_QUERY_RFC3986, bool $treatBoolsAsInts = \true) : string
{
if (!$params) {
return '';
@@ -78,12 +81,17 @@ final class Query
} else {
throw new \InvalidArgumentException('Invalid type');
}
$castBool = $treatBoolsAsInts ? static function ($v) {
return (int) $v;
} : static function ($v) {
return $v ? 'true' : 'false';
};
$qs = '';
foreach ($params as $k => $v) {
$k = $encoder((string) $k);
if (!\is_array($v)) {
$qs .= $k;
$v = \is_bool($v) ? (int) $v : $v;
$v = \is_bool($v) ? $castBool($v) : $v;
if ($v !== null) {
$qs .= '=' . $encoder((string) $v);
}
@@ -91,7 +99,7 @@ final class Query
} else {
foreach ($v as $vv) {
$qs .= $k;
$vv = \is_bool($vv) ? (int) $vv : $vv;
$vv = \is_bool($vv) ? $castBool($vv) : $vv;
if ($vv !== null) {
$qs .= '=' . $encoder((string) $vv);
}
@@ -24,7 +24,7 @@ class Response implements \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface
* @param string $version Protocol version
* @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
*/
public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', string $reason = null)
public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', ?string $reason = null)
{
$this->assertStatusCodeRange($status);
$this->statusCode = $status;
@@ -56,7 +56,7 @@ final class StreamWrapper
\stream_wrapper_register('guzzle', __CLASS__);
}
}
public function stream_open(string $path, string $mode, int $options, string &$opened_path = null) : bool
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path = null) : bool
{
$options = \stream_context_get_options($this->context);
if (!isset($options['guzzle']['stream'])) {
@@ -111,10 +111,13 @@ final class StreamWrapper
* ctime: int,
* blksize: int,
* blocks: int
* }
* }|false
*/
public function stream_stat() : array
public function stream_stat()
{
if ($this->stream->getSize() === null) {
return \false;
}
static $modeMap = ['r' => 33060, 'rb' => 33060, 'r+' => 33206, 'w' => 33188, 'wb' => 33188];
return ['dev' => 0, 'ino' => 0, 'mode' => $modeMap[$this->mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->stream->getSize() ?: 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0];
}
@@ -9,7 +9,7 @@ use YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface;
use RuntimeException;
class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface
{
private const ERRORS = [\UPLOAD_ERR_OK, \UPLOAD_ERR_INI_SIZE, \UPLOAD_ERR_FORM_SIZE, \UPLOAD_ERR_PARTIAL, \UPLOAD_ERR_NO_FILE, \UPLOAD_ERR_NO_TMP_DIR, \UPLOAD_ERR_CANT_WRITE, \UPLOAD_ERR_EXTENSION];
private const ERROR_MAP = [\UPLOAD_ERR_OK => 'UPLOAD_ERR_OK', \UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE', \UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE', \UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL', \UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE', \UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR', \UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE', \UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION'];
/**
* @var string|null
*/
@@ -41,7 +41,7 @@ class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInte
/**
* @param StreamInterface|string|resource $streamOrFile
*/
public function __construct($streamOrFile, ?int $size, int $errorStatus, string $clientFilename = null, string $clientMediaType = null)
public function __construct($streamOrFile, ?int $size, int $errorStatus, ?string $clientFilename = null, ?string $clientMediaType = null)
{
$this->setError($errorStatus);
$this->size = $size;
@@ -75,7 +75,7 @@ class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInte
*/
private function setError(int $error) : void
{
if (\false === \in_array($error, \YoastSEO_Vendor\GuzzleHttp\Psr7\UploadedFile::ERRORS, \true)) {
if (!isset(\YoastSEO_Vendor\GuzzleHttp\Psr7\UploadedFile::ERROR_MAP[$error])) {
throw new \InvalidArgumentException('Invalid error status for UploadedFile');
}
$this->error = $error;
@@ -101,7 +101,7 @@ class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInte
private function validateActive() : void
{
if (\false === $this->isOk()) {
throw new \RuntimeException('Cannot retrieve stream due to upload error');
throw new \RuntimeException(\sprintf('Cannot retrieve stream due to upload error (%s)', self::ERROR_MAP[$this->error]));
}
if ($this->isMoved()) {
throw new \RuntimeException('Cannot retrieve stream after it has already been moved');
@@ -80,7 +80,7 @@ class Uri implements \YoastSEO_Vendor\Psr\Http\Message\UriInterface, \JsonSerial
{
// If IPv6
$prefix = '';
if (\preg_match('%^(.*://\\[[0-9:a-f]+\\])(.*?)$%', $url, $matches)) {
if (\preg_match('%^(.*://\\[[0-9:a-fA-F]+\\])(.*?)$%', $url, $matches)) {
/** @var array{0:string, 1:string, 2:string} $matches */
$prefix = $matches[1];
$url = $matches[2];
@@ -216,7 +216,7 @@ class Uri implements \YoastSEO_Vendor\Psr\Http\Message\UriInterface, \JsonSerial
*
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4
*/
public static function isSameDocumentReference(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri, \YoastSEO_Vendor\Psr\Http\Message\UriInterface $base = null) : bool
public static function isSameDocumentReference(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri, ?\YoastSEO_Vendor\Psr\Http\Message\UriInterface $base = null) : bool
{
if ($base !== null) {
$uri = \YoastSEO_Vendor\GuzzleHttp\Psr7\UriResolver::resolve($base, $uri);
@@ -185,7 +185,7 @@ final class Utils
* @param StreamInterface $stream Stream to read from
* @param int|null $maxLength Maximum buffer length
*/
public static function readLine(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, int $maxLength = null) : string
public static function readLine(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, ?int $maxLength = null) : string
{
$buffer = '';
$size = 0;
@@ -201,6 +201,17 @@ final class Utils
}
return $buffer;
}
/**
* Redact the password in the user info part of a URI.
*/
public static function redactUserInfo(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri) : \YoastSEO_Vendor\Psr\Http\Message\UriInterface
{
$userInfo = $uri->getUserInfo();
if (\false !== ($pos = \strpos($userInfo, ':'))) {
return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
}
return $uri;
}
/**
* Create a new stream based on the input type.
*
@@ -312,7 +323,7 @@ final class Utils
}
\restore_error_handler();
if ($ex) {
/** @var $ex \RuntimeException */
/** @var \RuntimeException $ex */
throw $ex;
}
return $handle;
@@ -346,7 +357,7 @@ final class Utils
}
\restore_error_handler();
if ($ex) {
/** @var $ex \RuntimeException */
/** @var \RuntimeException $ex */
throw $ex;
}
return $contents;
@@ -17,6 +17,7 @@ namespace YoastSEO_Vendor\League\OAuth2\Client\Provider;
use YoastSEO_Vendor\GuzzleHttp\Client as HttpClient;
use YoastSEO_Vendor\GuzzleHttp\ClientInterface as HttpClientInterface;
use YoastSEO_Vendor\GuzzleHttp\Exception\BadResponseException;
use YoastSEO_Vendor\GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use YoastSEO_Vendor\League\OAuth2\Client\Grant\AbstractGrant;
use YoastSEO_Vendor\League\OAuth2\Client\Grant\GrantFactory;
@@ -347,6 +348,7 @@ abstract class AbstractProvider
*
* @param array $options
* @return array Authorization parameters
* @throws InvalidArgumentException
*/
protected function getAuthorizationParameters(array $options)
{
@@ -398,6 +400,7 @@ abstract class AbstractProvider
*
* @param array $options
* @return string Authorization URL
* @throws InvalidArgumentException
*/
public function getAuthorizationUrl(array $options = [])
{
@@ -412,8 +415,9 @@ abstract class AbstractProvider
* @param array $options
* @param callable|null $redirectHandler
* @return mixed
* @throws InvalidArgumentException
*/
public function authorize(array $options = [], callable $redirectHandler = null)
public function authorize(array $options = [], ?callable $redirectHandler = null)
{
$url = $this->getAuthorizationUrl($options);
if ($redirectHandler) {
@@ -516,12 +520,18 @@ abstract class AbstractProvider
*
* @param mixed $grant
* @param array<string, mixed> $options
* @throws IdentityProviderException
* @return AccessTokenInterface
* @throws IdentityProviderException
* @throws UnexpectedValueException
* @throws GuzzleException
*/
public function getAccessToken($grant, array $options = [])
{
$grant = $this->verifyGrant($grant);
if (isset($options['scope']) && \is_array($options['scope'])) {
$separator = $this->getScopeSeparator();
$options['scope'] = \implode($separator, $options['scope']);
}
$params = ['client_id' => $this->clientId, 'client_secret' => $this->clientSecret, 'redirect_uri' => $this->redirectUri];
if (!empty($this->pkceCode)) {
$params['code_verifier'] = $this->pkceCode;
@@ -585,6 +595,7 @@ abstract class AbstractProvider
*
* @param RequestInterface $request
* @return ResponseInterface
* @throws GuzzleException
*/
public function getResponse(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request)
{
@@ -594,8 +605,10 @@ abstract class AbstractProvider
* Sends a request and returns the parsed response.
*
* @param RequestInterface $request
* @throws IdentityProviderException
* @return mixed
* @throws IdentityProviderException
* @throws UnexpectedValueException
* @throws GuzzleException
*/
public function getParsedResponse(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request)
{
@@ -631,7 +644,7 @@ abstract class AbstractProvider
*/
protected function getContentType(\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response)
{
return \join(';', (array) $response->getHeader('content-type'));
return \implode(';', $response->getHeader('content-type'));
}
/**
* Parses the response according to its content-type header.
@@ -678,7 +691,7 @@ abstract class AbstractProvider
* Custom mapping of expiration, etc should be done here. Always call the
* parent method when overloading this method.
*
* @param mixed $result
* @param array<string, mixed> $result
* @return array
*/
protected function prepareAccessTokenResponse(array $result)
@@ -716,6 +729,9 @@ abstract class AbstractProvider
*
* @param AccessToken $token
* @return ResourceOwnerInterface
* @throws IdentityProviderException
* @throws UnexpectedValueException
* @throws GuzzleException
*/
public function getResourceOwner(\YoastSEO_Vendor\League\OAuth2\Client\Token\AccessToken $token)
{
@@ -727,6 +743,9 @@ abstract class AbstractProvider
*
* @param AccessToken $token
* @return mixed
* @throws IdentityProviderException
* @throws UnexpectedValueException
* @throws GuzzleException
*/
protected function fetchResourceOwnerDetails(\YoastSEO_Vendor\League\OAuth2\Client\Token\AccessToken $token)
{
@@ -21,7 +21,7 @@ use RuntimeException;
*
* @link http://tools.ietf.org/html/rfc6749#section-1.4 Access Token (RFC 6749, §1.4)
*/
class AccessToken implements \YoastSEO_Vendor\League\OAuth2\Client\Token\AccessTokenInterface, \YoastSEO_Vendor\League\OAuth2\Client\Token\ResourceOwnerAccessTokenInterface
class AccessToken implements \YoastSEO_Vendor\League\OAuth2\Client\Token\AccessTokenInterface, \YoastSEO_Vendor\League\OAuth2\Client\Token\ResourceOwnerAccessTokenInterface, \YoastSEO_Vendor\League\OAuth2\Client\Token\SettableRefreshTokenInterface
{
/**
* @var string
@@ -103,7 +103,7 @@ class AccessToken implements \YoastSEO_Vendor\League\OAuth2\Client\Token\AccessT
} elseif (!empty($options['expires'])) {
// Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received.
$expires = $options['expires'];
$expires = (int) $options['expires'];
if (!$this->isExpirationTimestamp($expires)) {
$expires += $this->getTimeNow();
}
@@ -142,6 +142,13 @@ class AccessToken implements \YoastSEO_Vendor\League\OAuth2\Client\Token\AccessT
{
return $this->refreshToken;
}
/**
* @inheritdoc
*/
public function setRefreshToken($refreshToken)
{
$this->refreshToken = $refreshToken;
}
/**
* @inheritdoc
*/
@@ -165,7 +172,7 @@ class AccessToken implements \YoastSEO_Vendor\League\OAuth2\Client\Token\AccessT
if (empty($expires)) {
throw new \RuntimeException('"expires" is not set on the token');
}
return $expires < \time();
return $expires < $this->getTimeNow();
}
/**
* @inheritdoc
@@ -0,0 +1,26 @@
<?php
/**
* This file is part of the league/oauth2-client library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Alex Bilbie <hello@alexbilbie.com>
* @license http://opensource.org/licenses/MIT MIT
* @link http://thephpleague.com/oauth2-client/ Documentation
* @link https://packagist.org/packages/league/oauth2-client Packagist
* @link https://github.com/thephpleague/oauth2-client GitHub
*/
namespace YoastSEO_Vendor\League\OAuth2\Client\Token;
interface SettableRefreshTokenInterface
{
/**
* Sets or replaces the refresh token with the provided refresh token.
*
* @param string $refreshToken
* @return void
*/
public function setRefreshToken($refreshToken);
}
@@ -1,8 +1,5 @@
<?php
/**
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace YoastSEO_Vendor\Psr\Container;
/**
@@ -1,8 +1,6 @@
<?php
/**
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
declare (strict_types=1);
namespace YoastSEO_Vendor\Psr\Container;
/**
@@ -20,7 +18,7 @@ interface ContainerInterface
*
* @return mixed Entry.
*/
public function get($id);
public function get(string $id);
/**
* Returns true if the container can return an entry for the given identifier.
* Returns false otherwise.
@@ -32,5 +30,5 @@ interface ContainerInterface
*
* @return bool
*/
public function has($id);
public function has(string $id);
}
@@ -1,8 +1,5 @@
<?php
/**
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace YoastSEO_Vendor\Psr\Container;
/**
@@ -15,14 +15,14 @@ interface UploadedFileFactoryInterface
*
* @param StreamInterface $stream Underlying stream representing the
* uploaded file content.
* @param int $size in bytes
* @param int|null $size in bytes
* @param int $error PHP file upload error
* @param string $clientFilename Filename as provided by the client, if any.
* @param string $clientMediaType Media type as provided by the client, if any.
* @param string|null $clientFilename Filename as provided by the client, if any.
* @param string|null $clientMediaType Media type as provided by the client, if any.
*
* @return UploadedFileInterface
*
* @throws \InvalidArgumentException If the file resource is not readable.
*/
public function createUploadedFile(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null) : \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface;
public function createUploadedFile(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, ?int $size = null, int $error = \UPLOAD_ERR_OK, ?string $clientFilename = null, ?string $clientMediaType = null) : \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface;
}
@@ -25,12 +25,12 @@ class RewindableGenerator implements \IteratorAggregate, \Countable
$this->generator = $generator;
$this->count = $count;
}
public function getIterator()
public function getIterator() : \Traversable
{
$g = $this->generator;
return $g();
}
public function count()
public function count() : int
{
if (\is_callable($count = $this->count)) {
$this->count = $count();
@@ -0,0 +1,49 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class ServiceLocator extends \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ServiceLocator
{
private $factory;
private $serviceMap;
private $serviceTypes;
public function __construct(\Closure $factory, array $serviceMap, ?array $serviceTypes = null)
{
$this->factory = $factory;
$this->serviceMap = $serviceMap;
$this->serviceTypes = $serviceTypes;
parent::__construct($serviceMap);
}
/**
* {@inheritdoc}
*
* @return mixed
*/
public function get(string $id)
{
return isset($this->serviceMap[$id]) ? ($this->factory)(...$this->serviceMap[$id]) : parent::get($id);
}
/**
* {@inheritdoc}
*/
public function getProvidedServices() : array
{
return $this->serviceTypes ?? ($this->serviceTypes = \array_map(function () {
return '?';
}, $this->serviceMap));
}
}
@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Reference;
/**
* Represents a closure acting as a service locator.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class ServiceLocatorArgument implements \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\ArgumentInterface
{
use ReferenceSetArgumentTrait;
private $taggedIteratorArgument;
/**
* @param Reference[]|TaggedIteratorArgument $values
*/
public function __construct($values = [])
{
if ($values instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument) {
$this->taggedIteratorArgument = $values;
$this->values = [];
} else {
$this->setValues($values);
}
}
public function getTaggedIteratorArgument() : ?\YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument
{
return $this->taggedIteratorArgument;
}
}
@@ -10,14 +10,21 @@
*/
namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use YoastSEO_Vendor\Symfony\Contracts\Service\ResetInterface;
// Help opcache.preload discover always-needed symbols
\class_exists(\YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\RewindableGenerator::class);
\class_exists(\YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\ServiceLocator::class);
/**
* Container is a dependency injection container.
*
@@ -26,40 +33,34 @@ use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\Parameter
* The container can have four possible behaviors when a service
* does not exist (or is not initialized for the last case):
*
* * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default)
* * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception at compilation time (the default)
* * NULL_ON_INVALID_REFERENCE: Returns null
* * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference
* (for instance, ignore a setter if the service does not exist)
* * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references
* * RUNTIME_EXCEPTION_ON_INVALID_REFERENCE: Throws an exception at runtime
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ResettableContainerInterface
class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerInterface, \YoastSEO_Vendor\Symfony\Contracts\Service\ResetInterface
{
protected $parameterBag;
protected $services = [];
protected $privates = [];
protected $fileMap = [];
protected $methodMap = [];
protected $factories = [];
protected $aliases = [];
protected $loading = [];
protected $resolving = [];
protected $syntheticIds = [];
/**
* @internal
*/
protected $privates = [];
/**
* @internal
*/
protected $normalizedIds = [];
private $underscoreMap = ['_' => '', '.' => '_', '\\' => '_'];
private $envCache = [];
private $compiled = \false;
private $getEnv;
public function __construct(\YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface $parameterBag = null)
public function __construct(?\YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface $parameterBag = null)
{
$this->parameterBag = $parameterBag ?: new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag();
$this->parameterBag = $parameterBag ?? new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag();
}
/**
* Compiles the container.
@@ -84,22 +85,10 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
{
return $this->compiled;
}
/**
* Returns true if the container parameter bag are frozen.
*
* @deprecated since version 3.3, to be removed in 4.0.
*
* @return bool true if the container parameter bag are frozen, false otherwise
*/
public function isFrozen()
{
@\trigger_error(\sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), \E_USER_DEPRECATED);
return $this->parameterBag instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
}
/**
* Gets the service container parameter bag.
*
* @return ParameterBagInterface A ParameterBagInterface instance
* @return ParameterBagInterface
*/
public function getParameterBag()
{
@@ -108,34 +97,28 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
/**
* Gets a parameter.
*
* @param string $name The parameter name
*
* @return mixed The parameter value
* @return array|bool|string|int|float|\UnitEnum|null
*
* @throws InvalidArgumentException if the parameter is not defined
*/
public function getParameter($name)
public function getParameter(string $name)
{
return $this->parameterBag->get($name);
}
/**
* Checks if a parameter exists.
*
* @param string $name The parameter name
*
* @return bool The presence of parameter in container
* @return bool
*/
public function hasParameter($name)
public function hasParameter(string $name)
{
return $this->parameterBag->has($name);
}
/**
* Sets a parameter.
*
* @param string $name The parameter name
* @param mixed $value The parameter value
* @param string $name The parameter name
* @param array|bool|string|int|float|\UnitEnum|null $value The parameter value
*/
public function setParameter($name, $value)
public function setParameter(string $name, $value)
{
$this->parameterBag->set($name, $value);
}
@@ -144,11 +127,8 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
*
* Setting a synthetic service to null resets it: has() returns false and get()
* behaves in the same way as if the service was never created.
*
* @param string $id The service identifier
* @param object|null $service The service instance
*/
public function set($id, $service)
public function set(string $id, ?object $service)
{
// Runs the internal initializer; used by the dumped container to include always-needed files
if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) {
@@ -156,25 +136,19 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
unset($this->privates['service_container']);
$initialize();
}
$id = $this->normalizeId($id);
if ('service_container' === $id) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException('You cannot set service "service_container".');
}
if (isset($this->privates[$id]) || !(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) {
if (!isset($this->privates[$id]) && !isset($this->getRemovedIds()[$id])) {
if (!(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) {
if (isset($this->syntheticIds[$id]) || !isset($this->getRemovedIds()[$id])) {
// no-op
} elseif (null === $service) {
@\trigger_error(\sprintf('The "%s" service is private, unsetting it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED);
unset($this->privates[$id]);
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('The "%s" service is private, you cannot unset it.', $id));
} else {
@\trigger_error(\sprintf('The "%s" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED);
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('The "%s" service is private, you cannot replace it.', $id));
}
} elseif (isset($this->services[$id])) {
if (null === $service) {
@\trigger_error(\sprintf('The "%s" service is already initialized, unsetting it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), \E_USER_DEPRECATED);
} else {
@\trigger_error(\sprintf('The "%s" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), \E_USER_DEPRECATED);
}
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('The "%s" service is already initialized, you cannot replace it.', $id));
}
if (isset($this->aliases[$id])) {
unset($this->aliases[$id]);
@@ -190,49 +164,25 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
*
* @param string $id The service identifier
*
* @return bool true if the service is defined, false otherwise
* @return bool
*/
public function has($id)
public function has(string $id)
{
for ($i = 2;;) {
if (isset($this->privates[$id])) {
@\trigger_error(\sprintf('The "%s" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED);
}
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}
if (isset($this->services[$id])) {
return \true;
}
if ('service_container' === $id) {
return \true;
}
if (isset($this->fileMap[$id]) || isset($this->methodMap[$id])) {
return \true;
}
if (--$i && $id !== ($normalizedId = $this->normalizeId($id))) {
$id = $normalizedId;
continue;
}
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
// and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
if (!$this->methodMap && !$this instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerBuilder && __CLASS__ !== static::class && \method_exists($this, 'get' . \strtr($id, $this->underscoreMap) . 'Service')) {
@\trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED);
return \true;
}
return \false;
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}
if (isset($this->services[$id])) {
return \true;
}
if ('service_container' === $id) {
return \true;
}
return isset($this->fileMap[$id]) || isset($this->methodMap[$id]);
}
/**
* Gets a service.
*
* If a service is defined both through a set() method and
* with a get{$id}Service() method, the former has always precedence.
*
* @param string $id The service identifier
* @param int $invalidBehavior The behavior when the service does not exist
*
* @return object|null The associated service
* @return object|null
*
* @throws ServiceCircularReferenceException When a circular reference is detected
* @throws ServiceNotFoundException When the service is not defined
@@ -240,52 +190,32 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
*
* @see Reference
*/
public function get($id, $invalidBehavior = 1)
public function get(string $id, int $invalidBehavior = 1)
{
// Attempt to retrieve the service by checking first aliases then
// available services. Service IDs are case insensitive, however since
// this method can be called thousands of times during a request, avoid
// calling $this->normalizeId($id) unless necessary.
for ($i = 2;;) {
if (isset($this->privates[$id])) {
@\trigger_error(\sprintf('The "%s" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.', $id), \E_USER_DEPRECATED);
}
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}
// Re-use shared service instance if it exists.
if (isset($this->services[$id])) {
return $this->services[$id];
}
if ('service_container' === $id) {
return $this;
}
if (isset($this->loading[$id])) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException($id, \array_merge(\array_keys($this->loading), [$id]));
}
$this->loading[$id] = \true;
try {
if (isset($this->fileMap[$id])) {
return 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]);
} elseif (isset($this->methodMap[$id])) {
return 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}();
} elseif (--$i && $id !== ($normalizedId = $this->normalizeId($id))) {
unset($this->loading[$id]);
$id = $normalizedId;
continue;
} elseif (!$this->methodMap && !$this instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerBuilder && __CLASS__ !== static::class && \method_exists($this, $method = 'get' . \strtr($id, $this->underscoreMap) . 'Service')) {
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
// and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
@\trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED);
return 4 === $invalidBehavior ? null : $this->{$method}();
}
break;
} catch (\Exception $e) {
unset($this->services[$id]);
throw $e;
} finally {
unset($this->loading[$id]);
return $this->services[$id] ?? $this->services[$id = $this->aliases[$id] ?? $id] ?? ('service_container' === $id ? $this : ($this->factories[$id] ?? [$this, 'make'])($id, $invalidBehavior));
}
/**
* Creates a service.
*
* As a separate method to allow "get()" to use the really fast `??` operator.
*/
private function make(string $id, int $invalidBehavior)
{
if (isset($this->loading[$id])) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException($id, \array_merge(\array_keys($this->loading), [$id]));
}
$this->loading[$id] = \true;
try {
if (isset($this->fileMap[$id])) {
return 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]);
} elseif (isset($this->methodMap[$id])) {
return 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}();
}
} catch (\Exception $e) {
unset($this->services[$id]);
throw $e;
} finally {
unset($this->loading[$id]);
}
if (1 === $invalidBehavior) {
if (!$id) {
@@ -299,27 +229,25 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
}
$alternatives = [];
foreach ($this->getServiceIds() as $knownId) {
if ('' === $knownId || '.' === $knownId[0]) {
continue;
}
$lev = \levenshtein($id, $knownId);
if ($lev <= \strlen($id) / 3 || \false !== \strpos($knownId, $id)) {
if ($lev <= \strlen($id) / 3 || \str_contains($knownId, $id)) {
$alternatives[] = $knownId;
}
}
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException($id, null, null, $alternatives);
}
return null;
}
/**
* Returns true if the given service has actually been initialized.
*
* @param string $id The service identifier
*
* @return bool true if service has already been initialized, false otherwise
* @return bool
*/
public function initialized($id)
public function initialized(string $id)
{
$id = $this->normalizeId($id);
if (isset($this->privates[$id])) {
@\trigger_error(\sprintf('Checking for the initialization of the "%s" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0.', $id), \E_USER_DEPRECATED);
}
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}
@@ -333,28 +261,26 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
*/
public function reset()
{
$this->services = [];
$services = $this->services + $this->privates;
foreach ($services as $service) {
try {
if ($service instanceof \YoastSEO_Vendor\Symfony\Contracts\Service\ResetInterface) {
$service->reset();
}
} catch (\Throwable $e) {
continue;
}
}
$this->services = $this->factories = $this->privates = [];
}
/**
* Gets all service ids.
*
* @return string[] An array of all defined service ids
* @return string[]
*/
public function getServiceIds()
{
$ids = [];
if (!$this->methodMap && !$this instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerBuilder && __CLASS__ !== static::class) {
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
// and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
@\trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED);
foreach (\get_class_methods($this) as $method) {
if (\preg_match('/^get(.+)Service$/', $method, $match)) {
$ids[] = self::underscore($match[1]);
}
}
}
$ids[] = 'service_container';
return \array_map('strval', \array_unique(\array_merge($ids, \array_keys($this->methodMap), \array_keys($this->fileMap), \array_keys($this->aliases), \array_keys($this->services))));
return \array_map('strval', \array_unique(\array_merge(['service_container'], \array_keys($this->fileMap), \array_keys($this->methodMap), \array_keys($this->aliases), \array_keys($this->services))));
}
/**
* Gets service ids that existed at compile time.
@@ -368,42 +294,36 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
/**
* Camelizes a string.
*
* @param string $id A string to camelize
*
* @return string The camelized string
* @return string
*/
public static function camelize($id)
public static function camelize(string $id)
{
return \strtr(\ucwords(\strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']);
}
/**
* A string to underscore.
*
* @param string $id The string to underscore
*
* @return string The underscored string
* @return string
*/
public static function underscore($id)
public static function underscore(string $id)
{
return \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], \str_replace('_', '.', $id)));
}
/**
* Creates a service by requiring its factory file.
*/
protected function load($file)
protected function load(string $file)
{
return require $file;
}
/**
* Fetches a variable from the environment.
*
* @param string $name The name of the environment variable
*
* @return mixed The value to use for the provided environment variable name
* @return mixed
*
* @throws EnvNotFoundException When the environment variable is not found and has no default value
*/
protected function getEnv($name)
protected function getEnv(string $name)
{
if (isset($this->resolving[$envName = "env({$name})"])) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException(\array_keys($this->resolving));
@@ -415,9 +335,7 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
$this->set($id, new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ServiceLocator([]));
}
if (!$this->getEnv) {
$this->getEnv = new \ReflectionMethod($this, __FUNCTION__);
$this->getEnv->setAccessible(\true);
$this->getEnv = $this->getEnv->getClosure($this);
$this->getEnv = \Closure::fromCallable([$this, 'getEnv']);
}
$processors = $this->get($id);
if (\false !== ($i = \strpos($name, ':'))) {
@@ -428,6 +346,9 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
$localName = $name;
}
$processor = $processors->has($prefix) ? $processors->get($prefix) : new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\EnvVarProcessor($this);
if (\false === $i) {
$prefix = '';
}
$this->resolving[$envName] = \true;
try {
return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv);
@@ -436,28 +357,31 @@ class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjectio
}
}
/**
* Returns the case sensitive id used at registration time.
* @param string|false $registry
* @param string|bool $load
*
* @param string $id
*
* @return string
* @return mixed
*
* @internal
*/
public function normalizeId($id)
protected final function getService($registry, string $id, ?string $method, $load)
{
if (!\is_string($id)) {
$id = (string) $id;
if ('service_container' === $id) {
return $this;
}
if (isset($this->normalizedIds[$normalizedId = \strtolower($id)])) {
$normalizedId = $this->normalizedIds[$normalizedId];
if ($id !== $normalizedId) {
@\trigger_error(\sprintf('Service identifiers will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.3.', $id, $normalizedId), \E_USER_DEPRECATED);
}
} else {
$normalizedId = $this->normalizedIds[$normalizedId] = $id;
if (\is_string($load)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException($load);
}
return $normalizedId;
if (null === $method) {
return \false !== $registry ? $this->{$registry}[$id] ?? null : null;
}
if (\false !== $registry) {
return $this->{$registry}[$id] ?? ($this->{$registry}[$id] = $load ? $this->load($method) : $this->{$method}());
}
if (!$load) {
return $this->{$method}();
}
return ($factory = $this->factories[$id] ?? $this->factories['service_container'][$id] ?? null) ? $factory() : $this->load($method);
}
private function __clone()
{
@@ -22,70 +22,54 @@ use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFo
*/
interface ContainerInterface extends \YoastSEO_Vendor\Psr\Container\ContainerInterface
{
const EXCEPTION_ON_INVALID_REFERENCE = 1;
const NULL_ON_INVALID_REFERENCE = 2;
const IGNORE_ON_INVALID_REFERENCE = 3;
const IGNORE_ON_UNINITIALIZED_REFERENCE = 4;
public const RUNTIME_EXCEPTION_ON_INVALID_REFERENCE = 0;
public const EXCEPTION_ON_INVALID_REFERENCE = 1;
public const NULL_ON_INVALID_REFERENCE = 2;
public const IGNORE_ON_INVALID_REFERENCE = 3;
public const IGNORE_ON_UNINITIALIZED_REFERENCE = 4;
/**
* Sets a service.
*
* @param string $id The service identifier
* @param object|null $service The service instance
*/
public function set($id, $service);
public function set(string $id, ?object $service);
/**
* Gets a service.
*
* @param string $id The service identifier
* @param int $invalidBehavior The behavior when the service does not exist
*
* @return object|null The associated service
* @return object|null
*
* @throws ServiceCircularReferenceException When a circular reference is detected
* @throws ServiceNotFoundException When the service is not defined
*
* @see Reference
*/
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE);
public function get(string $id, int $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE);
/**
* Returns true if the given service is defined.
*
* @param string $id The service identifier
*
* @return bool true if the service is defined, false otherwise
* @return bool
*/
public function has($id);
public function has(string $id);
/**
* Check for whether or not a service has been initialized.
*
* @param string $id
*
* @return bool true if the service has been initialized, false otherwise
* @return bool
*/
public function initialized($id);
public function initialized(string $id);
/**
* Gets a parameter.
*
* @param string $name The parameter name
*
* @return mixed The parameter value
* @return array|bool|string|int|float|\UnitEnum|null
*
* @throws InvalidArgumentException if the parameter is not defined
*/
public function getParameter($name);
public function getParameter(string $name);
/**
* Checks if a parameter exists.
*
* @param string $name The parameter name
*
* @return bool The presence of parameter in container
* @return bool
*/
public function hasParameter($name);
public function hasParameter(string $name);
/**
* Sets a parameter.
*
* @param string $name The parameter name
* @param mixed $value The parameter value
* @param string $name The parameter name
* @param array|bool|string|int|float|\UnitEnum|null $value The parameter value
*/
public function setParameter($name, $value);
public function setParameter(string $name, $value);
}
@@ -17,8 +17,4 @@ namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception;
*/
class EnvNotFoundException extends \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
{
public function __construct($name)
{
parent::__construct(\sprintf('Environment variable not found: "%s".', $name));
}
}
@@ -17,6 +17,6 @@ use YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface;
* @author Fabien Potencier <fabien@symfony.com>
* @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
*/
interface ExceptionInterface extends \YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface
interface ExceptionInterface extends \YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface, \Throwable
{
}
@@ -18,7 +18,7 @@ namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception;
class ParameterCircularReferenceException extends \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException
{
private $parameters;
public function __construct($parameters, \Exception $previous = null)
public function __construct(array $parameters, ?\Throwable $previous = null)
{
parent::__construct(\sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], \implode('" > "', $parameters), $parameters[0]), 0, $previous);
$this->parameters = $parameters;
@@ -19,7 +19,7 @@ class ServiceCircularReferenceException extends \YoastSEO_Vendor\Symfony\Compone
{
private $serviceId;
private $path;
public function __construct($serviceId, array $path, \Exception $previous = null)
public function __construct(string $serviceId, array $path, ?\Throwable $previous = null)
{
parent::__construct(\sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, \implode(' -> ', $path)), 0, $previous);
$this->serviceId = $serviceId;
@@ -21,7 +21,7 @@ class ServiceNotFoundException extends \YoastSEO_Vendor\Symfony\Component\Depend
private $id;
private $sourceId;
private $alternatives;
public function __construct($id, $sourceId = null, \Exception $previous = null, array $alternatives = [], $msg = null)
public function __construct(string $id, ?string $sourceId = null, ?\Throwable $previous = null, array $alternatives = [], ?string $msg = null)
{
if (null !== $msg) {
// no-op
@@ -17,14 +17,17 @@ use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeExcep
*/
class EnvPlaceholderParameterBag extends \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBag
{
private $envPlaceholderUniquePrefix;
private $envPlaceholders = [];
private $unusedEnvPlaceholders = [];
private $providedTypes = [];
private static $counter = 0;
/**
* {@inheritdoc}
*/
public function get($name)
public function get(string $name)
{
if (0 === \strpos($name, 'env(') && ')' === \substr($name, -1) && 'env()' !== $name) {
if (\str_starts_with($name, 'env(') && \str_ends_with($name, ')') && 'env()' !== $name) {
$env = \substr($name, 4, -1);
if (isset($this->envPlaceholders[$env])) {
foreach ($this->envPlaceholders[$env] as $placeholder) {
@@ -32,22 +35,39 @@ class EnvPlaceholderParameterBag extends \YoastSEO_Vendor\Symfony\Component\Depe
// return first result
}
}
if (!\preg_match('/^(?:\\w++:)*+\\w++$/', $env)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('Invalid "%s" name: only "word" characters are allowed.', $name));
}
if ($this->has($name)) {
$defaultValue = parent::get($name);
if (null !== $defaultValue && !\is_scalar($defaultValue)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException(\sprintf('The default value of an env() parameter must be scalar or null, but "%s" given to "%s".', \gettype($defaultValue), $name));
if (isset($this->unusedEnvPlaceholders[$env])) {
foreach ($this->unusedEnvPlaceholders[$env] as $placeholder) {
return $placeholder;
// return first result
}
}
$uniqueName = \md5($name . \uniqid(\mt_rand(), \true));
$placeholder = \sprintf('env_%s_%s', \str_replace(':', '_', $env), $uniqueName);
if (!\preg_match('/^(?:[-.\\w]*+:)*+\\w++$/', $env)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('Invalid %s name: only "word" characters are allowed.', $name));
}
if ($this->has($name) && null !== ($defaultValue = parent::get($name)) && !\is_string($defaultValue)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException(\sprintf('The default value of an env() parameter must be a string or null, but "%s" given to "%s".', \get_debug_type($defaultValue), $name));
}
$uniqueName = \md5($name . '_' . self::$counter++);
$placeholder = \sprintf('%s_%s_%s', $this->getEnvPlaceholderUniquePrefix(), \strtr($env, ':-.', '___'), $uniqueName);
$this->envPlaceholders[$env][$placeholder] = $placeholder;
return $placeholder;
}
return parent::get($name);
}
/**
* Gets the common env placeholder prefix for env vars created by this bag.
*/
public function getEnvPlaceholderUniquePrefix() : string
{
if (null === $this->envPlaceholderUniquePrefix) {
$reproducibleEntropy = \unserialize(\serialize($this->parameters));
\array_walk_recursive($reproducibleEntropy, function (&$v) {
$v = null;
});
$this->envPlaceholderUniquePrefix = 'env_' . \substr(\md5(\serialize($reproducibleEntropy)), -16);
}
return $this->envPlaceholderUniquePrefix;
}
/**
* Returns the map of env vars used in the resolved parameter values to their placeholders.
*
@@ -57,6 +77,14 @@ class EnvPlaceholderParameterBag extends \YoastSEO_Vendor\Symfony\Component\Depe
{
return $this->envPlaceholders;
}
public function getUnusedEnvPlaceholders() : array
{
return $this->unusedEnvPlaceholders;
}
public function clearUnusedEnvPlaceholders()
{
$this->unusedEnvPlaceholders = [];
}
/**
* Merges the env placeholders of another EnvPlaceholderParameterBag.
*/
@@ -68,6 +96,12 @@ class EnvPlaceholderParameterBag extends \YoastSEO_Vendor\Symfony\Component\Depe
$this->envPlaceholders[$env] += $placeholders;
}
}
if ($newUnusedPlaceholders = $bag->getUnusedEnvPlaceholders()) {
$this->unusedEnvPlaceholders += $newUnusedPlaceholders;
foreach ($newUnusedPlaceholders as $env => $placeholders) {
$this->unusedEnvPlaceholders[$env] += $placeholders;
}
}
}
/**
* Maps env prefixes to their corresponding PHP types.
@@ -95,13 +129,8 @@ class EnvPlaceholderParameterBag extends \YoastSEO_Vendor\Symfony\Component\Depe
}
parent::resolve();
foreach ($this->envPlaceholders as $env => $placeholders) {
if (!$this->has($name = "env({$env})")) {
continue;
}
if (\is_numeric($default = $this->parameters[$name])) {
$this->parameters[$name] = (string) $default;
} elseif (null !== $default && !\is_scalar($default)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException(\sprintf('The default value of env parameter "%s" must be scalar or null, "%s" given.', $env, \gettype($default)));
if ($this->has($name = "env({$env})") && null !== ($default = $this->parameters[$name]) && !\is_string($default)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException(\sprintf('The default value of env parameter "%s" must be a string or null, "%s" given.', $env, \get_debug_type($default)));
}
}
}
@@ -48,14 +48,14 @@ class FrozenParameterBag extends \YoastSEO_Vendor\Symfony\Component\DependencyIn
/**
* {@inheritdoc}
*/
public function set($name, $value)
public function set(string $name, $value)
{
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\LogicException('Impossible to call set() on a frozen ParameterBag.');
}
/**
* {@inheritdoc}
*/
public function remove($name)
public function remove(string $name)
{
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\LogicException('Impossible to call remove() on a frozen ParameterBag.');
}
@@ -22,25 +22,19 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
{
protected $parameters = [];
protected $resolved = \false;
private $normalizedNames = [];
/**
* @param array $parameters An array of parameters
*/
public function __construct(array $parameters = [])
{
$this->add($parameters);
}
/**
* Clears all parameters.
* {@inheritdoc}
*/
public function clear()
{
$this->parameters = [];
}
/**
* Adds parameters to the service container parameters.
*
* @param array $parameters An array of parameters
* {@inheritdoc}
*/
public function add(array $parameters)
{
@@ -58,9 +52,8 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
/**
* {@inheritdoc}
*/
public function get($name)
public function get(string $name)
{
$name = $this->normalizeName($name);
if (!\array_key_exists($name, $this->parameters)) {
if (!$name) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException($name);
@@ -68,12 +61,12 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
$alternatives = [];
foreach ($this->parameters as $key => $parameterValue) {
$lev = \levenshtein($name, $key);
if ($lev <= \strlen($name) / 3 || \false !== \strpos($key, $name)) {
if ($lev <= \strlen($name) / 3 || \str_contains($key, $name)) {
$alternatives[] = $key;
}
}
$nonNestedAlternative = null;
if (!\count($alternatives) && \false !== \strpos($name, '.')) {
if (!\count($alternatives) && \str_contains($name, '.')) {
$namePartsLength = \array_map('strlen', \explode('.', $name));
$key = \substr($name, 0, -1 * (1 + \array_pop($namePartsLength)));
while (\count($namePartsLength)) {
@@ -91,30 +84,25 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
return $this->parameters[$name];
}
/**
* Sets a service container parameter.
*
* @param string $name The parameter name
* @param mixed $value The parameter value
* {@inheritdoc}
*/
public function set($name, $value)
public function set(string $name, $value)
{
$this->parameters[$this->normalizeName($name)] = $value;
$this->parameters[$name] = $value;
}
/**
* {@inheritdoc}
*/
public function has($name)
public function has(string $name)
{
return \array_key_exists($this->normalizeName($name), $this->parameters);
return \array_key_exists($name, $this->parameters);
}
/**
* Removes a parameter.
*
* @param string $name The parameter name
* {@inheritdoc}
*/
public function remove($name)
public function remove(string $name)
{
unset($this->parameters[$this->normalizeName($name)]);
unset($this->parameters[$name]);
}
/**
* {@inheritdoc}
@@ -143,7 +131,7 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
* @param mixed $value A value
* @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
*
* @return mixed The resolved value
* @return mixed
*
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
* @throws ParameterCircularReferenceException if a circular reference if detected
@@ -166,28 +154,25 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
/**
* Resolves parameters inside a string.
*
* @param string $value The string to resolve
* @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
* @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
*
* @return mixed The resolved string
* @return mixed
*
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
* @throws ParameterCircularReferenceException if a circular reference if detected
* @throws RuntimeException when a given parameter has a type problem
*/
public function resolveString($value, array $resolving = [])
public function resolveString(string $value, array $resolving = [])
{
// we do this to deal with non string values (Boolean, integer, ...)
// as the preg_replace_callback throw an exception when trying
// a non-string in a parameter value
if (\preg_match('/^%([^%\\s]+)%$/', $value, $match)) {
$key = $match[1];
$lcKey = \strtolower($key);
// strtolower() to be removed in 4.0
if (isset($resolving[$lcKey])) {
if (isset($resolving[$key])) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException(\array_keys($resolving));
}
$resolving[$lcKey] = \true;
$resolving[$key] = \true;
return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
}
return \preg_replace_callback('/%%|%([^%\\s]+)%/', function ($match) use($resolving, $value) {
@@ -196,17 +181,15 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
return '%%';
}
$key = $match[1];
$lcKey = \strtolower($key);
// strtolower() to be removed in 4.0
if (isset($resolving[$lcKey])) {
if (isset($resolving[$key])) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException(\array_keys($resolving));
}
$resolved = $this->get($key);
if (!\is_string($resolved) && !\is_numeric($resolved)) {
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException(\sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type "%s" inside string value "%s".', $key, \gettype($resolved), $value));
throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException(\sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type "%s" inside string value "%s".', $key, \get_debug_type($resolved), $value));
}
$resolved = (string) $resolved;
$resolving[$lcKey] = \true;
$resolving[$key] = \true;
return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving);
}, $value);
}
@@ -248,16 +231,4 @@ class ParameterBag implements \YoastSEO_Vendor\Symfony\Component\DependencyInjec
}
return $value;
}
private function normalizeName($name)
{
if (isset($this->normalizedNames[$normalizedName = \strtolower($name)])) {
$normalizedName = $this->normalizedNames[$normalizedName];
if ((string) $name !== $normalizedName) {
@\trigger_error(\sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), \E_USER_DEPRECATED);
}
} else {
$normalizedName = $this->normalizedNames[$normalizedName] = (string) $name;
}
return $normalizedName;
}
}
@@ -13,7 +13,7 @@ namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\LogicException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
/**
* ParameterBagInterface.
* ParameterBagInterface is the interface implemented by objects that manage service container parameters.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@@ -22,56 +22,47 @@ interface ParameterBagInterface
/**
* Clears all parameters.
*
* @throws LogicException if the ParameterBagInterface can not be cleared
* @throws LogicException if the ParameterBagInterface cannot be cleared
*/
public function clear();
/**
* Adds parameters to the service container parameters.
*
* @param array $parameters An array of parameters
*
* @throws LogicException if the parameter can not be added
* @throws LogicException if the parameter cannot be added
*/
public function add(array $parameters);
/**
* Gets the service container parameters.
*
* @return array An array of parameters
* @return array
*/
public function all();
/**
* Gets a service container parameter.
*
* @param string $name The parameter name
*
* @return mixed The parameter value
* @return array|bool|string|int|float|\UnitEnum|null
*
* @throws ParameterNotFoundException if the parameter is not defined
*/
public function get($name);
public function get(string $name);
/**
* Removes a parameter.
*
* @param string $name The parameter name
*/
public function remove($name);
public function remove(string $name);
/**
* Sets a service container parameter.
*
* @param string $name The parameter name
* @param mixed $value The parameter value
* @param array|bool|string|int|float|\UnitEnum|null $value The parameter value
*
* @throws LogicException if the parameter can not be set
* @throws LogicException if the parameter cannot be set
*/
public function set($name, $value);
public function set(string $name, $value);
/**
* Returns true if a parameter name is defined.
*
* @param string $name The parameter name
*
* @return bool true if the parameter name is defined, false otherwise
* @return bool
*/
public function has($name);
public function has(string $name);
/**
* Replaces parameter placeholders (%name%) by their values for all parameters.
*/
@@ -1,30 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection;
/**
* ResettableContainerInterface defines additional resetting functionality
* for containers, allowing to release shared services when the container is
* not needed anymore.
*
* @author Christophe Coevoet <stof@notk.org>
*/
interface ResettableContainerInterface extends \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerInterface
{
/**
* Resets shared services from the container.
*
* The container is not intended to be used again after being reset in a normal workflow. This method is
* meant as a way to release references for ref-counting.
* A subsequent call to ContainerInterface::get will recreate a new instance of the shared service.
*/
public function reset();
}
@@ -0,0 +1,129 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection;
use YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface;
use YoastSEO_Vendor\Psr\Container\NotFoundExceptionInterface;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use YoastSEO_Vendor\Symfony\Contracts\Service\ServiceLocatorTrait;
use YoastSEO_Vendor\Symfony\Contracts\Service\ServiceProviderInterface;
use YoastSEO_Vendor\Symfony\Contracts\Service\ServiceSubscriberInterface;
/**
* @author Robin Chalas <robin.chalas@gmail.com>
* @author Nicolas Grekas <p@tchwork.com>
*/
class ServiceLocator implements \YoastSEO_Vendor\Symfony\Contracts\Service\ServiceProviderInterface
{
use ServiceLocatorTrait {
get as private doGet;
}
private $externalId;
private $container;
/**
* {@inheritdoc}
*
* @return mixed
*/
public function get(string $id)
{
if (!$this->externalId) {
return $this->doGet($id);
}
try {
return $this->doGet($id);
} catch (\YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException $e) {
$what = \sprintf('service "%s" required by "%s"', $id, $this->externalId);
$message = \preg_replace('/service "\\.service_locator\\.[^"]++"/', $what, $e->getMessage());
if ($e->getMessage() === $message) {
$message = \sprintf('Cannot resolve %s: %s', $what, $message);
}
$r = new \ReflectionProperty($e, 'message');
$r->setAccessible(\true);
$r->setValue($e, $message);
throw $e;
}
}
public function __invoke(string $id)
{
return isset($this->factories[$id]) ? $this->get($id) : null;
}
/**
* @internal
*
* @return static
*/
public function withContext(string $externalId, \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Container $container) : self
{
$locator = clone $this;
$locator->externalId = $externalId;
$locator->container = $container;
return $locator;
}
private function createNotFoundException(string $id) : \YoastSEO_Vendor\Psr\Container\NotFoundExceptionInterface
{
if ($this->loading) {
$msg = \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', \end($this->loading), $id, $this->formatAlternatives());
return new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException($id, \end($this->loading) ?: null, null, [], $msg);
}
$class = \debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 4);
$class = isset($class[3]['object']) ? \get_class($class[3]['object']) : null;
$externalId = $this->externalId ?: $class;
$msg = [];
$msg[] = \sprintf('Service "%s" not found:', $id);
if (!$this->container) {
$class = null;
} elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
$msg[] = 'even though it exists in the app\'s container,';
} else {
try {
$this->container->get($id);
$class = null;
} catch (\YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException $e) {
if ($e->getAlternatives()) {
$msg[] = \sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
} else {
$class = null;
}
}
}
if ($externalId) {
$msg[] = \sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
} else {
$msg[] = \sprintf('the current service locator %s', $this->formatAlternatives());
}
if (!$class) {
// no-op
} elseif (\is_subclass_of($class, \YoastSEO_Vendor\Symfony\Contracts\Service\ServiceSubscriberInterface::class)) {
$msg[] = \sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', \preg_replace('/([^\\\\]++\\\\)++/', '', $class));
} else {
$msg[] = 'Try using dependency injection instead.';
}
return new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException($id, \end($this->loading) ?: null, null, [], \implode(' ', $msg));
}
private function createCircularReferenceException(string $id, array $path) : \YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface
{
return new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException($id, $path);
}
private function formatAlternatives(?array $alternatives = null, string $separator = 'and') : string
{
$format = '"%s"%s';
if (null === $alternatives) {
if (!($alternatives = \array_keys($this->factories))) {
return 'is empty...';
}
$format = \sprintf('only knows about the %s service%s.', $format, 1 < \count($alternatives) ? 's' : '');
}
$last = \array_pop($alternatives);
return \sprintf($format, $alternatives ? \implode('", "', $alternatives) : $last, $alternatives ? \sprintf(' %s "%s"', $separator, $last) : '');
}
}
@@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace YoastSEO_Vendor\Symfony\Contracts\Service;
/**
* Provides a way to reset an object to its initial state.
*
* When calling the "reset()" method on an object, it should be put back to its
* initial state. This usually means clearing any internal buffers and forwarding
* the call to internal dependencies. All properties of the object should be put
* back to the same state it had when it was first ready to use.
*
* This method could be called, for example, to recycle objects that are used as
* services, so that they can be used to handle several requests in the same
* process loop (note that we advise making your services stateless instead of
* implementing this interface when possible.)
*/
interface ResetInterface
{
public function reset();
}
@@ -0,0 +1,113 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace YoastSEO_Vendor\Symfony\Contracts\Service;
use YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface;
use YoastSEO_Vendor\Psr\Container\NotFoundExceptionInterface;
// Help opcache.preload discover always-needed symbols
\class_exists(\YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface::class);
\class_exists(\YoastSEO_Vendor\Psr\Container\NotFoundExceptionInterface::class);
/**
* A trait to help implement ServiceProviderInterface.
*
* @author Robin Chalas <robin.chalas@gmail.com>
* @author Nicolas Grekas <p@tchwork.com>
*/
trait ServiceLocatorTrait
{
private $factories;
private $loading = [];
private $providedTypes;
/**
* @param callable[] $factories
*/
public function __construct(array $factories)
{
$this->factories = $factories;
}
/**
* {@inheritdoc}
*
* @return bool
*/
public function has(string $id)
{
return isset($this->factories[$id]);
}
/**
* {@inheritdoc}
*
* @return mixed
*/
public function get(string $id)
{
if (!isset($this->factories[$id])) {
throw $this->createNotFoundException($id);
}
if (isset($this->loading[$id])) {
$ids = \array_values($this->loading);
$ids = \array_slice($this->loading, \array_search($id, $ids));
$ids[] = $id;
throw $this->createCircularReferenceException($id, $ids);
}
$this->loading[$id] = $id;
try {
return $this->factories[$id]($this);
} finally {
unset($this->loading[$id]);
}
}
/**
* {@inheritdoc}
*/
public function getProvidedServices() : array
{
if (null === $this->providedTypes) {
$this->providedTypes = [];
foreach ($this->factories as $name => $factory) {
if (!\is_callable($factory)) {
$this->providedTypes[$name] = '?';
} else {
$type = (new \ReflectionFunction($factory))->getReturnType();
$this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '') . ($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?';
}
}
}
return $this->providedTypes;
}
private function createNotFoundException(string $id) : \YoastSEO_Vendor\Psr\Container\NotFoundExceptionInterface
{
if (!($alternatives = \array_keys($this->factories))) {
$message = 'is empty...';
} else {
$last = \array_pop($alternatives);
if ($alternatives) {
$message = \sprintf('only knows about the "%s" and "%s" services.', \implode('", "', $alternatives), $last);
} else {
$message = \sprintf('only knows about the "%s" service.', $last);
}
}
if ($this->loading) {
$message = \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', \end($this->loading), $id, $message);
} else {
$message = \sprintf('Service "%s" not found: the current service locator %s', $id, $message);
}
return new class($message) extends \InvalidArgumentException implements \YoastSEO_Vendor\Psr\Container\NotFoundExceptionInterface
{
};
}
private function createCircularReferenceException(string $id, array $path) : \YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface
{
return new class(\sprintf('Circular reference detected for service "%s", path: "%s".', $id, \implode(' -> ', $path))) extends \RuntimeException implements \YoastSEO_Vendor\Psr\Container\ContainerExceptionInterface
{
};
}
}
@@ -0,0 +1,34 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace YoastSEO_Vendor\Symfony\Contracts\Service;
use YoastSEO_Vendor\Psr\Container\ContainerInterface;
/**
* A ServiceProviderInterface exposes the identifiers and the types of services provided by a container.
*
* @author Nicolas Grekas <p@tchwork.com>
* @author Mateusz Sip <mateusz.sip@gmail.com>
*/
interface ServiceProviderInterface extends \YoastSEO_Vendor\Psr\Container\ContainerInterface
{
/**
* Returns an associative array of service types keyed by the identifiers provided by the current container.
*
* Examples:
*
* * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface
* * ['foo' => '?'] means the container provides service name "foo" of unspecified type
* * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null
*
* @return string[] The provided service types, keyed by service names
*/
public function getProvidedServices() : array;
}